@myst-theme/jupyter 0.3.2 → 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.
Files changed (176) hide show
  1. package/dist/cjs/ConnectionStatusTray.d.ts +2 -0
  2. package/dist/cjs/ConnectionStatusTray.d.ts.map +1 -0
  3. package/dist/cjs/ConnectionStatusTray.js +56 -0
  4. package/dist/cjs/ErrorTray.d.ts +5 -0
  5. package/dist/cjs/ErrorTray.d.ts.map +1 -0
  6. package/dist/cjs/ErrorTray.js +34 -0
  7. package/dist/cjs/controls/ArticleCellControls.d.ts +10 -0
  8. package/dist/cjs/controls/ArticleCellControls.d.ts.map +1 -0
  9. package/dist/cjs/controls/ArticleCellControls.js +33 -0
  10. package/dist/cjs/controls/Buttons.d.ts +47 -0
  11. package/dist/cjs/controls/Buttons.d.ts.map +1 -0
  12. package/dist/cjs/controls/Buttons.js +70 -0
  13. package/dist/cjs/controls/NotebookCellControls.d.ts +10 -0
  14. package/dist/cjs/controls/NotebookCellControls.d.ts.map +1 -0
  15. package/dist/cjs/controls/NotebookCellControls.js +27 -0
  16. package/dist/cjs/controls/NotebookToolbar.d.ts +4 -0
  17. package/dist/cjs/controls/NotebookToolbar.d.ts.map +1 -0
  18. package/dist/cjs/controls/NotebookToolbar.js +47 -0
  19. package/dist/cjs/controls/Spinner.d.ts +4 -0
  20. package/dist/cjs/controls/Spinner.d.ts.map +1 -0
  21. package/dist/cjs/controls/Spinner.js +8 -0
  22. package/dist/cjs/controls/index.d.ts +5 -0
  23. package/dist/cjs/controls/index.d.ts.map +1 -0
  24. package/dist/cjs/controls/index.js +20 -0
  25. package/dist/cjs/execute/actions.d.ts +55 -0
  26. package/dist/cjs/execute/actions.d.ts.map +1 -0
  27. package/dist/cjs/execute/actions.js +49 -0
  28. package/dist/cjs/execute/busy.d.ts +74 -0
  29. package/dist/cjs/execute/busy.d.ts.map +1 -0
  30. package/dist/cjs/execute/busy.js +182 -0
  31. package/dist/cjs/execute/hooks.d.ts +62 -0
  32. package/dist/cjs/execute/hooks.d.ts.map +1 -0
  33. package/dist/cjs/execute/hooks.js +308 -0
  34. package/dist/cjs/execute/index.d.ts +7 -0
  35. package/dist/cjs/execute/index.d.ts.map +1 -0
  36. package/dist/cjs/execute/index.js +22 -0
  37. package/dist/cjs/execute/leaf.d.ts +26 -0
  38. package/dist/cjs/execute/leaf.d.ts.map +1 -0
  39. package/dist/cjs/execute/leaf.js +154 -0
  40. package/dist/cjs/execute/provider.d.ts +29 -0
  41. package/dist/cjs/execute/provider.d.ts.map +1 -0
  42. package/dist/cjs/execute/provider.js +126 -0
  43. package/dist/cjs/execute/reducer.d.ts +4 -0
  44. package/dist/cjs/execute/reducer.d.ts.map +1 -0
  45. package/dist/cjs/execute/reducer.js +136 -0
  46. package/dist/cjs/execute/selectors.d.ts +22 -0
  47. package/dist/cjs/execute/selectors.d.ts.map +1 -0
  48. package/dist/cjs/execute/selectors.js +89 -0
  49. package/dist/cjs/execute/types.d.ts +49 -0
  50. package/dist/cjs/execute/types.d.ts.map +1 -0
  51. package/dist/cjs/execute/types.js +2 -0
  52. package/dist/cjs/execute/utils.d.ts +23 -0
  53. package/dist/cjs/execute/utils.d.ts.map +1 -0
  54. package/dist/cjs/execute/utils.js +62 -0
  55. package/dist/cjs/index.d.ts +4 -0
  56. package/dist/cjs/index.d.ts.map +1 -1
  57. package/dist/cjs/index.js +4 -0
  58. package/dist/cjs/jupyter.d.ts.map +1 -1
  59. package/dist/cjs/jupyter.js +19 -17
  60. package/dist/cjs/output.d.ts +1 -1
  61. package/dist/cjs/output.d.ts.map +1 -1
  62. package/dist/cjs/output.js +7 -4
  63. package/dist/cjs/providers.d.ts +1 -48
  64. package/dist/cjs/providers.d.ts.map +1 -1
  65. package/dist/cjs/providers.js +4 -155
  66. package/dist/cjs/safe.js +1 -1
  67. package/dist/esm/ConnectionStatusTray.d.ts +2 -0
  68. package/dist/esm/ConnectionStatusTray.d.ts.map +1 -0
  69. package/dist/esm/ConnectionStatusTray.js +52 -0
  70. package/dist/esm/ErrorTray.d.ts +5 -0
  71. package/dist/esm/ErrorTray.d.ts.map +1 -0
  72. package/dist/esm/ErrorTray.js +30 -0
  73. package/dist/esm/controls/ArticleCellControls.d.ts +10 -0
  74. package/dist/esm/controls/ArticleCellControls.d.ts.map +1 -0
  75. package/dist/esm/controls/ArticleCellControls.js +27 -0
  76. package/dist/esm/controls/Buttons.d.ts +47 -0
  77. package/dist/esm/controls/Buttons.d.ts.map +1 -0
  78. package/dist/esm/controls/Buttons.js +57 -0
  79. package/dist/esm/controls/NotebookCellControls.d.ts +10 -0
  80. package/dist/esm/controls/NotebookCellControls.d.ts.map +1 -0
  81. package/dist/esm/controls/NotebookCellControls.js +21 -0
  82. package/dist/esm/controls/NotebookToolbar.d.ts +4 -0
  83. package/dist/esm/controls/NotebookToolbar.d.ts.map +1 -0
  84. package/dist/esm/controls/NotebookToolbar.js +40 -0
  85. package/dist/esm/controls/Spinner.d.ts +4 -0
  86. package/dist/esm/controls/Spinner.d.ts.map +1 -0
  87. package/dist/esm/controls/Spinner.js +4 -0
  88. package/dist/esm/controls/index.d.ts +5 -0
  89. package/dist/esm/controls/index.d.ts.map +1 -0
  90. package/dist/esm/controls/index.js +4 -0
  91. package/dist/esm/execute/actions.d.ts +55 -0
  92. package/dist/esm/execute/actions.d.ts.map +1 -0
  93. package/dist/esm/execute/actions.js +38 -0
  94. package/dist/esm/execute/busy.d.ts +74 -0
  95. package/dist/esm/execute/busy.d.ts.map +1 -0
  96. package/dist/esm/execute/busy.js +150 -0
  97. package/dist/esm/execute/hooks.d.ts +62 -0
  98. package/dist/esm/execute/hooks.d.ts.map +1 -0
  99. package/dist/esm/execute/hooks.js +277 -0
  100. package/dist/esm/execute/index.d.ts +7 -0
  101. package/dist/esm/execute/index.d.ts.map +1 -0
  102. package/dist/esm/execute/index.js +6 -0
  103. package/dist/esm/execute/leaf.d.ts +26 -0
  104. package/dist/esm/execute/leaf.d.ts.map +1 -0
  105. package/dist/esm/execute/leaf.js +147 -0
  106. package/dist/esm/execute/provider.d.ts +29 -0
  107. package/dist/esm/execute/provider.d.ts.map +1 -0
  108. package/dist/esm/execute/provider.js +99 -0
  109. package/dist/esm/execute/reducer.d.ts +4 -0
  110. package/dist/esm/execute/reducer.d.ts.map +1 -0
  111. package/dist/esm/execute/reducer.js +132 -0
  112. package/dist/esm/execute/selectors.d.ts +22 -0
  113. package/dist/esm/execute/selectors.d.ts.map +1 -0
  114. package/dist/esm/execute/selectors.js +77 -0
  115. package/dist/esm/execute/types.d.ts +49 -0
  116. package/dist/esm/execute/types.d.ts.map +1 -0
  117. package/dist/esm/execute/types.js +1 -0
  118. package/dist/esm/execute/utils.d.ts +23 -0
  119. package/dist/esm/execute/utils.d.ts.map +1 -0
  120. package/dist/esm/execute/utils.js +58 -0
  121. package/dist/esm/index.d.ts +4 -0
  122. package/dist/esm/index.d.ts.map +1 -1
  123. package/dist/esm/index.js +4 -0
  124. package/dist/esm/jupyter.d.ts.map +1 -1
  125. package/dist/esm/jupyter.js +17 -15
  126. package/dist/esm/output.d.ts +1 -1
  127. package/dist/esm/output.d.ts.map +1 -1
  128. package/dist/esm/output.js +8 -5
  129. package/dist/esm/providers.d.ts +1 -48
  130. package/dist/esm/providers.d.ts.map +1 -1
  131. package/dist/esm/providers.js +2 -126
  132. package/dist/esm/safe.js +1 -1
  133. package/dist/types/ConnectionStatusTray.d.ts +2 -0
  134. package/dist/types/ConnectionStatusTray.d.ts.map +1 -0
  135. package/dist/types/ErrorTray.d.ts +5 -0
  136. package/dist/types/ErrorTray.d.ts.map +1 -0
  137. package/dist/types/controls/ArticleCellControls.d.ts +10 -0
  138. package/dist/types/controls/ArticleCellControls.d.ts.map +1 -0
  139. package/dist/types/controls/Buttons.d.ts +47 -0
  140. package/dist/types/controls/Buttons.d.ts.map +1 -0
  141. package/dist/types/controls/NotebookCellControls.d.ts +10 -0
  142. package/dist/types/controls/NotebookCellControls.d.ts.map +1 -0
  143. package/dist/types/controls/NotebookToolbar.d.ts +4 -0
  144. package/dist/types/controls/NotebookToolbar.d.ts.map +1 -0
  145. package/dist/types/controls/Spinner.d.ts +4 -0
  146. package/dist/types/controls/Spinner.d.ts.map +1 -0
  147. package/dist/types/controls/index.d.ts +5 -0
  148. package/dist/types/controls/index.d.ts.map +1 -0
  149. package/dist/types/execute/actions.d.ts +55 -0
  150. package/dist/types/execute/actions.d.ts.map +1 -0
  151. package/dist/types/execute/busy.d.ts +74 -0
  152. package/dist/types/execute/busy.d.ts.map +1 -0
  153. package/dist/types/execute/hooks.d.ts +62 -0
  154. package/dist/types/execute/hooks.d.ts.map +1 -0
  155. package/dist/types/execute/index.d.ts +7 -0
  156. package/dist/types/execute/index.d.ts.map +1 -0
  157. package/dist/types/execute/leaf.d.ts +26 -0
  158. package/dist/types/execute/leaf.d.ts.map +1 -0
  159. package/dist/types/execute/provider.d.ts +29 -0
  160. package/dist/types/execute/provider.d.ts.map +1 -0
  161. package/dist/types/execute/reducer.d.ts +4 -0
  162. package/dist/types/execute/reducer.d.ts.map +1 -0
  163. package/dist/types/execute/selectors.d.ts +22 -0
  164. package/dist/types/execute/selectors.d.ts.map +1 -0
  165. package/dist/types/execute/types.d.ts +49 -0
  166. package/dist/types/execute/types.d.ts.map +1 -0
  167. package/dist/types/execute/utils.d.ts +23 -0
  168. package/dist/types/execute/utils.d.ts.map +1 -0
  169. package/dist/types/index.d.ts +4 -0
  170. package/dist/types/index.d.ts.map +1 -1
  171. package/dist/types/jupyter.d.ts.map +1 -1
  172. package/dist/types/output.d.ts +1 -1
  173. package/dist/types/output.d.ts.map +1 -1
  174. package/dist/types/providers.d.ts +1 -48
  175. package/dist/types/providers.d.ts.map +1 -1
  176. package/package.json +9 -8
