@myst-theme/jupyter 0.3.3 → 0.3.4
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/cjs/ConnectionStatusTray.d.ts.map +1 -1
- package/dist/cjs/ConnectionStatusTray.js +6 -4
- package/dist/cjs/ErrorTray.d.ts +5 -0
- package/dist/cjs/ErrorTray.d.ts.map +1 -0
- package/dist/cjs/ErrorTray.js +34 -0
- package/dist/cjs/controls/ArticleCellControls.d.ts +10 -0
- package/dist/cjs/controls/ArticleCellControls.d.ts.map +1 -0
- package/dist/cjs/controls/ArticleCellControls.js +33 -0
- package/dist/cjs/controls/Buttons.d.ts +47 -0
- package/dist/cjs/controls/Buttons.d.ts.map +1 -0
- package/dist/cjs/controls/Buttons.js +70 -0
- package/dist/cjs/controls/NotebookCellControls.d.ts +10 -0
- package/dist/cjs/controls/NotebookCellControls.d.ts.map +1 -0
- package/dist/cjs/controls/NotebookCellControls.js +27 -0
- package/dist/cjs/controls/NotebookToolbar.d.ts +4 -0
- package/dist/cjs/controls/NotebookToolbar.d.ts.map +1 -0
- package/dist/cjs/controls/NotebookToolbar.js +47 -0
- package/dist/cjs/controls/Spinner.d.ts +4 -0
- package/dist/cjs/controls/Spinner.d.ts.map +1 -0
- package/dist/cjs/controls/Spinner.js +8 -0
- package/dist/cjs/controls/index.d.ts +5 -0
- package/dist/cjs/controls/index.d.ts.map +1 -0
- package/dist/cjs/controls/index.js +20 -0
- package/dist/cjs/execute/actions.d.ts +55 -0
- package/dist/cjs/execute/actions.d.ts.map +1 -0
- package/dist/cjs/execute/actions.js +49 -0
- package/dist/cjs/execute/busy.d.ts +74 -0
- package/dist/cjs/execute/busy.d.ts.map +1 -0
- package/dist/cjs/execute/busy.js +182 -0
- package/dist/cjs/execute/hooks.d.ts +62 -0
- package/dist/cjs/execute/hooks.d.ts.map +1 -0
- package/dist/cjs/execute/hooks.js +308 -0
- package/dist/cjs/execute/index.d.ts +7 -0
- package/dist/cjs/execute/index.d.ts.map +1 -0
- package/dist/cjs/execute/index.js +22 -0
- package/dist/cjs/execute/leaf.d.ts +26 -0
- package/dist/cjs/execute/leaf.d.ts.map +1 -0
- package/dist/cjs/execute/leaf.js +154 -0
- package/dist/cjs/execute/provider.d.ts +29 -0
- package/dist/cjs/execute/provider.d.ts.map +1 -0
- package/dist/cjs/execute/provider.js +126 -0
- package/dist/cjs/execute/reducer.d.ts +4 -0
- package/dist/cjs/execute/reducer.d.ts.map +1 -0
- package/dist/cjs/execute/reducer.js +136 -0
- package/dist/cjs/execute/selectors.d.ts +22 -0
- package/dist/cjs/execute/selectors.d.ts.map +1 -0
- package/dist/cjs/execute/selectors.js +89 -0
- package/dist/cjs/execute/types.d.ts +49 -0
- package/dist/cjs/execute/types.d.ts.map +1 -0
- package/dist/cjs/execute/types.js +2 -0
- package/dist/cjs/execute/utils.d.ts +23 -0
- package/dist/cjs/execute/utils.d.ts.map +1 -0
- package/dist/cjs/execute/utils.js +62 -0
- package/dist/cjs/index.d.ts +4 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/jupyter.d.ts.map +1 -1
- package/dist/cjs/jupyter.js +19 -17
- package/dist/cjs/output.d.ts +1 -1
- package/dist/cjs/output.d.ts.map +1 -1
- package/dist/cjs/output.js +7 -4
- package/dist/cjs/providers.d.ts +1 -48
- package/dist/cjs/providers.d.ts.map +1 -1
- package/dist/cjs/providers.js +4 -155
- package/dist/esm/ConnectionStatusTray.d.ts.map +1 -1
- package/dist/esm/ConnectionStatusTray.js +7 -5
- package/dist/esm/ErrorTray.d.ts +5 -0
- package/dist/esm/ErrorTray.d.ts.map +1 -0
- package/dist/esm/ErrorTray.js +30 -0
- package/dist/esm/controls/ArticleCellControls.d.ts +10 -0
- package/dist/esm/controls/ArticleCellControls.d.ts.map +1 -0
- package/dist/esm/controls/ArticleCellControls.js +27 -0
- package/dist/esm/controls/Buttons.d.ts +47 -0
- package/dist/esm/controls/Buttons.d.ts.map +1 -0
- package/dist/esm/controls/Buttons.js +57 -0
- package/dist/esm/controls/NotebookCellControls.d.ts +10 -0
- package/dist/esm/controls/NotebookCellControls.d.ts.map +1 -0
- package/dist/esm/controls/NotebookCellControls.js +21 -0
- package/dist/esm/controls/NotebookToolbar.d.ts +4 -0
- package/dist/esm/controls/NotebookToolbar.d.ts.map +1 -0
- package/dist/esm/controls/NotebookToolbar.js +40 -0
- package/dist/esm/controls/Spinner.d.ts +4 -0
- package/dist/esm/controls/Spinner.d.ts.map +1 -0
- package/dist/esm/controls/Spinner.js +4 -0
- package/dist/esm/controls/index.d.ts +5 -0
- package/dist/esm/controls/index.d.ts.map +1 -0
- package/dist/esm/controls/index.js +4 -0
- package/dist/esm/execute/actions.d.ts +55 -0
- package/dist/esm/execute/actions.d.ts.map +1 -0
- package/dist/esm/execute/actions.js +38 -0
- package/dist/esm/execute/busy.d.ts +74 -0
- package/dist/esm/execute/busy.d.ts.map +1 -0
- package/dist/esm/execute/busy.js +150 -0
- package/dist/esm/execute/hooks.d.ts +62 -0
- package/dist/esm/execute/hooks.d.ts.map +1 -0
- package/dist/esm/execute/hooks.js +277 -0
- package/dist/esm/execute/index.d.ts +7 -0
- package/dist/esm/execute/index.d.ts.map +1 -0
- package/dist/esm/execute/index.js +6 -0
- package/dist/esm/execute/leaf.d.ts +26 -0
- package/dist/esm/execute/leaf.d.ts.map +1 -0
- package/dist/esm/execute/leaf.js +147 -0
- package/dist/esm/execute/provider.d.ts +29 -0
- package/dist/esm/execute/provider.d.ts.map +1 -0
- package/dist/esm/execute/provider.js +99 -0
- package/dist/esm/execute/reducer.d.ts +4 -0
- package/dist/esm/execute/reducer.d.ts.map +1 -0
- package/dist/esm/execute/reducer.js +132 -0
- package/dist/esm/execute/selectors.d.ts +22 -0
- package/dist/esm/execute/selectors.d.ts.map +1 -0
- package/dist/esm/execute/selectors.js +77 -0
- package/dist/esm/execute/types.d.ts +49 -0
- package/dist/esm/execute/types.d.ts.map +1 -0
- package/dist/esm/execute/types.js +1 -0
- package/dist/esm/execute/utils.d.ts +23 -0
- package/dist/esm/execute/utils.d.ts.map +1 -0
- package/dist/esm/execute/utils.js +58 -0
- package/dist/esm/index.d.ts +4 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +4 -1
- package/dist/esm/jupyter.d.ts.map +1 -1
- package/dist/esm/jupyter.js +17 -15
- package/dist/esm/output.d.ts +1 -1
- package/dist/esm/output.d.ts.map +1 -1
- package/dist/esm/output.js +8 -5
- package/dist/esm/providers.d.ts +1 -48
- package/dist/esm/providers.d.ts.map +1 -1
- package/dist/esm/providers.js +2 -126
- package/dist/types/ConnectionStatusTray.d.ts.map +1 -1
- package/dist/types/ErrorTray.d.ts +5 -0
- package/dist/types/ErrorTray.d.ts.map +1 -0
- package/dist/types/controls/ArticleCellControls.d.ts +10 -0
- package/dist/types/controls/ArticleCellControls.d.ts.map +1 -0
- package/dist/types/controls/Buttons.d.ts +47 -0
- package/dist/types/controls/Buttons.d.ts.map +1 -0
- package/dist/types/controls/NotebookCellControls.d.ts +10 -0
- package/dist/types/controls/NotebookCellControls.d.ts.map +1 -0
- package/dist/types/controls/NotebookToolbar.d.ts +4 -0
- package/dist/types/controls/NotebookToolbar.d.ts.map +1 -0
- package/dist/types/controls/Spinner.d.ts +4 -0
- package/dist/types/controls/Spinner.d.ts.map +1 -0
- package/dist/types/controls/index.d.ts +5 -0
- package/dist/types/controls/index.d.ts.map +1 -0
- package/dist/types/execute/actions.d.ts +55 -0
- package/dist/types/execute/actions.d.ts.map +1 -0
- package/dist/types/execute/busy.d.ts +74 -0
- package/dist/types/execute/busy.d.ts.map +1 -0
- package/dist/types/execute/hooks.d.ts +62 -0
- package/dist/types/execute/hooks.d.ts.map +1 -0
- package/dist/types/execute/index.d.ts +7 -0
- package/dist/types/execute/index.d.ts.map +1 -0
- package/dist/types/execute/leaf.d.ts +26 -0
- package/dist/types/execute/leaf.d.ts.map +1 -0
- package/dist/types/execute/provider.d.ts +29 -0
- package/dist/types/execute/provider.d.ts.map +1 -0
- package/dist/types/execute/reducer.d.ts +4 -0
- package/dist/types/execute/reducer.d.ts.map +1 -0
- package/dist/types/execute/selectors.d.ts +22 -0
- package/dist/types/execute/selectors.d.ts.map +1 -0
- package/dist/types/execute/types.d.ts +49 -0
- package/dist/types/execute/types.d.ts.map +1 -0
- package/dist/types/execute/utils.d.ts +23 -0
- package/dist/types/execute/utils.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/jupyter.d.ts.map +1 -1
- package/dist/types/output.d.ts +1 -1
- package/dist/types/output.d.ts.map +1 -1
- package/dist/types/providers.d.ts +1 -48
- package/dist/types/providers.d.ts.map +1 -1
- package/package.json +9 -8
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import React, { useCallback } from 'react';
|
|
11
|
+
import { ExecuteScopeContext } from './provider';
|
|
12
|
+
import { useBusyScope } from './busy';
|
|
13
|
+
import { findErrors, useThebeConfig } from 'thebe-react';
|
|
14
|
+
import { SourceFileKind } from 'myst-common';
|
|
15
|
+
export function useExecutionScope({ clearOutputsOnExecute = false, } = {}) {
|
|
16
|
+
var _a;
|
|
17
|
+
const context = React.useContext(ExecuteScopeContext);
|
|
18
|
+
const { config } = useThebeConfig();
|
|
19
|
+
const busy = useBusyScope();
|
|
20
|
+
if (context === undefined) {
|
|
21
|
+
throw new Error('useExecuteScope must be used within a ExecuteScopeProvider');
|
|
22
|
+
}
|
|
23
|
+
const { state, dispatch } = context;
|
|
24
|
+
const start = useCallback((slug) => {
|
|
25
|
+
console.debug(`Jupyter: Starting ${slug}`);
|
|
26
|
+
dispatch({
|
|
27
|
+
type: 'REQUEST_BUILD',
|
|
28
|
+
payload: {
|
|
29
|
+
slug,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}, []);
|
|
33
|
+
const execute = (slug) => {
|
|
34
|
+
// set busy
|
|
35
|
+
Object.entries(state.pages[slug].scopes).forEach(([notebookSlug, { notebook }]) => {
|
|
36
|
+
busy.setNotebook(slug, notebookSlug, notebook.cells.map((c) => c.id), 'execute');
|
|
37
|
+
});
|
|
38
|
+
if (clearOutputsOnExecute) {
|
|
39
|
+
// clear all notebook cell outputs
|
|
40
|
+
Object.values(state.pages[slug].scopes).forEach(({ notebook }) => {
|
|
41
|
+
notebook.clear();
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// let busy state update prior to launching execute
|
|
45
|
+
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
const handler = (_, data) => {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
if (data.subject === 'cell' && data.status === 'idle') {
|
|
49
|
+
const notebookSlug = (_a = data.object.notebookId) !== null && _a !== void 0 ? _a : 'unknown';
|
|
50
|
+
busy.clearCell(slug, notebookSlug, (_b = data.id) !== null && _b !== void 0 ? _b : 'unknown', 'execute');
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
config === null || config === void 0 ? void 0 : config.events.on('status', handler);
|
|
54
|
+
// execute all cells on all notebooks
|
|
55
|
+
yield Promise.all(Object.entries(state.pages[slug].scopes).map(([, { notebook }]) => __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
const execReturns = yield notebook.executeAll(true);
|
|
57
|
+
const errs = findErrors(execReturns);
|
|
58
|
+
if (errs != null)
|
|
59
|
+
console.error('errors', errs);
|
|
60
|
+
})));
|
|
61
|
+
config === null || config === void 0 ? void 0 : config.events.off('status', handler);
|
|
62
|
+
}), 100);
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* clearAll clears all cells in all notebooks for a given rendering
|
|
66
|
+
*
|
|
67
|
+
*/
|
|
68
|
+
const clearAll = useCallback((pageSlug) => {
|
|
69
|
+
Object.entries(state.pages[pageSlug].scopes).forEach(([, { notebook }]) => {
|
|
70
|
+
notebook.clear();
|
|
71
|
+
});
|
|
72
|
+
}, [state]);
|
|
73
|
+
/**
|
|
74
|
+
* resetAll resets all cells in all notebooks for a given rendering
|
|
75
|
+
*/
|
|
76
|
+
const resetAll = useCallback((pageSlug) => {
|
|
77
|
+
Object.entries(state.pages[pageSlug].scopes).forEach(([notebookSlug, { notebook, session }]) => {
|
|
78
|
+
busy.setNotebook(pageSlug, notebookSlug, notebook.cells.map((c) => c.id), 'reset');
|
|
79
|
+
setTimeout(() => {
|
|
80
|
+
var _a;
|
|
81
|
+
notebook.reset();
|
|
82
|
+
(_a = session === null || session === void 0 ? void 0 : session.kernel) === null || _a === void 0 ? void 0 : _a.restart().finally(() => {
|
|
83
|
+
busy.clearNotebook(pageSlug, notebookSlug, 'reset');
|
|
84
|
+
});
|
|
85
|
+
}, 300);
|
|
86
|
+
});
|
|
87
|
+
}, [state]);
|
|
88
|
+
const ready = (_a = context.state.pages[context.slug]) === null || _a === void 0 ? void 0 : _a.ready;
|
|
89
|
+
return Object.assign(Object.assign({}, context), { ready, start, clearAll, resetAll, execute });
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* useNotebookExecution a hook to govern notebook execution in the context of a single
|
|
93
|
+
* cell embedded in an article
|
|
94
|
+
*
|
|
95
|
+
*/
|
|
96
|
+
export function useNotebookExecution(id, clearOutputsOnExecute = false) {
|
|
97
|
+
var _a, _b;
|
|
98
|
+
const context = React.useContext(ExecuteScopeContext);
|
|
99
|
+
const { config } = useThebeConfig();
|
|
100
|
+
const busy = useBusyScope();
|
|
101
|
+
if (context === undefined) {
|
|
102
|
+
throw new Error('useExecuteScope must be used within a ExecuteScopeProvider');
|
|
103
|
+
}
|
|
104
|
+
const { state, dispatch, idkmap } = context;
|
|
105
|
+
const target = (_a = idkmap[id]) !== null && _a !== void 0 ? _a : {};
|
|
106
|
+
const { pageSlug, notebookSlug, cellId } = target;
|
|
107
|
+
// TODO consider extending this to start only the notebook requested, currently this will
|
|
108
|
+
// execute all connected notebooks
|
|
109
|
+
const start = useCallback(() => {
|
|
110
|
+
dispatch({
|
|
111
|
+
type: 'REQUEST_BUILD',
|
|
112
|
+
payload: {
|
|
113
|
+
slug: context.slug,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
}, [target]);
|
|
117
|
+
let cell;
|
|
118
|
+
let notebook;
|
|
119
|
+
if (target && state.pages[pageSlug]) {
|
|
120
|
+
notebook = state.pages[pageSlug].scopes[notebookSlug].notebook;
|
|
121
|
+
if (!notebook)
|
|
122
|
+
console.error('no notebook for', { pageSlug, notebookSlug, cellId });
|
|
123
|
+
cell = notebook === null || notebook === void 0 ? void 0 : notebook.getCellById(cellId);
|
|
124
|
+
if (!cell)
|
|
125
|
+
console.error('no cell found', { pageSlug, notebookSlug, cellId });
|
|
126
|
+
}
|
|
127
|
+
const execute = () => {
|
|
128
|
+
var _a, _b;
|
|
129
|
+
const nb = (_b = (_a = state.pages[pageSlug]) === null || _a === void 0 ? void 0 : _a.scopes[notebookSlug]) === null || _b === void 0 ? void 0 : _b.notebook;
|
|
130
|
+
// set busy
|
|
131
|
+
busy.setNotebook(pageSlug, notebookSlug, nb.cells.map((c) => c.id), 'execute');
|
|
132
|
+
if (clearOutputsOnExecute)
|
|
133
|
+
nb.clear();
|
|
134
|
+
// let busy state update prior to launching execute
|
|
135
|
+
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
136
|
+
const handler = (_, data) => {
|
|
137
|
+
var _a;
|
|
138
|
+
if (data.subject === 'cell' && data.status === 'idle') {
|
|
139
|
+
busy.clearCell(pageSlug, notebookSlug, (_a = data.id) !== null && _a !== void 0 ? _a : 'unknown', 'execute');
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
config === null || config === void 0 ? void 0 : config.events.on('status', handler);
|
|
143
|
+
// execute all cells on the notebooks
|
|
144
|
+
const execReturns = yield nb.executeAll(true);
|
|
145
|
+
const errs = findErrors(execReturns);
|
|
146
|
+
if (errs != null)
|
|
147
|
+
console.error('errors', errs); // TODO: handle errors
|
|
148
|
+
config === null || config === void 0 ? void 0 : config.events.off('status', handler);
|
|
149
|
+
}), 100);
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* clearAll clears all cells in all notebooks for a given rendering
|
|
153
|
+
*
|
|
154
|
+
*/
|
|
155
|
+
const clear = useCallback(() => {
|
|
156
|
+
var _a, _b;
|
|
157
|
+
const nb = (_b = (_a = state.pages[pageSlug]) === null || _a === void 0 ? void 0 : _a.scopes[notebookSlug]) === null || _b === void 0 ? void 0 : _b.notebook;
|
|
158
|
+
nb.clear();
|
|
159
|
+
}, [state]);
|
|
160
|
+
/**
|
|
161
|
+
* resetAll resets all cells in all notebooks for a given rendering
|
|
162
|
+
*/
|
|
163
|
+
const reset = useCallback(() => {
|
|
164
|
+
var _a, _b;
|
|
165
|
+
const { notebook: nb, session } = (_b = (_a = state.pages[pageSlug]) === null || _a === void 0 ? void 0 : _a.scopes[notebookSlug]) !== null && _b !== void 0 ? _b : {};
|
|
166
|
+
busy.setNotebook(pageSlug, notebookSlug, nb.cells.map((c) => c.id), 'reset');
|
|
167
|
+
setTimeout(() => {
|
|
168
|
+
var _a;
|
|
169
|
+
nb.reset();
|
|
170
|
+
(_a = session === null || session === void 0 ? void 0 : session.kernel) === null || _a === void 0 ? void 0 : _a.restart().finally(() => {
|
|
171
|
+
busy.clearNotebook(pageSlug, notebookSlug, 'reset');
|
|
172
|
+
});
|
|
173
|
+
}, 300);
|
|
174
|
+
}, [state]);
|
|
175
|
+
const ready = (_b = context.state.pages[context.slug]) === null || _b === void 0 ? void 0 : _b.ready;
|
|
176
|
+
const notebookIsExecuting = busy.notebook(pageSlug, notebookSlug, 'execute');
|
|
177
|
+
const notebookIsResetting = busy.notebook(pageSlug, notebookSlug, 'reset');
|
|
178
|
+
const notebookIsBusy = notebookIsExecuting || notebookIsResetting;
|
|
179
|
+
return Object.assign(Object.assign({}, context), { ready,
|
|
180
|
+
start,
|
|
181
|
+
clear,
|
|
182
|
+
reset,
|
|
183
|
+
execute, cellIsExecuting: cell ? busy.cell(pageSlug, notebookSlug, cell === null || cell === void 0 ? void 0 : cell.id, 'execute') : false, notebookIsExecuting,
|
|
184
|
+
notebookIsResetting,
|
|
185
|
+
notebookIsBusy, executionCount: cell === null || cell === void 0 ? void 0 : cell.executionCount });
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* useCellExecution a hook to govern the execute status and actions for a single cell
|
|
189
|
+
*
|
|
190
|
+
* @param id
|
|
191
|
+
* @returns
|
|
192
|
+
*/
|
|
193
|
+
export function useCellExecution(id) {
|
|
194
|
+
var _a, _b, _c, _d;
|
|
195
|
+
const busy = useBusyScope();
|
|
196
|
+
const context = React.useContext(ExecuteScopeContext);
|
|
197
|
+
if (context === undefined) {
|
|
198
|
+
throw new Error('useExecuteScope must be used within a ExecuteScopeProvider');
|
|
199
|
+
}
|
|
200
|
+
const { state, idkmap } = context;
|
|
201
|
+
const target = (_a = idkmap[id]) !== null && _a !== void 0 ? _a : {};
|
|
202
|
+
const { pageSlug, notebookSlug, cellId } = target;
|
|
203
|
+
let cell;
|
|
204
|
+
let notebook;
|
|
205
|
+
if (target && state.pages[pageSlug]) {
|
|
206
|
+
notebook = state.pages[pageSlug].scopes[notebookSlug].notebook;
|
|
207
|
+
if (!notebook)
|
|
208
|
+
console.error('no notebook for', { pageSlug, notebookSlug, cellId });
|
|
209
|
+
cell = notebook === null || notebook === void 0 ? void 0 : notebook.getCellById(cellId);
|
|
210
|
+
if (!cell)
|
|
211
|
+
console.error('no cell found', { pageSlug, notebookSlug, cellId });
|
|
212
|
+
}
|
|
213
|
+
const ready = (_b = context.state.pages[context.slug]) === null || _b === void 0 ? void 0 : _b.ready;
|
|
214
|
+
const kind = (_d = (_c = context.state.pages[context.slug]) === null || _c === void 0 ? void 0 : _c.kind) !== null && _d !== void 0 ? _d : SourceFileKind.Article;
|
|
215
|
+
const execute = useCallback(() => {
|
|
216
|
+
if (!cell) {
|
|
217
|
+
console.error('no cell found on execute', { pageSlug, notebookSlug, cellId });
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
// set busy
|
|
221
|
+
busy.setCell(pageSlug, notebookSlug, cell.id, 'execute');
|
|
222
|
+
cell.clear();
|
|
223
|
+
// let busy state update prior to launching execute
|
|
224
|
+
setTimeout(() => {
|
|
225
|
+
if (!cell)
|
|
226
|
+
throw new Error('no cell found on execute');
|
|
227
|
+
cell.execute().then(() => {
|
|
228
|
+
if (!cell)
|
|
229
|
+
throw new Error('no cell found after execute');
|
|
230
|
+
busy.clearCell(pageSlug, notebookSlug, cell === null || cell === void 0 ? void 0 : cell.id, 'execute');
|
|
231
|
+
});
|
|
232
|
+
}, 100);
|
|
233
|
+
}, [state, cell]);
|
|
234
|
+
const clear = useCallback(() => {
|
|
235
|
+
if (!cell) {
|
|
236
|
+
console.error('no cell found on clear', { pageSlug, notebookSlug, cellId });
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
cell.clear();
|
|
240
|
+
}, [state, cell]);
|
|
241
|
+
const notebookIsExecuting = busy.notebook(pageSlug, notebookSlug, 'execute');
|
|
242
|
+
const notebookIsResetting = busy.notebook(pageSlug, notebookSlug, 'reset');
|
|
243
|
+
const notebookIsBusy = notebookIsExecuting || notebookIsResetting;
|
|
244
|
+
return {
|
|
245
|
+
kind,
|
|
246
|
+
ready,
|
|
247
|
+
execute,
|
|
248
|
+
clear,
|
|
249
|
+
cellIsExecuting: cell ? busy.cell(pageSlug, notebookSlug, cell === null || cell === void 0 ? void 0 : cell.id, 'execute') : false,
|
|
250
|
+
notebookIsExecuting,
|
|
251
|
+
notebookIsResetting,
|
|
252
|
+
notebookIsBusy,
|
|
253
|
+
cell,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
export function useIsAComputableCell(id) {
|
|
257
|
+
var _a, _b, _c;
|
|
258
|
+
const context = React.useContext(ExecuteScopeContext);
|
|
259
|
+
if (context === undefined) {
|
|
260
|
+
throw new Error('useExecuteScope must be used within a ExecuteScopeProvider');
|
|
261
|
+
}
|
|
262
|
+
const { idkmap } = context;
|
|
263
|
+
const target = (_a = idkmap[id]) !== null && _a !== void 0 ? _a : {};
|
|
264
|
+
return {
|
|
265
|
+
slug: context.slug,
|
|
266
|
+
computable: !!target,
|
|
267
|
+
ready: (_c = (_b = context.state.pages[context.slug]) === null || _b === void 0 ? void 0 : _b.ready) !== null && _c !== void 0 ? _c : false,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
export function useReadyToExecute() {
|
|
271
|
+
var _a, _b;
|
|
272
|
+
const context = React.useContext(ExecuteScopeContext);
|
|
273
|
+
if (context === undefined) {
|
|
274
|
+
throw new Error('useExecuteScope must be used within a ExecuteScopeProvider');
|
|
275
|
+
}
|
|
276
|
+
return (_b = (_a = context.state.pages[context.slug]) === null || _a === void 0 ? void 0 : _a.ready) !== null && _b !== void 0 ? _b : false;
|
|
277
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/execute/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { ExecuteScopeAction } from './actions';
|
|
3
|
+
import type { IdKeyMap, ExecuteScopeState } from './types';
|
|
4
|
+
export declare function MdastFetcher({ slug, url, dispatch, }: {
|
|
5
|
+
slug: string;
|
|
6
|
+
url: string;
|
|
7
|
+
dispatch: React.Dispatch<ExecuteScopeAction>;
|
|
8
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
9
|
+
export declare function NotebookBuilder({ pageSlug, notebookSlug, idkmap, state, dispatch, }: {
|
|
10
|
+
pageSlug: string;
|
|
11
|
+
notebookSlug: string;
|
|
12
|
+
idkmap: IdKeyMap;
|
|
13
|
+
state: ExecuteScopeState;
|
|
14
|
+
dispatch: React.Dispatch<ExecuteScopeAction>;
|
|
15
|
+
}): null;
|
|
16
|
+
export declare function SessionStarter({ pageSlug, notebookSlug, state, dispatch, }: {
|
|
17
|
+
pageSlug: string;
|
|
18
|
+
notebookSlug: string;
|
|
19
|
+
state: ExecuteScopeState;
|
|
20
|
+
dispatch: React.Dispatch<ExecuteScopeAction>;
|
|
21
|
+
}): null;
|
|
22
|
+
export declare function ServerMonitor({ state, dispatch, }: {
|
|
23
|
+
state: ExecuteScopeState;
|
|
24
|
+
dispatch: React.Dispatch<ExecuteScopeAction>;
|
|
25
|
+
}): null;
|
|
26
|
+
//# sourceMappingURL=leaf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leaf.d.ts","sourceRoot":"","sources":["../../../src/execute/leaf.tsx"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAO3D,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,GAAG,EACH,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;CAC9C,kDAkBA;AAED,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,KAAK,EACL,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;CAC9C,QA8CA;AAED,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,YAAY,EACZ,KAAK,EACL,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;CAC9C,QAoEA;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;CAC9C,QA4BA"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef } from 'react';
|
|
3
|
+
import { useThebeLoader, useThebeConfig, useThebeServer } from 'thebe-react';
|
|
4
|
+
import { notebookFromMdast } from './utils';
|
|
5
|
+
import { selectAreAllNotebookScopesBuilt, selectAreAllSessionsStarted } from './selectors';
|
|
6
|
+
import { useFetchMdast } from 'myst-to-react';
|
|
7
|
+
export function MdastFetcher({ slug, url, dispatch, }) {
|
|
8
|
+
const { data, error } = useFetchMdast({ remote: true, dataUrl: `${url}.json` });
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (!data)
|
|
11
|
+
return;
|
|
12
|
+
dispatch({ type: 'ADD_MDAST', payload: { slug, mdast: data.mdast } });
|
|
13
|
+
}, [data]);
|
|
14
|
+
if (error) {
|
|
15
|
+
return (_jsxs("div", { children: ["error: ", slug, error.message] }));
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
export function NotebookBuilder({ pageSlug, notebookSlug, idkmap, state, dispatch, }) {
|
|
20
|
+
var _a;
|
|
21
|
+
const { core } = useThebeLoader();
|
|
22
|
+
const { config } = useThebeConfig();
|
|
23
|
+
const lock = useRef(false); // TODO can be removed if we solve double render from provider
|
|
24
|
+
const scopeHasNotebook = !!((_a = state.pages[pageSlug]) === null || _a === void 0 ? void 0 : _a.scopes[notebookSlug]);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
var _a;
|
|
27
|
+
if (!core || !config || scopeHasNotebook || lock.current)
|
|
28
|
+
return;
|
|
29
|
+
lock.current = true;
|
|
30
|
+
console.debug(`Jupyter: NotebookBuilder - ${notebookSlug} being added to scope ${pageSlug}`);
|
|
31
|
+
const rendermime = core === null || core === void 0 ? void 0 : core.makeRenderMimeRegistry(config === null || config === void 0 ? void 0 : config.mathjax);
|
|
32
|
+
const notebook = notebookFromMdast(core, config, pageSlug, notebookSlug, state.mdast[notebookSlug].root, idkmap, rendermime);
|
|
33
|
+
// hook up computable targets
|
|
34
|
+
const computables = (_a = state.pages[pageSlug]) === null || _a === void 0 ? void 0 : _a.computables;
|
|
35
|
+
computables === null || computables === void 0 ? void 0 : computables.forEach((c) => {
|
|
36
|
+
if (idkmap[c.label]) {
|
|
37
|
+
idkmap[c.outputKey] = idkmap[c.label];
|
|
38
|
+
idkmap[c.embedKey] = idkmap[c.label];
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
dispatch({
|
|
42
|
+
type: 'ADD_NOTEBOOK',
|
|
43
|
+
payload: { pageSlug, notebookSlug, rendermime, notebook },
|
|
44
|
+
});
|
|
45
|
+
}, [core, config, pageSlug, notebookSlug, scopeHasNotebook, lock]);
|
|
46
|
+
// TODO find a way to check if the all the notebooks are built and do a single dispatch
|
|
47
|
+
// potentilly use a move the loop down into this component
|
|
48
|
+
const allNotebooksAreBuilt = selectAreAllNotebookScopesBuilt(state, pageSlug);
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (!allNotebooksAreBuilt)
|
|
51
|
+
return;
|
|
52
|
+
dispatch({ type: 'BUILD_STATUS', payload: { slug: pageSlug, status: 'wait-for-server' } });
|
|
53
|
+
}, [allNotebooksAreBuilt]);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
export function SessionStarter({ pageSlug, notebookSlug, state, dispatch, }) {
|
|
57
|
+
var _a;
|
|
58
|
+
const { core } = useThebeLoader();
|
|
59
|
+
const { config, server } = useThebeServer();
|
|
60
|
+
const lock = useRef(false); // TODO can be removed if we solve double render from provider
|
|
61
|
+
const scope = (_a = state.pages[pageSlug]) === null || _a === void 0 ? void 0 : _a.scopes[notebookSlug];
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!core || !server || scope.session || lock.current)
|
|
64
|
+
return;
|
|
65
|
+
lock.current = true;
|
|
66
|
+
console.debug(`Jupyter: Starting session for ${pageSlug}-${notebookSlug}`);
|
|
67
|
+
server.listRunningSessions().then((sessions) => {
|
|
68
|
+
console.debug('Jupyter: running sessions', sessions);
|
|
69
|
+
const path = `/${pageSlug}-${notebookSlug}.ipynb`;
|
|
70
|
+
const existing = sessions.find((s) => s.path === path);
|
|
71
|
+
if (existing) {
|
|
72
|
+
console.debug(`session already exists for ${pageSlug}-${notebookSlug}`, existing);
|
|
73
|
+
server.connectToExistingSession(existing, scope.rendermime).then((sesh) => {
|
|
74
|
+
var _a;
|
|
75
|
+
if (sesh == null) {
|
|
76
|
+
console.error(`Could not connect to session for ${pageSlug} ${notebookSlug}`);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
console.debug(`reconnected to session for ${pageSlug}/${notebookSlug}`, sesh);
|
|
80
|
+
console.debug('restarting session', sesh);
|
|
81
|
+
(_a = sesh.kernel) === null || _a === void 0 ? void 0 : _a.restart().then(() => {
|
|
82
|
+
var _a;
|
|
83
|
+
const notebook = (_a = state.pages[pageSlug]) === null || _a === void 0 ? void 0 : _a.scopes[notebookSlug].notebook;
|
|
84
|
+
notebook.attachSession(sesh);
|
|
85
|
+
dispatch({ type: 'ADD_SESSION', payload: { pageSlug, notebookSlug, session: sesh } });
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
server
|
|
91
|
+
.startNewSession(scope.rendermime, Object.assign(Object.assign({}, config === null || config === void 0 ? void 0 : config.kernels), { name: `${pageSlug}-${notebookSlug}.ipynb`, path }))
|
|
92
|
+
.then((sesh) => {
|
|
93
|
+
var _a;
|
|
94
|
+
if (sesh == null) {
|
|
95
|
+
server === null || server === void 0 ? void 0 : server.getKernelSpecs().then((specs) => {
|
|
96
|
+
console.error(`Could not start session for ${pageSlug} ${notebookSlug}`);
|
|
97
|
+
console.debug(`Available kernels: ${Object.keys(specs)}`);
|
|
98
|
+
});
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
console.debug(`session started for ${pageSlug}/${notebookSlug}`, sesh);
|
|
102
|
+
const notebook = (_a = state.pages[pageSlug]) === null || _a === void 0 ? void 0 : _a.scopes[notebookSlug].notebook;
|
|
103
|
+
notebook.attachSession(sesh);
|
|
104
|
+
dispatch({ type: 'ADD_SESSION', payload: { pageSlug, notebookSlug, session: sesh } });
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}, [core, config, pageSlug, notebookSlug, lock]);
|
|
109
|
+
// TODO avoid multiple dispatch?
|
|
110
|
+
const allSessionsAreStarted = selectAreAllSessionsStarted(state, pageSlug);
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
if (!allSessionsAreStarted)
|
|
113
|
+
return;
|
|
114
|
+
dispatch({
|
|
115
|
+
type: 'SET_RENDERING_READY',
|
|
116
|
+
payload: { slug: pageSlug },
|
|
117
|
+
});
|
|
118
|
+
}, [allSessionsAreStarted]);
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
export function ServerMonitor({ state, dispatch, }) {
|
|
122
|
+
const { core, load, loading } = useThebeLoader();
|
|
123
|
+
const { ready, error } = useThebeServer();
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
if (core || loading)
|
|
126
|
+
return;
|
|
127
|
+
load();
|
|
128
|
+
}, [core, load, loading]);
|
|
129
|
+
// When server is ready, move any waiting builds onto the start session step
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
if (ready) {
|
|
132
|
+
// TODO optimize to do a single dispatch
|
|
133
|
+
Object.entries(state.builds).forEach(([slug, { status }]) => {
|
|
134
|
+
if (status === 'wait-for-server') {
|
|
135
|
+
dispatch({ type: 'BUILD_STATUS', payload: { slug, status: 'start-session' } });
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}, [ready, state]);
|
|
140
|
+
useEffect(() => {
|
|
141
|
+
if (!error)
|
|
142
|
+
return;
|
|
143
|
+
// TODO
|
|
144
|
+
// dispatch({ type: 'SERVER_ERROR', payload: error });
|
|
145
|
+
}, [error]);
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Dependency } from 'myst-common';
|
|
2
|
+
import { SourceFileKind } from 'myst-common';
|
|
3
|
+
import type { Root } from 'mdast';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import type { ExecuteScopeAction } from './actions';
|
|
6
|
+
import type { ExecuteScopeState, IdKeyMap } from './types';
|
|
7
|
+
export interface ExecuteScopeType {
|
|
8
|
+
slug: string;
|
|
9
|
+
state: ExecuteScopeState;
|
|
10
|
+
dispatch: React.Dispatch<ExecuteScopeAction>;
|
|
11
|
+
idkmap: IdKeyMap;
|
|
12
|
+
}
|
|
13
|
+
export declare const ExecuteScopeContext: React.Context<ExecuteScopeType | undefined>;
|
|
14
|
+
type ArticleContents = {
|
|
15
|
+
slug: string;
|
|
16
|
+
kind: SourceFileKind;
|
|
17
|
+
mdast: Root;
|
|
18
|
+
dependencies?: Dependency[];
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* The ExecuteScopeProvider is responsible for maintaining the state of the
|
|
22
|
+
* execution scope. It is also responsible for fetching the json for dependencies
|
|
23
|
+
* and adding them to the sources tree.
|
|
24
|
+
*/
|
|
25
|
+
export declare function ExecuteScopeProvider({ children, contents, }: React.PropsWithChildren<{
|
|
26
|
+
contents: ArticleContents;
|
|
27
|
+
}>): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/execute/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,KAAwC,MAAM,OAAO,CAAC;AAE7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAc,iBAAiB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAUvE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAC7C,MAAM,EAAE,QAAQ,CAAC;CAClB;AAED,eAAO,MAAM,mBAAmB,6CAA+D,CAAC;AAEhG,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,IAAI,CAAC;IACZ,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC;CAC7B,CAAC;AA8DF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,GACT,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAAE,QAAQ,EAAE,eAAe,CAAA;CAAE,CAAC,2CAgGxD"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { SourceFileKind } from 'myst-common';
|
|
3
|
+
import React, { useEffect, useReducer, useRef } from 'react';
|
|
4
|
+
import { selectAll } from 'unist-util-select';
|
|
5
|
+
import { reducer } from './reducer';
|
|
6
|
+
import { selectAreAllDependenciesReady, selectDependenciesToFetch, selectScopeNotebooksToBuild, selectSessionsToStart, } from './selectors';
|
|
7
|
+
import { MdastFetcher, NotebookBuilder, ServerMonitor, SessionStarter } from './leaf';
|
|
8
|
+
export const ExecuteScopeContext = React.createContext(undefined);
|
|
9
|
+
function useScopeNavigate({ contents: { slug, kind, mdast, dependencies }, state, dispatch, }) {
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (state.pages[slug]) {
|
|
12
|
+
console.debug(`Jupyter: ExecuteScopeProvider - ${slug} is already in scope`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const computables = selectAll('container > embed', mdast).map((node) => {
|
|
16
|
+
const { key, label, source } = node;
|
|
17
|
+
const output = selectAll('output', node);
|
|
18
|
+
if (output.length === 0)
|
|
19
|
+
console.error(`embed must have exactly one output ${key}`);
|
|
20
|
+
if (output.length > 1)
|
|
21
|
+
console.warn(`embed has more than one output block ${key}}`);
|
|
22
|
+
return { embedKey: key, outputKey: output[0].key, label, source };
|
|
23
|
+
});
|
|
24
|
+
dispatch({
|
|
25
|
+
type: 'NAVIGATE',
|
|
26
|
+
payload: {
|
|
27
|
+
kind: kind,
|
|
28
|
+
slug: slug,
|
|
29
|
+
mdast: mdast,
|
|
30
|
+
dependencies: dependencies !== null && dependencies !== void 0 ? dependencies : [],
|
|
31
|
+
computables,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}, [slug]);
|
|
35
|
+
}
|
|
36
|
+
function useExecutionScopeFetcher({ slug, state, dispatch, }) {
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (!state.builds[slug])
|
|
39
|
+
return;
|
|
40
|
+
// TODO could be moved to the leaf
|
|
41
|
+
if (state.builds[slug].status === 'pending') {
|
|
42
|
+
dispatch({ type: 'BUILD_STATUS', payload: { slug, status: 'fetching' } });
|
|
43
|
+
}
|
|
44
|
+
// TODO could be moved to the leaf
|
|
45
|
+
if (state.builds[slug].status === 'fetching') {
|
|
46
|
+
if (selectAreAllDependenciesReady(state, slug)) {
|
|
47
|
+
dispatch({ type: 'BUILD_STATUS', payload: { slug, status: 'build-notebooks' } });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, [state.builds, state.mdast]);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The ExecuteScopeProvider is responsible for maintaining the state of the
|
|
54
|
+
* execution scope. It is also responsible for fetching the json for dependencies
|
|
55
|
+
* and adding them to the sources tree.
|
|
56
|
+
*/
|
|
57
|
+
export function ExecuteScopeProvider({ children, contents, }) {
|
|
58
|
+
var _a;
|
|
59
|
+
// compute incoming for first render
|
|
60
|
+
const computables = selectAll('container > embed', contents.mdast).map((node) => {
|
|
61
|
+
const { key, label, source } = node;
|
|
62
|
+
const output = selectAll('output', node);
|
|
63
|
+
if (output.length === 0)
|
|
64
|
+
console.error(`embed must have exactly one output ${key}`);
|
|
65
|
+
if (output.length > 1)
|
|
66
|
+
console.warn(`embed has mpre than one output block ${key}}`);
|
|
67
|
+
return { embedKey: key, outputKey: output[0].key, label, source };
|
|
68
|
+
});
|
|
69
|
+
const initialState = {
|
|
70
|
+
mdast: {
|
|
71
|
+
[contents.slug]: { root: contents.mdast },
|
|
72
|
+
},
|
|
73
|
+
pages: {
|
|
74
|
+
[contents.slug]: {
|
|
75
|
+
computable: computables.length > 0 || contents.kind === SourceFileKind.Notebook,
|
|
76
|
+
kind: contents.kind,
|
|
77
|
+
slug: contents.slug,
|
|
78
|
+
dependencies: (_a = contents.dependencies) !== null && _a !== void 0 ? _a : [],
|
|
79
|
+
computables,
|
|
80
|
+
ready: false,
|
|
81
|
+
scopes: {},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
builds: {},
|
|
85
|
+
};
|
|
86
|
+
const [state, dispatch] = useReducer(reducer, initialState);
|
|
87
|
+
const idkmap = useRef({});
|
|
88
|
+
useScopeNavigate({ contents, state: state, dispatch });
|
|
89
|
+
// TODO phase this out as it is based on the current slug only!
|
|
90
|
+
useExecutionScopeFetcher({ slug: contents.slug, state: state, dispatch });
|
|
91
|
+
const fetchTargets = selectDependenciesToFetch(state);
|
|
92
|
+
const notebookBuildTargets = selectScopeNotebooksToBuild(state);
|
|
93
|
+
const sessionStartTargets = selectSessionsToStart(state);
|
|
94
|
+
const memo = React.useMemo(() => ({ slug: contents.slug, state, dispatch, idkmap: idkmap.current }), [state, contents.slug]);
|
|
95
|
+
if (typeof window !== 'undefined') {
|
|
96
|
+
window.executeScope = memo;
|
|
97
|
+
}
|
|
98
|
+
return (_jsxs(ExecuteScopeContext.Provider, { value: memo, children: [_jsxs("div", { className: "hidden", children: [fetchTargets.length > 0 && (_jsx("div", { className: "p-1 pl-4", children: fetchTargets.map(({ slug, url }) => (_jsx(MdastFetcher, { slug: slug, url: url, dispatch: dispatch }, `fetch-${slug}`))) })), notebookBuildTargets.length > 0 && (_jsx("div", { className: "p-1 pl-4", children: notebookBuildTargets.map(({ pageSlug, notebookSlug }) => (_jsx(NotebookBuilder, { pageSlug: pageSlug, notebookSlug: notebookSlug, idkmap: idkmap.current, state: state, dispatch: dispatch }, `build-${pageSlug}-${notebookSlug}`))) })), sessionStartTargets.length > 0 && (_jsx("div", { className: "p-1 pl-4", children: sessionStartTargets.map(({ pageSlug, notebookSlug }) => (_jsx(SessionStarter, { pageSlug: pageSlug, notebookSlug: notebookSlug, state: state, dispatch: dispatch }, `session-${pageSlug}-${notebookSlug}`))) }))] }), _jsx(ServerMonitor, { state: state, dispatch: dispatch }), children] }));
|
|
99
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../../src/execute/reducer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AASpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,wBAAgB,OAAO,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,kBAAkB,GAAG,iBAAiB,CAuL/F"}
|