munchboka-edutools 0.2.3__py3-none-any.whl

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.

Potentially problematic release.


This version of munchboka-edutools might be problematic. Click here for more details.

Files changed (157) hide show
  1. munchboka_edutools/__init__.py +184 -0
  2. munchboka_edutools/_plotmath_shim.py +126 -0
  3. munchboka_edutools/_version.py +2 -0
  4. munchboka_edutools/directives/__init__.py +1 -0
  5. munchboka_edutools/directives/admonitions.py +389 -0
  6. munchboka_edutools/directives/cas_popup.py +428 -0
  7. munchboka_edutools/directives/clear.py +103 -0
  8. munchboka_edutools/directives/dialogue.py +137 -0
  9. munchboka_edutools/directives/escape_room.py +296 -0
  10. munchboka_edutools/directives/escape_room2.py +318 -0
  11. munchboka_edutools/directives/factor_tree.py +552 -0
  12. munchboka_edutools/directives/flashcards.py +233 -0
  13. munchboka_edutools/directives/ggb.py +209 -0
  14. munchboka_edutools/directives/ggb_icon.py +105 -0
  15. munchboka_edutools/directives/ggb_popup.py +308 -0
  16. munchboka_edutools/directives/horner.py +326 -0
  17. munchboka_edutools/directives/interactive_code.py +75 -0
  18. munchboka_edutools/directives/jeopardy.py +252 -0
  19. munchboka_edutools/directives/jeopardy2.py +636 -0
  20. munchboka_edutools/directives/multi_plot.py +2524 -0
  21. munchboka_edutools/directives/multi_plot2.py +252 -0
  22. munchboka_edutools/directives/pair_puzzle.py +191 -0
  23. munchboka_edutools/directives/parsons.py +109 -0
  24. munchboka_edutools/directives/plot.py +3758 -0
  25. munchboka_edutools/directives/poly_icon.py +111 -0
  26. munchboka_edutools/directives/polydiv.py +346 -0
  27. munchboka_edutools/directives/popup.py +245 -0
  28. munchboka_edutools/directives/quiz.py +291 -0
  29. munchboka_edutools/directives/quiz2.py +453 -0
  30. munchboka_edutools/directives/signchart.py +519 -0
  31. munchboka_edutools/directives/signchart2.py +1545 -0
  32. munchboka_edutools/directives/timed_quiz.py +436 -0
  33. munchboka_edutools/directives/turtle.py +157 -0
  34. munchboka_edutools/static/css/admonitions.css +2012 -0
  35. munchboka_edutools/static/css/cas_popup.css +242 -0
  36. munchboka_edutools/static/css/code_mirror_themes/github_dark_cm.css +112 -0
  37. munchboka_edutools/static/css/code_mirror_themes/github_dark_default_cm.css +40 -0
  38. munchboka_edutools/static/css/code_mirror_themes/github_dark_high_contrast_cm.css +141 -0
  39. munchboka_edutools/static/css/code_mirror_themes/github_light_cm.css +120 -0
  40. munchboka_edutools/static/css/code_mirror_themes/github_light_default_cm.css +108 -0
  41. munchboka_edutools/static/css/code_mirror_themes/one_dark_cm.css +121 -0
  42. munchboka_edutools/static/css/dialogue.css +92 -0
  43. munchboka_edutools/static/css/escapeRoom/escape-room.css +223 -0
  44. munchboka_edutools/static/css/figures.css +321 -0
  45. munchboka_edutools/static/css/flashcards.css +219 -0
  46. munchboka_edutools/static/css/general_style.css +74 -0
  47. munchboka_edutools/static/css/github-dark-high-contrast.css +141 -0
  48. munchboka_edutools/static/css/github-dark.css +147 -0
  49. munchboka_edutools/static/css/github-light.css +155 -0
  50. munchboka_edutools/static/css/interactive_code/style.css +575 -0
  51. munchboka_edutools/static/css/interactive_code.css +582 -0
  52. munchboka_edutools/static/css/jeopardy.css +553 -0
  53. munchboka_edutools/static/css/pairPuzzle/style.css +177 -0
  54. munchboka_edutools/static/css/parsons/parsonsPuzzle.css +331 -0
  55. munchboka_edutools/static/css/popup.css +115 -0
  56. munchboka_edutools/static/css/quiz.css +377 -0
  57. munchboka_edutools/static/css/timedQuiz.css +375 -0
  58. munchboka_edutools/static/icons/ggb/mode_evaluate.svg +1 -0
  59. munchboka_edutools/static/icons/ggb/mode_extremum.svg +1 -0
  60. munchboka_edutools/static/icons/ggb/mode_intersect.svg +1 -0
  61. munchboka_edutools/static/icons/ggb/mode_nsolve.svg +1 -0
  62. munchboka_edutools/static/icons/ggb/mode_numeric.svg +1 -0
  63. munchboka_edutools/static/icons/ggb/mode_point.svg +1 -0
  64. munchboka_edutools/static/icons/ggb/mode_solve.svg +1 -0
  65. munchboka_edutools/static/icons/misc/windows-logo.svg +1 -0
  66. munchboka_edutools/static/icons/outline/dark_mode/academic.svg +3 -0
  67. munchboka_edutools/static/icons/outline/dark_mode/backward.svg +3 -0
  68. munchboka_edutools/static/icons/outline/dark_mode/book.svg +3 -0
  69. munchboka_edutools/static/icons/outline/dark_mode/chat_bubble.svg +3 -0
  70. munchboka_edutools/static/icons/outline/dark_mode/check.svg +3 -0
  71. munchboka_edutools/static/icons/outline/dark_mode/cmd_line.svg +3 -0
  72. munchboka_edutools/static/icons/outline/dark_mode/file.svg +1 -0
  73. munchboka_edutools/static/icons/outline/dark_mode/fire.svg +4 -0
  74. munchboka_edutools/static/icons/outline/dark_mode/key.svg +3 -0
  75. munchboka_edutools/static/icons/outline/dark_mode/magnifying.svg +3 -0
  76. munchboka_edutools/static/icons/outline/dark_mode/pencil_square.svg +3 -0
  77. munchboka_edutools/static/icons/outline/dark_mode/play.svg +3 -0
  78. munchboka_edutools/static/icons/outline/dark_mode/question.svg +3 -0
  79. munchboka_edutools/static/icons/outline/dark_mode/square_check.svg +1 -0
  80. munchboka_edutools/static/icons/outline/dark_mode/stop.svg +3 -0
  81. munchboka_edutools/static/icons/outline/dark_mode/summary.svg +3 -0
  82. munchboka_edutools/static/icons/outline/dark_mode/undo.svg +3 -0
  83. munchboka_edutools/static/icons/outline/dark_mode/unlock.svg +3 -0
  84. munchboka_edutools/static/icons/outline/light_mode/academic.svg +3 -0
  85. munchboka_edutools/static/icons/outline/light_mode/backward.svg +3 -0
  86. munchboka_edutools/static/icons/outline/light_mode/book.svg +3 -0
  87. munchboka_edutools/static/icons/outline/light_mode/chat_bubble.svg +3 -0
  88. munchboka_edutools/static/icons/outline/light_mode/check.svg +3 -0
  89. munchboka_edutools/static/icons/outline/light_mode/cmd_line.svg +3 -0
  90. munchboka_edutools/static/icons/outline/light_mode/file.svg +1 -0
  91. munchboka_edutools/static/icons/outline/light_mode/fire.svg +4 -0
  92. munchboka_edutools/static/icons/outline/light_mode/key.svg +3 -0
  93. munchboka_edutools/static/icons/outline/light_mode/magnifying.svg +3 -0
  94. munchboka_edutools/static/icons/outline/light_mode/pencil_square.svg +3 -0
  95. munchboka_edutools/static/icons/outline/light_mode/play.svg +3 -0
  96. munchboka_edutools/static/icons/outline/light_mode/question.svg +3 -0
  97. munchboka_edutools/static/icons/outline/light_mode/square_check.svg +1 -0
  98. munchboka_edutools/static/icons/outline/light_mode/stop.svg +3 -0
  99. munchboka_edutools/static/icons/outline/light_mode/summary.svg +3 -0
  100. munchboka_edutools/static/icons/outline/light_mode/undo.svg +3 -0
  101. munchboka_edutools/static/icons/outline/light_mode/unlock.svg +3 -0
  102. munchboka_edutools/static/icons/polyicons/cubicdown.svg +3 -0
  103. munchboka_edutools/static/icons/polyicons/cubicup.svg +3 -0
  104. munchboka_edutools/static/icons/polyicons/frown.svg +3 -0
  105. munchboka_edutools/static/icons/polyicons/smile.svg +3 -0
  106. munchboka_edutools/static/icons/solid/dark_mode/academic.svg +5 -0
  107. munchboka_edutools/static/icons/solid/dark_mode/backward.svg +3 -0
  108. munchboka_edutools/static/icons/solid/dark_mode/book.svg +3 -0
  109. munchboka_edutools/static/icons/solid/dark_mode/brain.svg +1 -0
  110. munchboka_edutools/static/icons/solid/dark_mode/file.svg +1 -0
  111. munchboka_edutools/static/icons/solid/dark_mode/fire.svg +3 -0
  112. munchboka_edutools/static/icons/solid/dark_mode/key.svg +3 -0
  113. munchboka_edutools/static/icons/solid/dark_mode/pencil_square.svg +4 -0
  114. munchboka_edutools/static/icons/solid/dark_mode/play.svg +3 -0
  115. munchboka_edutools/static/icons/solid/dark_mode/python.svg +1 -0
  116. munchboka_edutools/static/icons/solid/dark_mode/scroll.svg +1 -0
  117. munchboka_edutools/static/icons/solid/dark_mode/stop.svg +3 -0
  118. munchboka_edutools/static/icons/solid/light_mode/academic.svg +5 -0
  119. munchboka_edutools/static/icons/solid/light_mode/backward.svg +3 -0
  120. munchboka_edutools/static/icons/solid/light_mode/book.svg +3 -0
  121. munchboka_edutools/static/icons/solid/light_mode/brain.svg +1 -0
  122. munchboka_edutools/static/icons/solid/light_mode/file.svg +1 -0
  123. munchboka_edutools/static/icons/solid/light_mode/fire.svg +3 -0
  124. munchboka_edutools/static/icons/solid/light_mode/key.svg +3 -0
  125. munchboka_edutools/static/icons/solid/light_mode/pencil_square.svg +4 -0
  126. munchboka_edutools/static/icons/solid/light_mode/play.svg +3 -0
  127. munchboka_edutools/static/icons/solid/light_mode/python.svg +1 -0
  128. munchboka_edutools/static/icons/solid/light_mode/scroll.svg +1 -0
  129. munchboka_edutools/static/icons/solid/light_mode/stop.svg +3 -0
  130. munchboka_edutools/static/icons/stickers/edit.svg +1 -0
  131. munchboka_edutools/static/icons/stickers/pencil_square.svg +3 -0
  132. munchboka_edutools/static/js/casThemeManager.js +99 -0
  133. munchboka_edutools/static/js/escapeRoom/escape-room.js +219 -0
  134. munchboka_edutools/static/js/flashcards.js +199 -0
  135. munchboka_edutools/static/js/geogebra-setup.js +6 -0
  136. munchboka_edutools/static/js/highlight-init.js +6 -0
  137. munchboka_edutools/static/js/interactiveCode/codeEditor.js +648 -0
  138. munchboka_edutools/static/js/interactiveCode/interactiveCodeSetup.js +441 -0
  139. munchboka_edutools/static/js/interactiveCode/pythonRunner.js +336 -0
  140. munchboka_edutools/static/js/interactiveCode/turtleCode.js +203 -0
  141. munchboka_edutools/static/js/interactiveCode/workerManager.js +353 -0
  142. munchboka_edutools/static/js/jeopardy.js +560 -0
  143. munchboka_edutools/static/js/pairPuzzle/draggableItem.js +64 -0
  144. munchboka_edutools/static/js/pairPuzzle/dropZone.js +119 -0
  145. munchboka_edutools/static/js/pairPuzzle/game.js +160 -0
  146. munchboka_edutools/static/js/parsons/parsonsPuzzle.js +641 -0
  147. munchboka_edutools/static/js/popup.js +85 -0
  148. munchboka_edutools/static/js/quiz.js +566 -0
  149. munchboka_edutools/static/js/skulpt/skulpt.js +35721 -0
  150. munchboka_edutools/static/js/timedQuiz/multipleChoiceQuestion.js +184 -0
  151. munchboka_edutools/static/js/timedQuiz/timedMultipleChoiceQuiz.js +244 -0
  152. munchboka_edutools/static/js/timedQuiz/utils.js +6 -0
  153. munchboka_edutools/static/js/utils.js +3 -0
  154. munchboka_edutools-0.2.3.dist-info/METADATA +109 -0
  155. munchboka_edutools-0.2.3.dist-info/RECORD +157 -0
  156. munchboka_edutools-0.2.3.dist-info/WHEEL +4 -0
  157. munchboka_edutools-0.2.3.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,353 @@
