@myst-theme/jupyter 0.18.0 → 1.0.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/dist/active.d.ts +13 -0
- package/dist/active.d.ts.map +1 -0
- package/dist/active.js +67 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/decoration.d.ts.map +1 -1
- package/dist/decoration.js +8 -6
- package/dist/embed.d.ts.map +1 -1
- package/dist/embed.js +10 -4
- package/dist/execute/utils.js +4 -4
- package/dist/figure.d.ts.map +1 -1
- package/dist/figure.js +14 -6
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/jupyter.d.ts +9 -3
- package/dist/jupyter.d.ts.map +1 -1
- package/dist/jupyter.js +26 -65
- package/dist/output.d.ts +13 -9
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +48 -41
- package/dist/output.spec.d.ts +2 -0
- package/dist/output.spec.d.ts.map +1 -0
- package/dist/output.spec.js +133 -0
- package/dist/outputs.d.ts +5 -0
- package/dist/outputs.d.ts.map +1 -0
- package/dist/outputs.js +43 -0
- package/dist/passive.d.ts +20 -0
- package/dist/passive.d.ts.map +1 -0
- package/dist/passive.js +28 -0
- package/dist/providers.d.ts +9 -0
- package/dist/providers.d.ts.map +1 -1
- package/dist/providers.js +10 -0
- package/dist/renderers.d.ts +2 -0
- package/dist/renderers.d.ts.map +1 -1
- package/dist/renderers.js +2 -0
- package/dist/safe.d.ts +2 -3
- package/dist/safe.d.ts.map +1 -1
- package/dist/safe.js +6 -13
- package/package.json +12 -3
package/dist/active.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IOutput } from '@jupyterlab/nbformat';
|
|
2
|
+
import type { ThebeCore } from 'thebe-core';
|
|
3
|
+
import { type MinifiedOutput } from 'nbtx';
|
|
4
|
+
export declare function ActiveOutputRenderer({ outputsId, initialData, core, }: {
|
|
5
|
+
outputsId: string;
|
|
6
|
+
initialData: IOutput[];
|
|
7
|
+
core: ThebeCore;
|
|
8
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function ActiveJupyterCellOutputs({ outputsId, outputs, }: {
|
|
10
|
+
outputsId: string;
|
|
11
|
+
outputs: MinifiedOutput[];
|
|
12
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=active.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active.d.ts","sourceRoot":"","sources":["../src/active.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAK5C,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,MAAM,CAAC;AAM9D,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,WAAW,EACX,IAAI,GACL,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,EAAE,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;CACjB,2CA0CA;AAED,wBAAgB,wBAAwB,CAAC,EACvC,SAAS,EACT,OAAO,GACR,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B,2CA6CA"}
|
package/dist/active.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { useCellExecution } from './execute/index.js';
|
|
4
|
+
import { usePlaceholder } from './decoration.js';
|
|
5
|
+
import { MyST } from 'myst-to-react';
|
|
6
|
+
import classNames from 'classnames';
|
|
7
|
+
import { convertToIOutputs } from 'nbtx';
|
|
8
|
+
import { useThebeLoader } from 'thebe-react';
|
|
9
|
+
import { useFetchAnyTruncatedContent } from './hooks.js';
|
|
10
|
+
import { useXRefState } from '@myst-theme/providers';
|
|
11
|
+
import { fetchAndEncodeOutputImages } from './convertImages.js';
|
|
12
|
+
export function ActiveOutputRenderer({ outputsId, initialData, core, }) {
|
|
13
|
+
var _a;
|
|
14
|
+
const exec = useCellExecution(outputsId);
|
|
15
|
+
const placeholder = usePlaceholder();
|
|
16
|
+
const ref = useRef(null);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
var _a, _b, _c;
|
|
19
|
+
if (!ref.current || !(exec === null || exec === void 0 ? void 0 : exec.cell)) {
|
|
20
|
+
console.debug(`Jupyter: No cell ref available for cell ${outputsId}:${(_a = exec === null || exec === void 0 ? void 0 : exec.cell) === null || _a === void 0 ? void 0 : _a.id}`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const verb = exec.cell.isAttachedToDOM ? 'reattaching' : 'attaching';
|
|
24
|
+
console.debug(`${verb} cell ${exec.cell.id} to DOM at:`, {
|
|
25
|
+
el: ref.current,
|
|
26
|
+
connected: ref.current.isConnected,
|
|
27
|
+
data: (_b = core === null || core === void 0 ? void 0 : core.stripWidgets(initialData)) !== null && _b !== void 0 ? _b : initialData,
|
|
28
|
+
});
|
|
29
|
+
exec.cell.attachToDOM(ref.current);
|
|
30
|
+
if (exec.cell.executionCount == null) {
|
|
31
|
+
exec.cell.initOutputs((_c = core === null || core === void 0 ? void 0 : core.stripWidgets(initialData, true, placeholder ? () => '' : undefined)) !== null && _c !== void 0 ? _c : initialData);
|
|
32
|
+
}
|
|
33
|
+
}, [ref === null || ref === void 0 ? void 0 : ref.current, exec === null || exec === void 0 ? void 0 : exec.cell]);
|
|
34
|
+
const executed = ((_a = exec === null || exec === void 0 ? void 0 : exec.cell) === null || _a === void 0 ? void 0 : _a.executionCount) != null;
|
|
35
|
+
console.debug(`Jupyter: Cell ${outputsId} executed: ${executed}; Show output: ${executed || !placeholder}`);
|
|
36
|
+
return (_jsxs("div", { children: [_jsx("div", { ref: ref, "data-thebe-active-ref": "true", className: classNames('relative', { 'invisible h-0': !executed && placeholder }) }), exec.ready && placeholder && !executed && _jsx(MyST, { ast: placeholder })] }));
|
|
37
|
+
}
|
|
38
|
+
export function ActiveJupyterCellOutputs({ outputsId, outputs, }) {
|
|
39
|
+
const { core, load } = useThebeLoader();
|
|
40
|
+
const { inCrossRef } = useXRefState();
|
|
41
|
+
const exec = useCellExecution(outputsId);
|
|
42
|
+
// NOTE: could maybe lift this into the outputs renderer, from here and the passive renderer
|
|
43
|
+
// but the images will be cached anywways, so there is limited benefit
|
|
44
|
+
const { data, error } = useFetchAnyTruncatedContent(outputs);
|
|
45
|
+
const [fullOutputs, setFullOutputs] = useState(null);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (core)
|
|
48
|
+
return;
|
|
49
|
+
load();
|
|
50
|
+
}, [core, load]);
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (!data || fullOutputs != null)
|
|
53
|
+
return;
|
|
54
|
+
fetchAndEncodeOutputImages(data).then((out) => {
|
|
55
|
+
const compactOutputs = convertToIOutputs(out, {});
|
|
56
|
+
setFullOutputs(compactOutputs);
|
|
57
|
+
});
|
|
58
|
+
}, [outputsId, data, fullOutputs]);
|
|
59
|
+
if (error) {
|
|
60
|
+
console.error(error);
|
|
61
|
+
return _jsxs("div", { className: "text-red-500", children: ["Error rendering output: ", error.message] });
|
|
62
|
+
}
|
|
63
|
+
if (!inCrossRef && (exec === null || exec === void 0 ? void 0 : exec.ready)) {
|
|
64
|
+
return (_jsxs("div", { children: [!fullOutputs && _jsx("div", { className: "p-2.5", children: "Fetching full output data..." }), core && fullOutputs && (_jsx(ActiveOutputRenderer, { outputsId: outputsId, initialData: fullOutputs, core: core }, outputsId))] }));
|
|
65
|
+
}
|
|
66
|
+
return _jsx("div", { children: "ActiveJupyterCellOutputs in cross reference" });
|
|
67
|
+
}
|
package/dist/components.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,GAAI,4BAI9B;IACD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC;CAC1C,4CAWA,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,sBAAsB;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,4CAWtE,CAAC"}
|
package/dist/decoration.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decoration.d.ts","sourceRoot":"","sources":["../src/decoration.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"decoration.d.ts","sourceRoot":"","sources":["../src/decoration.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA4B/C,wBAAgB,cAAc,4BAG7B;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,KAA0B,EAC1B,GAAG,EACH,aAAa,GACd,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,2CAuEA"}
|
package/dist/decoration.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { SourceFileKind } from 'myst-spec-ext';
|
|
4
4
|
import { useCellExecution } from './execute/index.js';
|
|
5
5
|
import { ArticleResetNotebook, ArticleRunNotebook, ArticleStatusBadge, } from './controls/ArticleCellControls.js';
|
|
6
6
|
import { JupyterIcon } from '@scienceicons/react/24/solid';
|
|
7
|
-
import { useLinkProvider, useBaseurl, withBaseurl, useThemeTop } from '@myst-theme/providers';
|
|
7
|
+
import { useLinkProvider, useBaseurl, withBaseurl, useThemeTop, useXRefState, } from '@myst-theme/providers';
|
|
8
8
|
import { useComputeOptions } from './providers.js';
|
|
9
9
|
const PlaceholderContext = React.createContext({});
|
|
10
10
|
function PlaceholderProvider({ placeholder, children, }) {
|
|
@@ -21,17 +21,19 @@ export function OutputDecoration({ outputId, placeholder, children, title = 'Jup
|
|
|
21
21
|
const Link = useLinkProvider();
|
|
22
22
|
const top = useThemeTop();
|
|
23
23
|
const baseurl = useBaseurl();
|
|
24
|
+
const { inCrossRef } = useXRefState();
|
|
24
25
|
const showComputeControls = (compute === null || compute === void 0 ? void 0 : compute.enabled) &&
|
|
25
26
|
(compute === null || compute === void 0 ? void 0 : compute.features.figureCompute) &&
|
|
26
27
|
kind === SourceFileKind.Article &&
|
|
27
|
-
!remoteBaseUrl
|
|
28
|
+
!remoteBaseUrl &&
|
|
29
|
+
!inCrossRef;
|
|
28
30
|
if (showComputeControls) {
|
|
29
|
-
return (_jsxs("div", {
|
|
31
|
+
return (_jsxs("div", { "data-name": "output-decoration-with-compute-ctrls", className: "mb-4 shadow myst-jp-output-deco", children: [_jsx("div", { className: "myst-jp-output-deco-header sticky z-[2] w-full bg-gray-100/80 backdrop-blur dark:bg-neutral-800/80 py-1 px-2", style: { top }, children: _jsxs("div", { className: "flex items-center myst-jp-output-deco-inner", children: [_jsxs("div", { className: "flex items-center myst-jp-output-deco-source", children: [_jsx(JupyterIcon, { width: "1.25rem", height: "1.25rem", className: "inline-block" }), _jsx("span", { className: "ml-2 myst-jp-output-deco-label", children: "Source:" }), url && (_jsx(Link, { to: withBaseurl(url, remoteBaseUrl !== null && remoteBaseUrl !== void 0 ? remoteBaseUrl : baseurl), className: "ml-2 no-underline myst-jp-output-deco-link text-normal hover:underline", children: title }))] }), _jsx("div", { className: "flex-grow" }), _jsx(ArticleStatusBadge, { id: outputId }), _jsx(ArticleRunNotebook, { id: outputId }), _jsx(ArticleResetNotebook, { id: outputId })] }) }), _jsx(PlaceholderProvider, { placeholder: placeholder, children: children })] }));
|
|
30
32
|
}
|
|
31
33
|
// light
|
|
32
34
|
if (kind === SourceFileKind.Article) {
|
|
33
|
-
return (_jsxs(
|
|
35
|
+
return (_jsxs("div", { "data-name": "output-decoration-article", children: [_jsxs("div", { className: "flex justify-end items-center text-xsmyst-jp-output-deco-light", children: [_jsx(JupyterIcon, { width: "0.75rem", height: "0.75rem", className: "inline-block" }), _jsx("div", { className: "ml-1 myst-jp-output-deco-label", children: "Source:" }), url && (_jsx(Link, { to: withBaseurl(url, remoteBaseUrl !== null && remoteBaseUrl !== void 0 ? remoteBaseUrl : baseurl), className: "ml-1 no-underline myst-jp-output-deco-link text-normal hover:underline", children: title }))] }), _jsx(PlaceholderProvider, { placeholder: placeholder, children: children })] }));
|
|
34
36
|
}
|
|
35
37
|
// Notebook outputs do not need any decoration
|
|
36
|
-
return _jsx(
|
|
38
|
+
return _jsx("div", { "data-name": "output-decoration-notebook-output", children: children });
|
|
37
39
|
}
|
package/dist/embed.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embed.d.ts","sourceRoot":"","sources":["../src/embed.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"embed.d.ts","sourceRoot":"","sources":["../src/embed.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAO/C,wBAAgB,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,2CA6BpD"}
|
package/dist/embed.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { OutputDecoration } from './decoration.js';
|
|
3
3
|
import { MyST } from 'myst-to-react';
|
|
4
|
+
import { OutputsContextProvider } from './providers.js';
|
|
4
5
|
export function Embed({ node }) {
|
|
5
|
-
var _a, _b, _c, _d;
|
|
6
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
6
7
|
const output = (_a = node.children) === null || _a === void 0 ? void 0 : _a.find((child) => child.type === 'output');
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
const outputs = (_b = node.children) === null || _b === void 0 ? void 0 : _b.find((child) => child.type === 'outputs');
|
|
9
|
+
if (outputs) {
|
|
10
|
+
return (_jsx(OutputDecoration, { outputId: (_c = outputs.id) !== null && _c !== void 0 ? _c : outputs.key, title: (_d = node.source) === null || _d === void 0 ? void 0 : _d.title, url: (_e = node.source) === null || _e === void 0 ? void 0 : _e.url, remoteBaseUrl: (_f = node.source) === null || _f === void 0 ? void 0 : _f.remoteBaseUrl, children: _jsx(OutputsContextProvider, { outputsId: (_g = outputs.id) !== null && _g !== void 0 ? _g : outputs.key, children: _jsx(MyST, { ast: node.children }) }) }, node.key));
|
|
11
|
+
}
|
|
12
|
+
else if (output) {
|
|
13
|
+
return (_jsx(OutputsContextProvider, { outputsId: output.key, children: _jsx(MyST, { ast: node.children }) }));
|
|
14
|
+
}
|
|
15
|
+
return _jsx(MyST, { ast: node.children });
|
|
10
16
|
}
|
package/dist/execute/utils.js
CHANGED
|
@@ -38,7 +38,7 @@ export function notebookFromMdast(core, config, pageSlug, notebookSlug, mdast, i
|
|
|
38
38
|
// no metadata included in mdast yet
|
|
39
39
|
//Object.assign(notebook.metadata, ipynb.metadata);
|
|
40
40
|
notebook.cells = mdast.children.map((block) => {
|
|
41
|
-
var _a, _b, _c;
|
|
41
|
+
var _a, _b, _c, _d;
|
|
42
42
|
if (block.type !== 'block')
|
|
43
43
|
console.warn(`Unexpected block type ${block.type}`);
|
|
44
44
|
const executableNodes = executableNodesFromBlock(block);
|
|
@@ -53,7 +53,7 @@ export function notebookFromMdast(core, config, pageSlug, notebookSlug, mdast, i
|
|
|
53
53
|
cellId: block.key,
|
|
54
54
|
};
|
|
55
55
|
idkmap[block.key] = target; // can reference from block in notebook views
|
|
56
|
-
idkmap[output.id] = target; // can reference from output in article views
|
|
56
|
+
idkmap[(_a = output.id) !== null && _a !== void 0 ? _a : output.key] = target; // can reference from output in article views
|
|
57
57
|
// include identifiers to enable lookup by (normalized) labels
|
|
58
58
|
if (block.identifier)
|
|
59
59
|
idkmap[block.identifier] = target;
|
|
@@ -61,12 +61,12 @@ export function notebookFromMdast(core, config, pageSlug, notebookSlug, mdast, i
|
|
|
61
61
|
idkmap[codeCell.identifier] = target;
|
|
62
62
|
if (output.identifier)
|
|
63
63
|
idkmap[output.identifier] = target;
|
|
64
|
-
return new core.ThebeCodeCell(target.cellId, notebook.id, (
|
|
64
|
+
return new core.ThebeCodeCell(target.cellId, notebook.id, (_b = codeCell.value) !== null && _b !== void 0 ? _b : '', config, (_c = block.data) !== null && _c !== void 0 ? _c : {}, notebook.rendermime);
|
|
65
65
|
}
|
|
66
66
|
else {
|
|
67
67
|
// assume content - concatenate it
|
|
68
68
|
// TODO inject cell metadata
|
|
69
|
-
const cell = new core.ThebeMarkdownCell(block.key, notebook.id, block.children.reduce((acc, child) => { var _a; return acc + '\n' + ((_a = child.value) !== null && _a !== void 0 ? _a : ''); }, ''), (
|
|
69
|
+
const cell = new core.ThebeMarkdownCell(block.key, notebook.id, block.children.reduce((acc, child) => { var _a; return acc + '\n' + ((_a = child.value) !== null && _a !== void 0 ? _a : ''); }, ''), (_d = block.data) !== null && _d !== void 0 ? _d : {}, notebook.rendermime);
|
|
70
70
|
return cell;
|
|
71
71
|
}
|
|
72
72
|
});
|
package/dist/figure.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"figure.d.ts","sourceRoot":"","sources":["../src/figure.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"figure.d.ts","sourceRoot":"","sources":["../src/figure.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAS/C,wBAAgB,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,2CAqDrD"}
|
package/dist/figure.js
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { SourceFileKind } from 'myst-spec-ext';
|
|
3
|
-
import { DEFAULT_RENDERERS, MyST } from 'myst-to-react';
|
|
3
|
+
import { Callout, DEFAULT_RENDERERS, MyST } from 'myst-to-react';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
5
|
import { OutputDecoration } from './decoration.js';
|
|
6
|
+
import { OutputsContextProvider } from './providers.js';
|
|
7
|
+
import { ExclamationTriangleIcon } from '@heroicons/react/24/outline';
|
|
6
8
|
export function Figure({ node }) {
|
|
7
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
9
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
8
10
|
const { base: Container } = DEFAULT_RENDERERS['container'];
|
|
9
11
|
const isFromJupyer = ((_a = node.source) === null || _a === void 0 ? void 0 : _a.kind) === SourceFileKind.Notebook;
|
|
10
12
|
const output = (_b = node.children) === null || _b === void 0 ? void 0 : _b.find((child) => child.type === 'output');
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const outputs = (_c = node.children) === null || _c === void 0 ? void 0 : _c.find((child) => child.type === 'outputs');
|
|
14
|
+
if (isFromJupyer) {
|
|
15
|
+
if (outputs) {
|
|
16
|
+
const placeholder = (_d = node.children) === null || _d === void 0 ? void 0 : _d.find((child) => child.type === 'image' && child.placeholder);
|
|
17
|
+
const others = (_e = node.children) === null || _e === void 0 ? void 0 : _e.filter((child) => !(child.type === 'image' && child.placeholder));
|
|
18
|
+
return (_jsx("figure", { id: node.html_id || node.identifier || node.key, className: classNames('myst-jp-figure', { subcontainer: node.subcontainer }, node.class), children: _jsx(OutputDecoration, { outputId: (_f = outputs.id) !== null && _f !== void 0 ? _f : outputs.key, placeholder: placeholder, title: (_g = node.source) === null || _g === void 0 ? void 0 : _g.title, url: (_h = node.source) === null || _h === void 0 ? void 0 : _h.url, remoteBaseUrl: (_j = node.source) === null || _j === void 0 ? void 0 : _j.remoteBaseUrl, children: _jsx(OutputsContextProvider, { outputsId: (_k = outputs.id) !== null && _k !== void 0 ? _k : outputs.key, children: _jsx(MyST, { ast: others }) }) }, node.key) }));
|
|
19
|
+
}
|
|
20
|
+
else if (output) {
|
|
21
|
+
return (_jsx(Callout, { title: _jsx("div", { children: "Cannot render embedded output node" }), color: 'red', dropdown: true, Icon: ExclamationTriangleIcon, className: output.className, children: _jsx("div", { className: "py-2", children: "Output data package is not compatible with the current renderer." }) }));
|
|
22
|
+
}
|
|
15
23
|
}
|
|
16
24
|
return _jsx(Container, { node: node });
|
|
17
25
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,4 +7,5 @@ export * from './controls/index.js';
|
|
|
7
7
|
export * from './utils.js';
|
|
8
8
|
export { useLaunchBinder } from './hooks.js';
|
|
9
9
|
export { JUPYTER_RENDERERS, NOTEBOOK_BLOCK_RENDERERS, OUTPUT_RENDERERS } from './renderers.js';
|
|
10
|
+
export { MYST_SPEC_VERSION } from '@myst-theme/common';
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/jupyter.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { MinifiedOutput } from 'nbtx';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Render a single output as a Jupyter output.
|
|
5
|
+
*
|
|
6
|
+
* @param id - The id of the cell.
|
|
7
|
+
* @param output - The output data.
|
|
8
|
+
*/
|
|
9
|
+
export declare const JupyterOutput: React.MemoExoticComponent<({ outputsId, output }: {
|
|
10
|
+
outputsId: string;
|
|
11
|
+
output: MinifiedOutput;
|
|
6
12
|
}) => import("react/jsx-runtime").JSX.Element>;
|
|
7
13
|
//# sourceMappingURL=jupyter.d.ts.map
|
package/dist/jupyter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jupyter.d.ts","sourceRoot":"","sources":["../src/jupyter.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"jupyter.d.ts","sourceRoot":"","sources":["../src/jupyter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAO3C;;;;;GAKG;AACH,eAAO,MAAM,aAAa,oDACA;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,6CAiDtE,CAAC"}
|
package/dist/jupyter.js
CHANGED
|
@@ -1,86 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import React, { useEffect,
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
3
|
import { useFetchAnyTruncatedContent } from './hooks.js';
|
|
4
4
|
import { convertToIOutputs } from 'nbtx';
|
|
5
5
|
import { fetchAndEncodeOutputImages } from './convertImages.js';
|
|
6
6
|
import { SourceFileKind } from 'myst-spec-ext';
|
|
7
|
-
import { useXRefState } from '@myst-theme/providers';
|
|
8
7
|
import { useThebeLoader } from 'thebe-react';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const placeholder = usePlaceholder();
|
|
18
|
-
const ref = useRef(null);
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
var _a, _b, _c;
|
|
21
|
-
if (!ref.current || !(exec === null || exec === void 0 ? void 0 : exec.cell)) {
|
|
22
|
-
console.debug(`Jupyter: No cell ref available for cell ${id}:${(_a = exec === null || exec === void 0 ? void 0 : exec.cell) === null || _a === void 0 ? void 0 : _a.id}`);
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
const verb = exec.cell.isAttachedToDOM ? 'reattaching' : 'attaching';
|
|
26
|
-
console.debug(`${verb} cell ${exec.cell.id} to DOM at:`, {
|
|
27
|
-
el: ref.current,
|
|
28
|
-
connected: ref.current.isConnected,
|
|
29
|
-
data: (_b = core === null || core === void 0 ? void 0 : core.stripWidgets(initialData)) !== null && _b !== void 0 ? _b : initialData,
|
|
30
|
-
});
|
|
31
|
-
exec.cell.attachToDOM(ref.current);
|
|
32
|
-
if (exec.cell.executionCount == null) {
|
|
33
|
-
exec.cell.initOutputs((_c = core === null || core === void 0 ? void 0 : core.stripWidgets(initialData, true, placeholder ? () => '' : undefined)) !== null && _c !== void 0 ? _c : initialData);
|
|
34
|
-
}
|
|
35
|
-
}, [ref === null || ref === void 0 ? void 0 : ref.current, exec === null || exec === void 0 ? void 0 : exec.cell]);
|
|
36
|
-
const executed = ((_a = exec === null || exec === void 0 ? void 0 : exec.cell) === null || _a === void 0 ? void 0 : _a.executionCount) != null;
|
|
37
|
-
console.debug(`Jupyter: Cell ${id} executed: ${executed}; Show output: ${executed || !placeholder}`);
|
|
38
|
-
return (_jsxs("div", { children: [_jsx("div", { ref: ref, "data-thebe-active-ref": "true", className: classNames('relative', { 'invisible h-0': !executed && placeholder }) }), placeholder && !executed && _jsx(MyST, { ast: placeholder })] }));
|
|
39
|
-
}
|
|
40
|
-
function PassiveOutputRenderer({ id, data, core, }) {
|
|
41
|
-
const rendermime = core.makeRenderMimeRegistry();
|
|
42
|
-
const cell = useRef(new core.PassiveCellRenderer(id, rendermime, undefined));
|
|
43
|
-
const ref = useRef(null);
|
|
44
|
-
const { loaded } = usePlotlyPassively(rendermime, data);
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
var _a, _b;
|
|
47
|
-
if (!ref.current || !loaded)
|
|
48
|
-
return;
|
|
49
|
-
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
50
|
-
cell.current.attachToDOM((_a = ref.current) !== null && _a !== void 0 ? _a : undefined, true);
|
|
51
|
-
cell.current.render((_b = core === null || core === void 0 ? void 0 : core.stripWidgets(data)) !== null && _b !== void 0 ? _b : data);
|
|
52
|
-
}, [ref, loaded]);
|
|
53
|
-
return _jsx("div", { ref: ref, "data-thebe-passive-ref": "true" });
|
|
54
|
-
}
|
|
55
|
-
export const JupyterOutputs = React.memo(({ id, outputs }) => {
|
|
8
|
+
import { PassiveOutputRenderer } from './passive.js';
|
|
9
|
+
/**
|
|
10
|
+
* Render a single output as a Jupyter output.
|
|
11
|
+
*
|
|
12
|
+
* @param id - The id of the cell.
|
|
13
|
+
* @param output - The output data.
|
|
14
|
+
*/
|
|
15
|
+
export const JupyterOutput = React.memo(({ outputsId, output }) => {
|
|
56
16
|
const { core, load } = useThebeLoader();
|
|
57
|
-
const {
|
|
58
|
-
const
|
|
59
|
-
const [fullOutputs, setFullOutputs] = useState(null);
|
|
60
|
-
const exec = useCellExecution(id);
|
|
61
|
-
const placeholder = usePlaceholder();
|
|
17
|
+
const { data, error } = useFetchAnyTruncatedContent([output]);
|
|
18
|
+
const [fullOutput, setFullOutput] = useState(null);
|
|
62
19
|
useEffect(() => {
|
|
63
20
|
if (core)
|
|
64
21
|
return;
|
|
65
22
|
load();
|
|
66
23
|
}, [core, load]);
|
|
67
24
|
useEffect(() => {
|
|
68
|
-
if (!data ||
|
|
25
|
+
if (!data || fullOutput != null)
|
|
69
26
|
return;
|
|
70
27
|
fetchAndEncodeOutputImages(data).then((out) => {
|
|
71
28
|
const compactOutputs = convertToIOutputs(out, {});
|
|
72
|
-
|
|
29
|
+
setFullOutput(compactOutputs[0]);
|
|
73
30
|
});
|
|
74
|
-
}, [
|
|
31
|
+
}, [outputsId, data, fullOutput]);
|
|
75
32
|
if (error) {
|
|
76
33
|
console.error(error);
|
|
77
34
|
return _jsxs("div", { className: "text-red-500", children: ["Error rendering output: ", error.message] });
|
|
78
35
|
}
|
|
79
|
-
if (!inCrossRef &&
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
36
|
+
// if (!inCrossRef && exec?.ready) {
|
|
37
|
+
// return (
|
|
38
|
+
// <div>
|
|
39
|
+
// {!fullOutputs && <div className="p-2.5">Fetching full output data...</div>}
|
|
40
|
+
// {core && fullOutputs && (
|
|
41
|
+
// <ActiveOutputRenderer key={id} id={id} initialData={fullOutputs} core={core} />
|
|
42
|
+
// )}
|
|
43
|
+
// </div>
|
|
44
|
+
// );
|
|
45
|
+
// }
|
|
46
|
+
return (_jsxs("div", { children: [!fullOutput && _jsx("div", { className: "p-2.5", children: "Loading..." }), fullOutput && core && (_jsx(PassiveOutputRenderer, { id: outputsId, data: fullOutput, core: core, kind: SourceFileKind.Notebook }))] }));
|
|
86
47
|
});
|
package/dist/output.d.ts
CHANGED
|
@@ -2,15 +2,19 @@ import type { GenericNode } from 'myst-common';
|
|
|
2
2
|
import type { MinifiedOutput } from 'nbtx';
|
|
3
3
|
export declare const DIRECT_OUTPUT_TYPES: Set<string>;
|
|
4
4
|
export declare const DIRECT_MIME_TYPES: Set<string>;
|
|
5
|
-
export declare function
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
export declare function isOutputSafe(output: MinifiedOutput | null | undefined, directOutputTypes: Set<string>, directMimeTypes: Set<string>): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Check if an output is valid and has the expected structure.
|
|
8
|
+
*
|
|
9
|
+
* @param output - The output to validate.
|
|
10
|
+
* @returns Object with isValid flag and reason if invalid.
|
|
11
|
+
*/
|
|
12
|
+
export declare function validateOutput(output: unknown): {
|
|
13
|
+
isValid: boolean;
|
|
14
|
+
reason?: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function Output({ node, className }: {
|
|
14
17
|
node: GenericNode;
|
|
18
|
+
className?: string;
|
|
15
19
|
}): import("react/jsx-runtime").JSX.Element;
|
|
16
20
|
//# sourceMappingURL=output.d.ts.map
|
package/dist/output.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EAAsB,cAAc,EAAE,MAAM,MAAM,CAAC;AAS/D,eAAO,MAAM,mBAAmB,aAA+B,CAAC;AAEhE,eAAO,MAAM,iBAAiB,EAMxB,GAAG,CAAC,MAAM,CAAC,CAAC;AAElB,wBAAgB,
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EAAsB,cAAc,EAAE,MAAM,MAAM,CAAC;AAS/D,eAAO,MAAM,mBAAmB,aAA+B,CAAC;AAEhE,eAAO,MAAM,iBAAiB,EAMxB,GAAG,CAAC,MAAM,CAAC,CAAC;AAElB,wBAAgB,YAAY,CAC1B,MAAM,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EACzC,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,EAC9B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,WAgB7B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAWA;AAED,wBAAgB,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,2CAoCpF"}
|
package/dist/output.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { KnownCellOutputMimeTypes } from 'nbtx';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import { JupyterOutputs } from './jupyter.js';
|
|
3
|
+
import { SafeOutput } from './safe.js';
|
|
4
|
+
import { JupyterOutput } from './jupyter.js';
|
|
6
5
|
import { useMemo } from 'react';
|
|
7
6
|
import { useCellExecution } from './execute/index.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
7
|
+
import { useOutputsContext } from './providers.js';
|
|
8
|
+
import { Callout } from 'myst-to-react';
|
|
9
|
+
import { ExclamationTriangleIcon } from '@heroicons/react/24/outline';
|
|
10
10
|
export const DIRECT_OUTPUT_TYPES = new Set(['stream', 'error']);
|
|
11
11
|
export const DIRECT_MIME_TYPES = new Set([
|
|
12
12
|
KnownCellOutputMimeTypes.TextPlain,
|
|
@@ -15,48 +15,55 @@ export const DIRECT_MIME_TYPES = new Set([
|
|
|
15
15
|
KnownCellOutputMimeTypes.ImageJpeg,
|
|
16
16
|
KnownCellOutputMimeTypes.ImageBmp,
|
|
17
17
|
]);
|
|
18
|
-
export function
|
|
19
|
-
if (!
|
|
20
|
-
return
|
|
21
|
-
|
|
18
|
+
export function isOutputSafe(output, directOutputTypes, directMimeTypes) {
|
|
19
|
+
if (!output)
|
|
20
|
+
return false;
|
|
21
|
+
try {
|
|
22
22
|
if (directOutputTypes.has(output.output_type))
|
|
23
|
-
return
|
|
23
|
+
return true;
|
|
24
24
|
const data = output.data;
|
|
25
25
|
const mimetypes = data ? Object.keys(data) : [];
|
|
26
|
-
|
|
26
|
+
return ('data' in output &&
|
|
27
27
|
Boolean(output.data) &&
|
|
28
|
-
mimetypes.every((mimetype) => directMimeTypes.has(mimetype));
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
mimetypes.every((mimetype) => directMimeTypes.has(mimetype)));
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error(error);
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
31
34
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return _jsx(MyST, { ast: placeholder });
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
component = _jsx(SafeOutputs, { keyStub: outputId, outputs: outputs });
|
|
35
|
+
/**
|
|
36
|
+
* Check if an output is valid and has the expected structure.
|
|
37
|
+
*
|
|
38
|
+
* @param output - The output to validate.
|
|
39
|
+
* @returns Object with isValid flag and reason if invalid.
|
|
40
|
+
*/
|
|
41
|
+
export function validateOutput(output) {
|
|
42
|
+
if (!output || typeof output !== 'object') {
|
|
43
|
+
return { isValid: false, reason: 'Jupyter output data package is missing or not an object' };
|
|
45
44
|
}
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
const outputType = output.output_type;
|
|
46
|
+
if (!('output_type' in output) || typeof outputType !== 'string') {
|
|
47
|
+
return { isValid: false, reason: 'Missing or invalid output_type property' };
|
|
48
48
|
}
|
|
49
|
-
return
|
|
50
|
-
'text-left': !align || align === 'left',
|
|
51
|
-
'text-center': align === 'center',
|
|
52
|
-
'text-right': align === 'right',
|
|
53
|
-
'mb-5': outputs && outputs.length > 0,
|
|
54
|
-
}, className), children: component }));
|
|
49
|
+
return { isValid: true };
|
|
55
50
|
}
|
|
56
|
-
export function Output({ node }) {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
export function Output({ node, className }) {
|
|
52
|
+
const { outputsId } = useOutputsContext();
|
|
53
|
+
const { ready } = useCellExecution(outputsId !== null && outputsId !== void 0 ? outputsId : '');
|
|
54
|
+
// FUTURE: we'll be rendering AST outputs directly in future
|
|
55
|
+
const maybeSafeOutput = useMemo(() => node.jupyter_data, [node]);
|
|
56
|
+
const isSafe = isOutputSafe(maybeSafeOutput, DIRECT_OUTPUT_TYPES, DIRECT_MIME_TYPES);
|
|
57
|
+
const validation = validateOutput(maybeSafeOutput);
|
|
58
|
+
if (!outputsId || !maybeSafeOutput || !validation.isValid) {
|
|
59
|
+
if (validation.reason) {
|
|
60
|
+
console.error(validation.reason);
|
|
61
|
+
}
|
|
62
|
+
return (_jsx(Callout, { title: _jsx("div", { children: "Cannot render output node" }), color: 'red', dropdown: true, Icon: ExclamationTriangleIcon, className: className, children: _jsxs("div", { className: "py-2 space-y-1", children: [_jsx("div", { children: "Output data package is not compatible with the current renderer." }), validation.reason && (_jsxs("div", { className: "font-mono text-sm", children: ["Reason: ", validation.reason] }))] }) }));
|
|
63
|
+
}
|
|
64
|
+
if (isSafe && !ready) {
|
|
65
|
+
return _jsx(SafeOutput, { output: maybeSafeOutput });
|
|
60
66
|
}
|
|
61
|
-
|
|
67
|
+
// TODO: myst-jp-output should be added to the first child div
|
|
68
|
+
return _jsx(JupyterOutput, { outputsId: outputsId, output: maybeSafeOutput });
|
|
62
69
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.spec.d.ts","sourceRoot":"","sources":["../src/output.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
import { isOutputSafe, DIRECT_OUTPUT_TYPES, DIRECT_MIME_TYPES } from './output.js';
|
|
4
|
+
import { KnownCellOutputMimeTypes } from 'nbtx';
|
|
5
|
+
describe('Output Safety Functions', () => {
|
|
6
|
+
describe('isOutputSafe', () => {
|
|
7
|
+
it('should return true for direct output types', () => {
|
|
8
|
+
const output = {
|
|
9
|
+
output_type: 'stream',
|
|
10
|
+
name: 'stdout',
|
|
11
|
+
text: 'some output',
|
|
12
|
+
};
|
|
13
|
+
expect(isOutputSafe(output, DIRECT_OUTPUT_TYPES, DIRECT_MIME_TYPES)).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
it('should return true for safe mime types', () => {
|
|
16
|
+
const output = {
|
|
17
|
+
output_type: 'display_data',
|
|
18
|
+
data: {
|
|
19
|
+
[KnownCellOutputMimeTypes.TextPlain]: {
|
|
20
|
+
content_type: 'text/plain',
|
|
21
|
+
content: 'some text',
|
|
22
|
+
},
|
|
23
|
+
[KnownCellOutputMimeTypes.ImagePng]: {
|
|
24
|
+
content_type: 'image/png',
|
|
25
|
+
content: 'base64data',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
metadata: {},
|
|
29
|
+
};
|
|
30
|
+
expect(isOutputSafe(output, DIRECT_OUTPUT_TYPES, DIRECT_MIME_TYPES)).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
it('should return false for unsafe mime types', () => {
|
|
33
|
+
const output = {
|
|
34
|
+
output_type: 'display_data',
|
|
35
|
+
data: {
|
|
36
|
+
'application/javascript': {
|
|
37
|
+
content_type: 'application/javascript',
|
|
38
|
+
content: 'alert("unsafe")',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
metadata: {},
|
|
42
|
+
};
|
|
43
|
+
expect(isOutputSafe(output, DIRECT_OUTPUT_TYPES, DIRECT_MIME_TYPES)).toBe(false);
|
|
44
|
+
});
|
|
45
|
+
it('should return false for output without data', () => {
|
|
46
|
+
// technically malformed input, but we'll handle it gracefully
|
|
47
|
+
const output = {
|
|
48
|
+
output_type: 'display_data',
|
|
49
|
+
metadata: {},
|
|
50
|
+
};
|
|
51
|
+
expect(isOutputSafe(output, DIRECT_OUTPUT_TYPES, DIRECT_MIME_TYPES)).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
// describe('allOutputsAreSafe', () => {
|
|
55
|
+
// it('should return true for empty outputs', () => {
|
|
56
|
+
// expect(allOutputsAreSafe([], DIRECT_OUTPUT_TYPES, DIRECT_MIME_TYPES)).toBe(true);
|
|
57
|
+
// });
|
|
58
|
+
// it('should return true when all outputs are safe', () => {
|
|
59
|
+
// const outputs: MinifiedOutput[] = [
|
|
60
|
+
// {
|
|
61
|
+
// output_type: 'stream',
|
|
62
|
+
// name: 'stdout',
|
|
63
|
+
// text: 'some output',
|
|
64
|
+
// },
|
|
65
|
+
// {
|
|
66
|
+
// output_type: 'display_data',
|
|
67
|
+
// data: {
|
|
68
|
+
// [KnownCellOutputMimeTypes.TextPlain]: {
|
|
69
|
+
// content_type: 'text/plain',
|
|
70
|
+
// content: 'text',
|
|
71
|
+
// },
|
|
72
|
+
// [KnownCellOutputMimeTypes.ImagePng]: {
|
|
73
|
+
// content_type: 'image/png',
|
|
74
|
+
// content: 'data',
|
|
75
|
+
// },
|
|
76
|
+
// },
|
|
77
|
+
// metadata: {},
|
|
78
|
+
// },
|
|
79
|
+
// ];
|
|
80
|
+
// expect(allOutputsAreSafe(outputs, DIRECT_OUTPUT_TYPES, DIRECT_MIME_TYPES)).toBe(true);
|
|
81
|
+
// });
|
|
82
|
+
// it('should return false when any output is unsafe', () => {
|
|
83
|
+
// const outputs: MinifiedOutput[] = [
|
|
84
|
+
// {
|
|
85
|
+
// output_type: 'stream',
|
|
86
|
+
// name: 'stdout',
|
|
87
|
+
// text: 'some output',
|
|
88
|
+
// },
|
|
89
|
+
// {
|
|
90
|
+
// output_type: 'display_data',
|
|
91
|
+
// data: {
|
|
92
|
+
// 'application/javascript': {
|
|
93
|
+
// content_type: 'application/javascript',
|
|
94
|
+
// content: 'alert("unsafe")',
|
|
95
|
+
// },
|
|
96
|
+
// },
|
|
97
|
+
// metadata: {},
|
|
98
|
+
// },
|
|
99
|
+
// ];
|
|
100
|
+
// expect(allOutputsAreSafe(outputs, DIRECT_OUTPUT_TYPES, DIRECT_MIME_TYPES)).toBe(false);
|
|
101
|
+
// });
|
|
102
|
+
// it('should handle mixed safe and unsafe outputs', () => {
|
|
103
|
+
// const outputs: MinifiedOutput[] = [
|
|
104
|
+
// {
|
|
105
|
+
// output_type: 'stream',
|
|
106
|
+
// name: 'stdout',
|
|
107
|
+
// text: 'some output',
|
|
108
|
+
// },
|
|
109
|
+
// {
|
|
110
|
+
// output_type: 'display_data',
|
|
111
|
+
// data: {
|
|
112
|
+
// [KnownCellOutputMimeTypes.TextPlain]: {
|
|
113
|
+
// content_type: 'text/plain',
|
|
114
|
+
// content: 'text',
|
|
115
|
+
// },
|
|
116
|
+
// },
|
|
117
|
+
// metadata: {},
|
|
118
|
+
// },
|
|
119
|
+
// {
|
|
120
|
+
// output_type: 'display_data',
|
|
121
|
+
// data: {
|
|
122
|
+
// 'application/javascript': {
|
|
123
|
+
// content_type: 'application/javascript',
|
|
124
|
+
// content: 'alert("unsafe")',
|
|
125
|
+
// },
|
|
126
|
+
// },
|
|
127
|
+
// metadata: {},
|
|
128
|
+
// },
|
|
129
|
+
// ];
|
|
130
|
+
// expect(allOutputsAreSafe(outputs, DIRECT_OUTPUT_TYPES, DIRECT_MIME_TYPES)).toBe(false);
|
|
131
|
+
// });
|
|
132
|
+
// });
|
|
133
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputs.d.ts","sourceRoot":"","sources":["../src/outputs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAU/C,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,2CAoDtD"}
|
package/dist/outputs.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import { useCellExecution } from './execute/index.js';
|
|
5
|
+
import { usePlaceholder } from './decoration.js';
|
|
6
|
+
import { Details, MyST } from 'myst-to-react';
|
|
7
|
+
import { selectAll } from 'unist-util-select';
|
|
8
|
+
import { OutputsContextProvider } from './providers.js';
|
|
9
|
+
import { ActiveJupyterCellOutputs } from './active.js';
|
|
10
|
+
export function Outputs({ node }) {
|
|
11
|
+
var _a;
|
|
12
|
+
const className = classNames({ hidden: node.visibility === 'remove' });
|
|
13
|
+
const { children, identifier, align } = node;
|
|
14
|
+
const outputsId = (_a = node.id) !== null && _a !== void 0 ? _a : node.key;
|
|
15
|
+
const cellExecutionContext = useCellExecution(outputsId);
|
|
16
|
+
const { ready } = cellExecutionContext;
|
|
17
|
+
const legacyOutputsArray = useMemo(() => {
|
|
18
|
+
return selectAll('output', node).map((child) => child.jupyter_data);
|
|
19
|
+
}, [children]);
|
|
20
|
+
const atLeastOneChildHasJupyterData = legacyOutputsArray.length > 0;
|
|
21
|
+
// NOTE: a placeholder is actually an option on the figure node, not the outputs node
|
|
22
|
+
// perhaps we should move the placeholder to the figure renderer?
|
|
23
|
+
const placeholder = usePlaceholder();
|
|
24
|
+
if (!ready && placeholder) {
|
|
25
|
+
return _jsx(MyST, { ast: placeholder });
|
|
26
|
+
}
|
|
27
|
+
// if not ready, we leave each output to independently render
|
|
28
|
+
// NOTE: we need to see that bokeh & plotly can render ok in this way
|
|
29
|
+
if (!ready) {
|
|
30
|
+
const passiveOutputs = (_jsx("div", { "data-name": "outputs-container", id: identifier || undefined, "data-mdast-node-id": outputsId, className: classNames('max-w-full overflow-y-visible overflow-x-auto m-0 group not-prose relative', {
|
|
31
|
+
'text-left': !align || align === 'left',
|
|
32
|
+
'text-center': align === 'center',
|
|
33
|
+
'text-right': align === 'right',
|
|
34
|
+
'mb-5': atLeastOneChildHasJupyterData,
|
|
35
|
+
}, className), children: _jsx(OutputsContextProvider, { outputsId: outputsId, children: _jsx(MyST, { ast: children }) }) }));
|
|
36
|
+
if (node.visibility === 'hide') {
|
|
37
|
+
return _jsx(Details, { title: "Output", children: passiveOutputs });
|
|
38
|
+
}
|
|
39
|
+
return passiveOutputs;
|
|
40
|
+
}
|
|
41
|
+
// else compute is ready, and we need to treat the whole cell output as one unit
|
|
42
|
+
return _jsx(ActiveJupyterCellOutputs, { outputsId: outputsId, outputs: legacyOutputsArray });
|
|
43
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { IOutput } from '@jupyterlab/nbformat';
|
|
2
|
+
import type { ThebeCore } from 'thebe-core';
|
|
3
|
+
import type { SourceFileKind } from 'myst-spec-ext';
|
|
4
|
+
/**
|
|
5
|
+
* Render a single output as a passive cell output.
|
|
6
|
+
*
|
|
7
|
+
* This is used for outputs that require jupyters rendermime support, such as Plotly.
|
|
8
|
+
*
|
|
9
|
+
* @param id - The id of the cell.
|
|
10
|
+
* @param data - The output data.
|
|
11
|
+
* @param core - The Thebe core.
|
|
12
|
+
* @param kind - The kind of source file.
|
|
13
|
+
*/
|
|
14
|
+
export declare function PassiveOutputRenderer({ id, data, core, }: {
|
|
15
|
+
id: string;
|
|
16
|
+
data: IOutput;
|
|
17
|
+
core: ThebeCore;
|
|
18
|
+
kind: SourceFileKind;
|
|
19
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=passive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passive.d.ts","sourceRoot":"","sources":["../src/passive.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,EAAE,EACF,IAAI,EACJ,IAAI,GACL,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,cAAc,CAAC;CACtB,2CAgBA"}
|
package/dist/passive.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef } from 'react';
|
|
3
|
+
import { usePlotlyPassively } from './plotly.js';
|
|
4
|
+
/**
|
|
5
|
+
* Render a single output as a passive cell output.
|
|
6
|
+
*
|
|
7
|
+
* This is used for outputs that require jupyters rendermime support, such as Plotly.
|
|
8
|
+
*
|
|
9
|
+
* @param id - The id of the cell.
|
|
10
|
+
* @param data - The output data.
|
|
11
|
+
* @param core - The Thebe core.
|
|
12
|
+
* @param kind - The kind of source file.
|
|
13
|
+
*/
|
|
14
|
+
export function PassiveOutputRenderer({ id, data, core, }) {
|
|
15
|
+
const rendermime = core.makeRenderMimeRegistry();
|
|
16
|
+
const cell = useRef(new core.PassiveCellRenderer(id, rendermime, undefined));
|
|
17
|
+
const ref = useRef(null);
|
|
18
|
+
const { loaded } = usePlotlyPassively(rendermime, [data]);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
if (!ref.current || !loaded)
|
|
22
|
+
return;
|
|
23
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
24
|
+
cell.current.attachToDOM((_a = ref.current) !== null && _a !== void 0 ? _a : undefined, true);
|
|
25
|
+
cell.current.render((_b = core === null || core === void 0 ? void 0 : core.stripWidgets([data])) !== null && _b !== void 0 ? _b : data);
|
|
26
|
+
}, [ref, loaded]);
|
|
27
|
+
return _jsx("div", { ref: ref, "data-thebe-passive-ref": "true", "data-output-id": id });
|
|
28
|
+
}
|
package/dist/providers.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import { type ExtendedCoreOptions } from './utils.js';
|
|
4
4
|
import type { GenericParent } from 'myst-common';
|
|
5
5
|
import type { RepoProviderSpec } from 'thebe-core';
|
|
6
|
+
import type { IdOrKey } from './execute/types.js';
|
|
6
7
|
type ComputeOptionsContextType = {
|
|
7
8
|
enabled: boolean;
|
|
8
9
|
features: {
|
|
@@ -41,5 +42,13 @@ export declare function ThebeLoaderAndServer({ baseurl, connect, children, }: Re
|
|
|
41
42
|
connect?: boolean;
|
|
42
43
|
baseurl?: string;
|
|
43
44
|
}>): import("react/jsx-runtime").JSX.Element;
|
|
45
|
+
type OutputsContextType = {
|
|
46
|
+
outputsId: IdOrKey | undefined;
|
|
47
|
+
};
|
|
48
|
+
export declare function useOutputsContext(): OutputsContextType;
|
|
49
|
+
export declare function OutputsContextProvider({ outputsId, children, }: {
|
|
50
|
+
children: React.ReactNode;
|
|
51
|
+
outputsId: IdOrKey;
|
|
52
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
44
53
|
export {};
|
|
45
54
|
//# sourceMappingURL=providers.d.ts.map
|
package/dist/providers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAqB,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,KAAK,mBAAmB,EAA6B,MAAM,YAAY,CAAC;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAqB,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,KAAK,mBAAmB,EAA6B,MAAM,YAAY,CAAC;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD,KAAK,yBAAyB,GAAG;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QACR,eAAe,EAAE,OAAO,CAAC;QACzB,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;KACvB,CAAC;IACF,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC1C,CAAC;AAIF,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,gBAAgB,EAChB,mBAAmB,EACnB,QAAQ,GACT,EAAE,KAAK,CAAC,iBAAiB,CAAC;IACzB,QAAQ,EAAE;QACR,eAAe,EAAE,OAAO,CAAC;QACzB,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;KACvB,CAAC;IACF,gBAAgB,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,mBAAmB,KAAK,mBAAmB,GAAG,SAAS,CAAC;IACnF,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC1C,CAAC,2CA2BD;AAED,wBAAgB,aAAa,wBAG5B;AAED,wBAAgB,iBAAiB,0CAEhC;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,aAAa,CAAC;CACtB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,OAAO,EACP,OAAO,EACP,QAAQ,GACT,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,2CAkBlE;AAED,KAAK,kBAAkB,GAAG;IACxB,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,CAAC;AAGF,wBAAgB,iBAAiB,uBAIhC;AACD,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;CACpB,2CAEA"}
|
package/dist/providers.js
CHANGED
|
@@ -44,3 +44,13 @@ export function ThebeLoaderAndServer({ baseurl, connect, children, }) {
|
|
|
44
44
|
const compute = useComputeOptions();
|
|
45
45
|
return (_jsx(ThebeBundleLoaderProvider, { loadThebeLite: (_b = (_a = compute === null || compute === void 0 ? void 0 : compute.thebe) === null || _a === void 0 ? void 0 : _a.useJupyterLite) !== null && _b !== void 0 ? _b : false, publicPath: baseurl, children: _jsx(ThebeServerProvider, { connect: connect !== null && connect !== void 0 ? connect : false, options: compute === null || compute === void 0 ? void 0 : compute.thebe, useBinder: (_d = (_c = compute === null || compute === void 0 ? void 0 : compute.thebe) === null || _c === void 0 ? void 0 : _c.useBinder) !== null && _d !== void 0 ? _d : false, useJupyterLite: (_f = (_e = compute === null || compute === void 0 ? void 0 : compute.thebe) === null || _e === void 0 ? void 0 : _e.useJupyterLite) !== null && _f !== void 0 ? _f : false, customRepoProviders: (_g = compute === null || compute === void 0 ? void 0 : compute.customRepoProviders) !== null && _g !== void 0 ? _g : [], children: children }) }));
|
|
46
46
|
}
|
|
47
|
+
const OutputsContext = React.createContext(null);
|
|
48
|
+
export function useOutputsContext() {
|
|
49
|
+
const context = useContext(OutputsContext);
|
|
50
|
+
if (context === null)
|
|
51
|
+
return { outputsId: undefined };
|
|
52
|
+
return context;
|
|
53
|
+
}
|
|
54
|
+
export function OutputsContextProvider({ outputsId, children, }) {
|
|
55
|
+
return _jsx(OutputsContext.Provider, { value: { outputsId }, children: children });
|
|
56
|
+
}
|
package/dist/renderers.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Embed } from './embed.js';
|
|
2
|
+
import { Outputs } from './outputs.js';
|
|
2
3
|
import { Output } from './output.js';
|
|
3
4
|
import { Figure } from './figure.js';
|
|
4
5
|
export { NOTEBOOK_BLOCK_RENDERERS } from './block.js';
|
|
5
6
|
export declare const OUTPUT_RENDERERS: {
|
|
7
|
+
outputs: typeof Outputs;
|
|
6
8
|
output: typeof Output;
|
|
7
9
|
embed: typeof Embed;
|
|
8
10
|
container: typeof Figure;
|
package/dist/renderers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderers.d.ts","sourceRoot":"","sources":["../src/renderers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACtD,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"renderers.d.ts","sourceRoot":"","sources":["../src/renderers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACtD,eAAO,MAAM,gBAAgB;;;;;CAK5B,CAAC;AACF,eAAO,MAAM,iBAAiB,+CAA+D,CAAC"}
|
package/dist/renderers.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Embed } from './embed.js';
|
|
2
|
+
import { Outputs } from './outputs.js';
|
|
2
3
|
import { Output } from './output.js';
|
|
3
4
|
import { Figure } from './figure.js';
|
|
4
5
|
import { mergeRenderers } from '@myst-theme/providers';
|
|
5
6
|
import { NOTEBOOK_BLOCK_RENDERERS } from './block.js';
|
|
6
7
|
export { NOTEBOOK_BLOCK_RENDERERS } from './block.js';
|
|
7
8
|
export const OUTPUT_RENDERERS = {
|
|
9
|
+
outputs: Outputs,
|
|
8
10
|
output: Output,
|
|
9
11
|
embed: Embed,
|
|
10
12
|
container: Figure,
|
package/dist/safe.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { MinifiedOutput } from 'nbtx';
|
|
2
|
-
export declare function
|
|
3
|
-
|
|
4
|
-
outputs: MinifiedOutput[];
|
|
2
|
+
export declare function SafeOutput({ output }: {
|
|
3
|
+
output: MinifiedOutput;
|
|
5
4
|
}): import("react/jsx-runtime").JSX.Element | null;
|
|
6
5
|
//# sourceMappingURL=safe.d.ts.map
|
package/dist/safe.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safe.d.ts","sourceRoot":"","sources":["../src/safe.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA2C,cAAc,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"safe.d.ts","sourceRoot":"","sources":["../src/safe.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA2C,cAAc,EAAE,MAAM,MAAM,CAAC;AA8CpF,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,kDAwChE"}
|
package/dist/safe.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { KnownCellOutputMimeTypes } from 'nbtx';
|
|
3
3
|
import Stream from './stream.js';
|
|
4
4
|
import Error from './error.js';
|
|
@@ -40,12 +40,12 @@ function OutputImage({ image, text }) {
|
|
|
40
40
|
var _a;
|
|
41
41
|
return _jsx("img", { src: image === null || image === void 0 ? void 0 : image.path, alt: (_a = text === null || text === void 0 ? void 0 : text.content) !== null && _a !== void 0 ? _a : 'Image produced in Jupyter' });
|
|
42
42
|
}
|
|
43
|
-
function SafeOutput({ output }) {
|
|
43
|
+
export function SafeOutput({ output }) {
|
|
44
44
|
switch (output.output_type) {
|
|
45
45
|
case 'stream':
|
|
46
|
-
return _jsx(Stream, { output: output });
|
|
46
|
+
return (_jsx("div", { "data-name": "safe-output-stream", children: _jsx(Stream, { output: output }) }));
|
|
47
47
|
case 'error':
|
|
48
|
-
return _jsx(Error, { output: output });
|
|
48
|
+
return (_jsx("div", { "data-name": "safe-output-error", children: _jsx(Error, { output: output }) }));
|
|
49
49
|
case 'display_data':
|
|
50
50
|
case 'execute_result':
|
|
51
51
|
case 'update_display_data': {
|
|
@@ -53,9 +53,9 @@ function SafeOutput({ output }) {
|
|
|
53
53
|
if (!image && !text)
|
|
54
54
|
return null;
|
|
55
55
|
if (image)
|
|
56
|
-
return _jsx(OutputImage, { image: image, text: text });
|
|
56
|
+
return (_jsx("div", { "data-name": "safe-output-image", children: _jsx(OutputImage, { image: image, text: text }) }));
|
|
57
57
|
if (text)
|
|
58
|
-
return (_jsx("div", {
|
|
58
|
+
return (_jsx("div", { "data-name": "safe-output-text", className: "font-mono text-sm whitespace-pre-wrap myst-jp-safe-output-text", children: _jsx(Ansi, { children: text.content }) }));
|
|
59
59
|
return null;
|
|
60
60
|
}
|
|
61
61
|
default:
|
|
@@ -63,10 +63,3 @@ function SafeOutput({ output }) {
|
|
|
63
63
|
return null;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
export function SafeOutputs({ keyStub, outputs }) {
|
|
67
|
-
if (!outputs)
|
|
68
|
-
return null;
|
|
69
|
-
// TODO better key - add keys during content creation?
|
|
70
|
-
const components = outputs.map((output, idx) => (_jsx(SafeOutput, { output: output }, `${keyStub}-${idx}`)));
|
|
71
|
-
return _jsx(_Fragment, { children: components });
|
|
72
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myst-theme/jupyter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
"node": ">=16"
|
|
12
12
|
},
|
|
13
13
|
"license": "MIT",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/jupyter-book/myst-theme.git"
|
|
17
|
+
},
|
|
14
18
|
"scripts": {
|
|
15
19
|
"clean": "rimraf dist",
|
|
16
20
|
"lint": "eslint \"src/**/*.ts*\" \"src/**/*.tsx\" -c ./.eslintrc.cjs",
|
|
@@ -25,7 +29,7 @@
|
|
|
25
29
|
"@curvenote/ansi-to-react": "^7.0.0",
|
|
26
30
|
"@headlessui/react": "^1.7.15",
|
|
27
31
|
"@heroicons/react": "^2.0.18",
|
|
28
|
-
"@myst-theme/providers": "^0.
|
|
32
|
+
"@myst-theme/providers": "^1.0.1",
|
|
29
33
|
"@scienceicons/react": "^0.0.13",
|
|
30
34
|
"buffer": "^6.0.3",
|
|
31
35
|
"classnames": "^2.5.1",
|
|
@@ -35,7 +39,7 @@
|
|
|
35
39
|
"myst-frontmatter": "^1.7.9",
|
|
36
40
|
"myst-spec": "^0.0.5",
|
|
37
41
|
"myst-spec-ext": "^1.8.1",
|
|
38
|
-
"myst-to-react": "^0.
|
|
42
|
+
"myst-to-react": "^1.0.1",
|
|
39
43
|
"nanoid": "^4.0.2",
|
|
40
44
|
"nbtx": "^0.2.3",
|
|
41
45
|
"react-syntax-highlighter": "^15.5.0",
|
|
@@ -45,6 +49,11 @@
|
|
|
45
49
|
"thebe-react": "0.5.0",
|
|
46
50
|
"unist-util-select": "^4.0.3"
|
|
47
51
|
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/react": "^18.0.0",
|
|
54
|
+
"@types/react-dom": "^18.0.0",
|
|
55
|
+
"vitest": "^1.0.0"
|
|
56
|
+
},
|
|
48
57
|
"peerDependencies": {
|
|
49
58
|
"@types/react": "^16.8 || ^17.0 || ^18.0",
|
|
50
59
|
"@types/react-dom": "^16.8 || ^17.0 || ^18.0",
|