@@ -0,0 +1,62 @@
1
+ import React from 'react';
2
+ import type { IdOrKey } from './types';
3
+ import type { IThebeCell } from 'thebe-core';
4
+ import { SourceFileKind } from 'myst-common';
5
+ export declare function useExecutionScope({ clearOutputsOnExecute, }?: {
6
+ clearOutputsOnExecute?: boolean;
7
+ }): {
8
+ ready: boolean;
9
+ start: (slug: string) => void;
10
+ clearAll: (pageSlug: string) => void;
11
+ resetAll: (pageSlug: string) => void;
12
+ execute: (slug: string) => void;
13
+ slug: string;
14
+ state: import("./types").ExecuteScopeState;
15
+ dispatch: React.Dispatch<import("./actions").ExecuteScopeAction>;
16
+ idkmap: import("./types").IdKeyMap;
17
+ };
18
+ /**
19
+ * useNotebookExecution a hook to govern notebook execution in the context of a single
20
+ * cell embedded in an article
21
+ *
22
+ */
23
+ export declare function useNotebookExecution(id: IdOrKey, clearOutputsOnExecute?: boolean): {
24
+ ready: boolean;
25
+ start: () => void;
26
+ clear: () => void;
27
+ reset: () => void;
28
+ execute: () => void;
29
+ cellIsExecuting: boolean;
30
+ notebookIsExecuting: boolean;
31
+ notebookIsResetting: boolean;
32
+ notebookIsBusy: boolean;
33
+ executionCount: number | null | undefined;
34
+ slug: string;
35
+ state: import("./types").ExecuteScopeState;
36
+ dispatch: React.Dispatch<import("./actions").ExecuteScopeAction>;
37
+ idkmap: import("./types").IdKeyMap;
38
+ };
39
+ /**
40
+ * useCellExecution a hook to govern the execute status and actions for a single cell
41
+ *
42
+ * @param id
43
+ * @returns
44
+ */
45
+ export declare function useCellExecution(id: IdOrKey): {
46
+ kind: SourceFileKind;
47
+ ready: boolean;
48
+ execute: () => void;
49
+ clear: () => void;
50
+ cellIsExecuting: boolean;
51
+ notebookIsExecuting: boolean;
52
+ notebookIsResetting: boolean;
53
+ notebookIsBusy: boolean;
54
+ cell: IThebeCell | undefined;
55
+ };
56
+ export declare function useIsAComputableCell(id: IdOrKey): {
57
+ slug: string;
58
+ computable: boolean;
59
+ ready: boolean;
60
+ };
61
+ export declare function useReadyToExecute(): boolean;
62
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/execute/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,KAAK,EAAE,UAAU,EAA0C,MAAM,YAAY,CAAC;AAGrF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,wBAAgB,iBAAiB,CAAC,EAChC,qBAA6B,GAC9B,GAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAO;;kBAUR,MAAM;yBAsD1B,MAAM;yBAYN,MAAM;oBAxDI,MAAM;;;;;EAgF9B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,OAAO,EAAE,qBAAqB,UAAQ;;;;;;;;;;;;;;;EA4G9E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,OAAO;;;;;;;;;;EAiE3C;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,OAAO;;;;EAc/C;AAED,wBAAgB,iBAAiB,YAOhC"}
@@ -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,7 @@
1
+ export * from './hooks';
2
+ export * from './actions';
3
+ export * from './provider';
4
+ export * from './selectors';
5
+ export * from './types';
6
+ export * from './busy';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -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,6 @@
1
+ export * from './hooks';
2
+ export * from './actions';
3
+ export * from './provider';
4
+ export * from './selectors';
5
+ export * from './types';
6
+ export * from './busy';
@@ -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"}