1
+ // workerManager.js
2
+
3
+ class WorkerManager {
4
+ static instance = null;
5
+
6
+ static getInstance(preloadPackages = null) {
7
+ if (!WorkerManager.instance) {
8
+ // Default PYODIDE packages (micropip is needed for custom packages)
9
+ const defaultPreloadPackages = ['matplotlib', 'numpy', 'scipy', 'sympy', 'micropip'];
10
+ const combinedPreloadPackages = Array.from(new Set(preloadPackages ? [...defaultPreloadPackages, ...preloadPackages] : defaultPreloadPackages));
11
+ WorkerManager.instance = new WorkerManager(combinedPreloadPackages);
12
+
13
+ // Trigger warm-up after initialization
14
+ setTimeout(() => {
15
+ WorkerManager.instance.warmUpPyodide().catch(err => {
16
+ console.warn("Pyodide warm-up failed:", err);
17
+ });
18
+ }, 1000); // Small delay to let the page finish loading
19
+
20
+
21
+
22
+ } else if (preloadPackages) {
23
+ // Only load packages that are NOT already loaded.
24
+ const packagesToLoad = preloadPackages.filter(pkg => !WorkerManager.instance.loadedPackages.has(pkg));
25
+ const combinedPreloadPackages = Array.from(new Set(['matplotlib', 'numpy', 'scipy', 'sympy', 'micropip', ...packagesToLoad]));
26
+ if (combinedPreloadPackages.length > 0) {
27
+ WorkerManager.instance.loadPackages(combinedPreloadPackages);
28
+ }
29
+ }
30
+ return WorkerManager.instance;
31
+ }
32
+
33
+ constructor(preloadPackages = []) { // Corrected default
34
+ if (WorkerManager.instance) {
35
+ return WorkerManager.instance;
36
+ }
37
+
38
+ this.worker = null;
39
+ this.callbacks = {};
40
+ this.preloadPackages = preloadPackages;
41
+ this.loadedPackages = new Set();
42
+ this.packageLoadPromises = {};
43
+ console.log("Preload packages in WorkerManager:", this.preloadPackages);
44
+
45
+ this.workerReadyPromise = new Promise((resolve, reject) => {
46
+ this.workerReadyResolve = resolve;
47
+ this.workerReadyReject = reject;
48
+ });
49
+
50
+ this.initWorker();
51
+
52
+ WorkerManager.instance = this;
53
+
54
+
55
+ }
56
+
57
+ initWorker() {
58
+ const workerScript = `
59
+ importScripts('https://cdn.jsdelivr.net/pyodide/v0.26.2/full/pyodide.js');
60
+
61
+ let pyodideReadyPromise = loadPyodide();
62
+ let initialGlobals = new Set();
63
+
64
+ async function resetPyodide(pyodide, initialGlobals) {
65
+ const currentGlobals = new Set(pyodide.globals.keys());
66
+ const globalsToClear = Array.from(currentGlobals).filter(x => !initialGlobals.has(x));
67
+ for (const key of globalsToClear) {
68
+ pyodide.globals.delete(key);
69
+ }
70
+ console.log("Globals cleared:", globalsToClear);
71
+ }
72
+
73
+ // Helper function to install packages via micropip
74
+ async function installPackages(pyodide, packages) {
75
+ if (packages.length > 0) {
76
+ await pyodide.loadPackage("micropip"); // Load micropip
77
+ const micropip = pyodide.pyimport("micropip");
78
+ await micropip.install(packages);
79
+ }
80
+ }
81
+
82
+ onmessage = async (event) => {
83
+ const messageId = event.data.messageId;
84
+
85
+ if (event.data.type === 'init') {
86
+ const { preloadPackages } = event.data; // Receive preloadPackages
87
+ const pyodide = await pyodideReadyPromise;
88
+ initialGlobals = new Set(pyodide.globals.keys());
89
+
90
+ // Separate Pyodide packages from PyPI packages
91
+ const pyodidePackages = preloadPackages.filter(pkg => ['matplotlib', 'numpy', 'scipy', 'sympy', 'micropip'].includes(pkg));
92
+ const pypiPackages = preloadPackages.filter(pkg => !['matplotlib', 'numpy', 'scipy', 'sympy', 'micropip'].includes(pkg));
93
+
94
+ // Load Pyodide packages
95
+ if (pyodidePackages.length > 0) {
96
+ await pyodide.loadPackage(pyodidePackages);
97
+ }
98
+
99
+ // Install PyPI packages using micropip
100
+ await installPackages(pyodide, pypiPackages);
101
+
102
+ postMessage(JSON.stringify({ type: 'initReady' })); // Send AFTER preloading
103
+ }
104
+
105
+ if (event.data.type === 'runCode') {
106
+ const { code } = event.data;
107
+ try {
108
+ const pyodide = await pyodideReadyPromise;
109
+ await resetPyodide(pyodide, initialGlobals);
110
+
111
+ // Prepare the Python code
112
+ const pyCode = \`
113
+ import sys
114
+ import json
115
+ import io
116
+ import base64
117
+ from js import postMessage
118
+ import matplotlib
119
+ matplotlib.use('Agg')
120
+ import matplotlib.pyplot as plt
121
+
122
+ class PyConsole:
123
+ def __init__(self, messageId):
124
+ self.messageId = messageId
125
+ self.buffer = ""
126
+
127
+ def write(self, msg):
128
+ self.buffer += msg
129
+ # Flush immediately for any output
130
+ self.flush()
131
+
132
+ def flush(self):
133
+ if self.buffer:
134
+ postMessage(json.dumps({'type': 'stdout', 'msg': self.buffer, 'messageId': self.messageId}))
135
+ self.buffer = ""
136
+
137
+ sys.stdout = PyConsole("\${messageId}")
138
+ sys.stderr = PyConsole("\${messageId}")
139
+
140
+ # Override plt.show()
141
+ def show_override(messageId):
142
+ buf = io.BytesIO()
143
+ plt.savefig(buf, format='png')
144
+ fig = plt.gcf()
145
+ width_in = fig.get_figwidth()
146
+ height_in = fig.get_figheight()
147
+ dpi = fig.get_dpi()
148
+ width_px = int(width_in * dpi)
149
+ height_px = int(height_in * dpi)
150
+ buf.seek(0)
151
+ image_base64 = base64.b64encode(buf.read()).decode('utf-8')
152
+ postMessage(json.dumps({
153
+ 'type': 'plot',
154
+ 'data': image_base64,
155
+ 'messageId': messageId,
156
+ 'width': width_px,
157
+ 'height': height_px
158
+ }))
159
+ plt.clf()
160
+ # Add a newline after the plot
161
+ sys.stdout.write('\\\\\\\\n')
162
+ sys.stdout.write('\\\\\\\\n')
163
+ sys.stdout.flush()
164
+
165
+ plt.show = lambda: show_override("\${messageId}")
166
+ \`;
167
+
168
+
169
+ await pyodide.runPythonAsync(pyCode);
170
+ await pyodide.runPythonAsync(code);
171
+ postMessage(JSON.stringify({ type: 'executionComplete', messageId }));
172
+ } catch (err) {
173
+ postMessage(JSON.stringify({ type: 'stderr', msg: String(err), messageId }));
174
+ }
175
+ }
176
+
177
+ if (event.data.type === 'loadPackage') {
178
+ const { packages, packageRequestId } = event.data;
179
+ try {
180
+ const pyodide = await pyodideReadyPromise;
181
+ console.log("Loading packages:", packages);
182
+
183
+ // Separate Pyodide packages from PyPI packages
184
+ const pyodidePackages = packages.filter(pkg => ['matplotlib', 'numpy', 'scipy', 'sympy', 'micropip'].includes(pkg));
185
+ const pypiPackages = packages.filter(pkg => !['matplotlib', 'numpy', 'scipy', 'sympy', 'micropip'].includes(pkg));
186
+
187
+ // Load Pyodide packages directly
188
+ if (pyodidePackages.length > 0) {
189
+ await pyodide.loadPackage(pyodidePackages);
190
+ }
191
+
192
+ // Install custom packages using micropip
193
+ await installPackages(pyodide, pypiPackages);
194
+
195
+ console.log("Packages loaded:", packages);
196
+ postMessage(JSON.stringify({ type: 'packagesLoaded', packageRequestId }));
197
+ } catch (err) {
198
+ postMessage(JSON.stringify({ type: 'stderr', msg: String(err), packageRequestId }));
199
+ }
200
+ }
201
+ };
202
+ `;
203
+
204
+ const workerBlob = new Blob([workerScript], { type: 'application/javascript' });
205
+ this.worker = new Worker(URL.createObjectURL(workerBlob));
206
+
207
+ this.worker.onmessage = this.handleMessage.bind(this);
208
+ this.worker.onerror = this.handleError.bind(this);
209
+
210
+ // Send preloadPackages with the init message!
211
+ this.worker.postMessage({ type: 'init', preloadPackages: this.preloadPackages });
212
+
213
+
214
+ this.pyodideWarmedUp = false;
215
+ }
216
+
217
+ warmUpPyodide() {
218
+ // Only warm up once
219
+ if (this.pyodideWarmedUp) {
220
+ return Promise.resolve();
221
+ }
222
+
223
+ return this.workerReadyPromise.then(() => {
224
+ console.log("Warming up Pyodide with empty execution...");
225
+ return new Promise((resolve) => {
226
+ const messageId = this.generateMessageId();
227
+ this.callbacks[messageId] = (data) => {
228
+ if (data.type === 'executionComplete') {
229
+ console.log("Pyodide warm-up complete");
230
+ this.pyodideWarmedUp = true;
231
+ resolve();
232
+ }
233
+ };
234
+ this.worker.postMessage({
235
+ type: 'runCode',
236
+ code: '# Empty script to trigger Pyodide compilation',
237
+ messageId
238
+ });
239
+ });
240
+ });
241
+ }
242
+
243
+ generateMessageId() {
244
+ return 'msg-' + Math.random().toString(36).substr(2, 9);
245
+ }
246
+
247
+ loadPackages(packages) {
248
+ const packagesToLoad = packages.filter(pkg => !this.loadedPackages.has(pkg));
249
+
250
+ if (packagesToLoad.length === 0) {
251
+ return Promise.resolve(); // All packages already loaded
252
+ }
253
+
254
+ const packageRequestId = 'pkg-' + Math.random().toString(36).substr(2, 9);
255
+
256
+ return new Promise((resolve, reject) => {
257
+ this.packageLoadPromises[packageRequestId] = { resolve, reject, packages: packagesToLoad };
258
+ this.worker.postMessage({ type: 'loadPackage', packages: packagesToLoad, packageRequestId });
259
+ });
260
+ }
261
+
262
+ runCode(code, onMessageCallback) {
263
+ const messageId = this.generateMessageId();
264
+ this.callbacks[messageId] = onMessageCallback;
265
+ this.worker.postMessage({ type: 'runCode', code, messageId });
266
+ return messageId;
267
+ }
268
+
269
+ handleMessage(event) {
270
+ let data;
271
+ try {
272
+ data = JSON.parse(event.data);
273
+ } catch (e) {
274
+ console.error("Failed to parse message from worker:", event.data);
275
+ return;
276
+ }
277
+
278
+ const messageId = data.messageId;
279
+ const packageRequestId = data.packageRequestId;
280
+
281
+ if (messageId && this.callbacks[messageId]) {
282
+ this.callbacks[messageId](data);
283
+
284
+ if (data.type === 'executionComplete') {
285
+ delete this.callbacks[messageId];
286
+ }
287
+ } else if (packageRequestId && this.packageLoadPromises[packageRequestId]) {
288
+ const packagePromise = this.packageLoadPromises[packageRequestId];
289
+ if (data.type === 'packagesLoaded') {
290
+ for (const pkg of packagePromise.packages) {
291
+ this.loadedPackages.add(pkg);
292
+ }
293
+ packagePromise.resolve();
294
+ } else if (data.type === 'stderr') {
295
+ packagePromise.reject(new Error(data.msg));
296
+ }
297
+ delete this.packageLoadPromises[packageRequestId];
298
+ } else {
299
+ if (data.type === 'initReady') {
300
+ console.log("Worker initialization message:", data.type);
301
+ this.workerReadyResolve(); // Resolve *after* preloading is done in the worker.
302
+ } else {
303
+ console.warn("Unhandled message from worker:", data);
304
+ }
305
+ }
306
+ }
307
+
308
+ handleError(error) {
309
+ console.error("Worker error:", error);
310
+ if (this.workerReadyReject) {
311
+ this.workerReadyReject(error);
312
+ }
313
+ }
314
+
315
+ // restartWorker() {
316
+ // if (this.worker) {
317
+ // this.worker.terminate();
318
+ // this.worker = null;
319
+ // }
320
+
321
+ // this.loadedPackages = new Set();
322
+ // this.workerReadyPromise = new Promise((resolve, reject) => {
323
+ // this.workerReadyResolve = resolve;
324
+ // this.workerReadyReject = reject;
325
+ // });
326
+
327
+ // this.initWorker();
328
+ // }
329
+
330
+ restartWorker() {
331
+ if (this.worker) {
332
+ this.worker.terminate();
333
+ this.worker = null;
334
+ }
335
+
336
+ this.loadedPackages = new Set();
337
+ this.pyodideWarmedUp = false; // Reset warm-up status
338
+
339
+ this.workerReadyPromise = new Promise((resolve, reject) => {
340
+ this.workerReadyResolve = resolve;
341
+ this.workerReadyReject = reject;
342
+ });
343
+
344
+ this.initWorker();
345
+
346
+ // Trigger warm-up after reinitialization
347
+ setTimeout(() => {
348
+ this.warmUpPyodide().catch(err => {
349
+ console.warn("Pyodide warm-up failed after restart:", err);
350
+ });
351
+ }, 1000); // Small delay to let the worker initialize
352
+ }
353
+ }