@jupyterlite/pyodide-kernel 0.6.0-alpha.6 → 0.6.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/kernel.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { ILogPayload } from '@jupyterlab/logconsole';
1
2
  import { Contents, KernelMessage } from '@jupyterlab/services';
2
3
  import { BaseKernel, IKernel } from '@jupyterlite/kernel';
3
4
  import { IPyodideWorkerKernel } from './tokens';
@@ -37,6 +38,7 @@ export declare class PyodideKernel extends BaseKernel implements IKernel {
37
38
  * A promise that is fulfilled when the kernel is ready.
38
39
  */
39
40
  get ready(): Promise<void>;
41
+ private _processLogMessage;
40
42
  /**
41
43
  * Process a message coming from the pyodide web worker.
42
44
  *
@@ -108,6 +110,7 @@ export declare class PyodideKernel extends BaseKernel implements IKernel {
108
110
  */
109
111
  inputReply(content: KernelMessage.IInputReplyMsg['content']): Promise<void>;
110
112
  private _contentsManager;
113
+ private _logger;
111
114
  private _contentsProcessor;
112
115
  private _worker;
113
116
  private _remoteKernel;
@@ -160,5 +163,12 @@ export declare namespace PyodideKernel {
160
163
  * identify the browsing context from which the request originated.
161
164
  */
162
165
  browsingContextId?: string;
166
+ /**
167
+ * The logger function to use for logging messages from the kernel.
168
+ */
169
+ logger?: (options: {
170
+ payload: ILogPayload;
171
+ kernelId: string;
172
+ }) => void;
163
173
  }
164
174
  }
package/lib/kernel.js CHANGED
@@ -21,6 +21,7 @@ export class PyodideKernel extends BaseKernel {
21
21
  this._worker = this.initWorker(options);
22
22
  this._remoteKernel = this.initRemote(options);
23
23
  this._contentsManager = options.contentsManager;
24
+ this._logger = options.logger || (() => { });
24
25
  }
25
26
  /**
26
27
  * Load the worker.
@@ -53,6 +54,7 @@ export class PyodideKernel extends BaseKernel {
53
54
  let remote;
54
55
  if (crossOriginIsolated) {
55
56
  remote = coincident(this._worker);
57
+ remote.processLogMessage = this._processLogMessage.bind(this);
56
58
  remote.processWorkerMessage = this._processWorkerMessage.bind(this);
57
59
  // The coincident worker uses its own filesystem API:
58
60
  remote.processDriveRequest = async (data) => {
@@ -79,17 +81,28 @@ export class PyodideKernel extends BaseKernel {
79
81
  }
80
82
  else {
81
83
  remote = wrap(this._worker);
82
- // we use the normal postMessage mechanism
84
+ // we use the normal postMessage mechanism in the case of comlink
83
85
  this._worker.addEventListener('message', (ev) => {
84
- var _a;
86
+ var _a, _b;
85
87
  if (typeof ((_a = ev === null || ev === void 0 ? void 0 : ev.data) === null || _a === void 0 ? void 0 : _a._kernelMessage) !== 'undefined') {
86
88
  // only process non comlink messages
87
89
  this._processWorkerMessage(ev.data._kernelMessage);
88
90
  }
91
+ else if (typeof ((_b = ev === null || ev === void 0 ? void 0 : ev.data) === null || _b === void 0 ? void 0 : _b._logMessage) !== 'undefined') {
92
+ this._processLogMessage(ev.data._logMessage);
93
+ }
89
94
  });
90
95
  }
91
96
  const remoteOptions = this.initRemoteOptions(options);
92
- remote.initialize(remoteOptions).then(this._ready.resolve.bind(this._ready));
97
+ remote
98
+ .initialize(remoteOptions)
99
+ .then(this._ready.resolve.bind(this._ready))
100
+ .catch((err) => {
101
+ this._logger({
102
+ payload: { type: 'text', level: 'critical', data: err.message },
103
+ kernelId: this.id,
104
+ });
105
+ });
93
106
  return remote;
94
107
  }
95
108
  initRemoteOptions(options) {
@@ -109,6 +122,7 @@ export class PyodideKernel extends BaseKernel {
109
122
  mountDrive: options.mountDrive,
110
123
  loadPyodideOptions: options.loadPyodideOptions || {},
111
124
  browsingContextId: options.browsingContextId,
125
+ kernelId: this.id,
112
126
  };
113
127
  }
114
128
  /**
@@ -128,6 +142,9 @@ export class PyodideKernel extends BaseKernel {
128
142
  get ready() {
129
143
  return this._ready.promise;
130
144
  }
145
+ _processLogMessage(payload) {
146
+ this._logger({ payload, kernelId: this.id });
147
+ }
131
148
  /**
132
149
  * Process a message coming from the pyodide web worker.
133
150
  *
package/lib/tokens.d.ts CHANGED
@@ -20,21 +20,35 @@ export interface IPyodideWorkerKernel extends IWorkerKernel {
20
20
  * @param data
21
21
  */
22
22
  processDriveRequest<T extends TDriveMethod>(data: TDriveRequest<T>): TDriveResponse<T>;
23
+ }
24
+ /**
25
+ * An interface for Pyodide workers that use comlink.
26
+ */
27
+ export interface IComlinkPyodideKernel extends IPyodideWorkerKernel {
23
28
  /**
24
- * Process worker message
25
- * @param msg
29
+ * Register a callback for handling messages from the worker.
26
30
  */
27
- processWorkerMessage(msg: any): void;
31
+ registerWorkerMessageCallback(callback: (msg: any) => void): void;
28
32
  /**
29
- * Register a callback for handling messages from the worker.
33
+ * Register a callback for handling log messages from the worker.
30
34
  */
31
- registerCallback(callback: (msg: any) => void): void;
35
+ registerLogMessageCallback(callback: (msg: any) => void): void;
32
36
  }
33
37
  /**
34
38
  * An interface for Coincident Pyodide workers that include extra SharedArrayBuffer
35
39
  * functionality.
36
40
  */
37
41
  export interface ICoincidentPyodideWorkerKernel extends IPyodideWorkerKernel {
42
+ /**
43
+ * Process a log message
44
+ * @param msg
45
+ */
46
+ processLogMessage(msg: any): void;
47
+ /**
48
+ * Process worker message
49
+ * @param msg
50
+ */
51
+ processWorkerMessage(msg: any): void;
38
52
  /**
39
53
  * Process stdin request, blocking until the reply is received.
40
54
  * This is sync for the web worker, async for the UI thread.
@@ -99,5 +113,9 @@ export declare namespace IPyodideWorkerKernel {
99
113
  lockFileURL: string;
100
114
  packages: string[];
101
115
  };
116
+ /**
117
+ * The kernel id.
118
+ */
119
+ kernelId?: string;
102
120
  }
103
121
  }
package/lib/worker.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type Pyodide from 'pyodide';
2
- import type { DriveFS } from '@jupyterlite/contents';
2
+ import type { ILogPayload } from '@jupyterlab/logconsole';
3
3
  import { KernelMessage } from '@jupyterlab/services';
4
+ import type { DriveFS } from '@jupyterlite/contents';
4
5
  import type { IPyodideWorkerKernel } from './tokens';
5
6
  export declare abstract class PyodideRemoteKernel {
6
7
  constructor();
@@ -29,9 +30,16 @@ export declare abstract class PyodideRemoteKernel {
29
30
  formatResult(res: any): any;
30
31
  /**
31
32
  * Register the callback function to send messages from the worker back to the main thread.
33
+ *
34
+ * @param callback the callback to register
35
+ */
36
+ registerWorkerMessageCallback(callback: (msg: any) => void): void;
37
+ /**
38
+ * Register the callback function to log messages from the worker back to the main thread.
39
+ *
32
40
  * @param callback the callback to register
33
41
  */
34
- registerCallback(callback: (msg: any) => void): void;
42
+ registerLogMessageCallback(callback: (msg: any) => void): void;
35
43
  /**
36
44
  * Makes sure pyodide is ready before continuing, and cache the parent message.
37
45
  */
@@ -136,4 +144,5 @@ export declare abstract class PyodideRemoteKernel {
136
144
  protected _stderr_stream: any;
137
145
  protected _driveFS: DriveFS | null;
138
146
  protected _sendWorkerMessage: (msg: any) => void;
147
+ protected _logMessage: (msg: ILogPayload) => void;
139
148
  }
package/lib/worker.js CHANGED
@@ -13,6 +13,7 @@ export class PyodideRemoteKernel {
13
13
  this._driveName = '';
14
14
  this._driveFS = null;
15
15
  this._sendWorkerMessage = () => { };
16
+ this._logMessage = () => { };
16
17
  this._initialized = new Promise((resolve, reject) => {
17
18
  this._initializer = { resolve, reject };
18
19
  });
@@ -56,6 +57,44 @@ export class PyodideRemoteKernel {
56
57
  indexURL: indexUrl,
57
58
  ...options.loadPyodideOptions,
58
59
  });
60
+ // @ts-expect-error: pyodide._api is private
61
+ this._pyodide._api.on_fatal = async (e) => {
62
+ let error = '';
63
+ if (e.name === 'Exit') {
64
+ error = 'Pyodide has exited and can no longer be used.';
65
+ }
66
+ else {
67
+ error = `Pyodide has suffered a fatal error. Please report this to the Pyodide maintainers.
68
+ The cause of the error was: ${e.name}
69
+ ${e.message}
70
+ Stack trace:
71
+ ${e.stack}`;
72
+ }
73
+ this._logMessage({
74
+ type: 'text',
75
+ level: 'critical',
76
+ data: error,
77
+ });
78
+ };
79
+ const log = (msg) => {
80
+ console.log(msg);
81
+ this._logMessage({ type: 'text', level: 'info', data: msg });
82
+ };
83
+ const err = (msg) => {
84
+ console.error(msg);
85
+ this._logMessage({ type: 'text', level: 'critical', data: msg });
86
+ };
87
+ // Workaround for being able to get information about packages being loaded by Pyodide
88
+ // See discussion in https://github.com/pyodide/pyodide/discussions/5512
89
+ const origLoadPackage = this._pyodide.loadPackage;
90
+ this._pyodide.loadPackage = (pkgs, options) => origLoadPackage(pkgs, {
91
+ // Use custom callbacks to surface messages from Pyodide
92
+ messageCallback: (msg) => log(msg),
93
+ errorCallback: (msg) => {
94
+ err(msg);
95
+ },
96
+ ...options,
97
+ });
59
98
  }
60
99
  async initPackageManager(options) {
61
100
  if (!this._options) {
@@ -168,11 +207,20 @@ export class PyodideRemoteKernel {
168
207
  }
169
208
  /**
170
209
  * Register the callback function to send messages from the worker back to the main thread.
210
+ *
171
211
  * @param callback the callback to register
172
212
  */
173
- registerCallback(callback) {
213
+ registerWorkerMessageCallback(callback) {
174
214
  this._sendWorkerMessage = callback;
175
215
  }
216
+ /**
217
+ * Register the callback function to log messages from the worker back to the main thread.
218
+ *
219
+ * @param callback the callback to register
220
+ */
221
+ registerLogMessageCallback(callback) {
222
+ this._logMessage = callback;
223
+ }
176
224
  /**
177
225
  * Makes sure pyodide is ready before continuing, and cache the parent message.
178
226
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyterlite/pyodide-kernel",
3
- "version": "0.6.0-alpha.6",
3
+ "version": "0.6.0-beta.1",
4
4
  "description": "JupyterLite - Pyodide Kernel",
5
5
  "homepage": "https://github.com/jupyterlite/pyodide-kernel",
6
6
  "bugs": {
@@ -51,8 +51,9 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@jupyterlab/coreutils": "^6.4.0",
54
- "@jupyterlite/contents": "^0.6.0-alpha.8",
55
- "@jupyterlite/kernel": "^0.6.0-alpha.8",
54
+ "@jupyterlab/logconsole": "^4.4.0",
55
+ "@jupyterlite/contents": "^0.6.0-beta.0",
56
+ "@jupyterlite/kernel": "^0.6.0-beta.0",
56
57
  "coincident": "^1.2.3",
57
58
  "comlink": "^4.4.2"
58
59
  },
@@ -68,8 +69,8 @@
68
69
  },
69
70
  "pyodide-kernel": {
70
71
  "packages": {
71
- "py/pyodide-kernel": "0.6.0a6",
72
- "py/piplite": "0.6.0a6",
72
+ "py/pyodide-kernel": "0.6.0b1",
73
+ "py/piplite": "0.6.0b1",
73
74
  "py/ipykernel": "6.9.2",
74
75
  "py/widgetsnbextension3/widgetsnbextension": "3.6.999",
75
76
  "py/widgetsnbextension4/widgetsnbextension": "4.0.999"
package/pypi/all.json CHANGED
@@ -5,19 +5,19 @@
5
5
  {
6
6
  "comment_text": "",
7
7
  "digests": {
8
- "md5": "c4a1c70e9d300eaa77da2573911088c8",
9
- "sha256": "17c7aa29892f2724ee3bea223e2565a5a492c38953db901e1b528582670bd510"
8
+ "md5": "8b1a087058bce264871af947d2696973",
9
+ "sha256": "a0ada63eb25aa2a5cd7e653e4e446052084279834537c5ea725f5c6368a26559"
10
10
  },
11
11
  "downloads": -1,
12
12
  "filename": "ipykernel-6.9.2-py3-none-any.whl",
13
13
  "has_sig": false,
14
- "md5_digest": "c4a1c70e9d300eaa77da2573911088c8",
14
+ "md5_digest": "8b1a087058bce264871af947d2696973",
15
15
  "packagetype": "bdist_wheel",
16
16
  "python_version": "py3",
17
17
  "requires_python": ">=3.10",
18
18
  "size": 2731,
19
- "upload_time": "2025-05-07T18:41:19.083517Z",
20
- "upload_time_iso_8601": "2025-05-07T18:41:19.083517Z",
19
+ "upload_time": "2025-05-15T06:32:07.843518Z",
20
+ "upload_time_iso_8601": "2025-05-15T06:32:07.843518Z",
21
21
  "url": "./ipykernel-6.9.2-py3-none-any.whl",
22
22
  "yanked": false,
23
23
  "yanked_reason": null
@@ -27,24 +27,24 @@
27
27
  },
28
28
  "piplite": {
29
29
  "releases": {
30
- "0.6.0a6": [
30
+ "0.6.0b1": [
31
31
  {
32
32
  "comment_text": "",
33
33
  "digests": {
34
- "md5": "d09f7d8ce9121e2befca9bae84cd54b1",
35
- "sha256": "77a42f2dbc285e0609265f5255007e2d978127eeaf7b0b2898547980fb347057"
34
+ "md5": "70da30049b0e2706d7ad9511dbc51a8f",
35
+ "sha256": "7927de23509161f19042640b01459992156ccebaaca7fb8e009942723d25ebf4"
36
36
  },
37
37
  "downloads": -1,
38
- "filename": "piplite-0.6.0a6-py3-none-any.whl",
38
+ "filename": "piplite-0.6.0b1-py3-none-any.whl",
39
39
  "has_sig": false,
40
- "md5_digest": "d09f7d8ce9121e2befca9bae84cd54b1",
40
+ "md5_digest": "70da30049b0e2706d7ad9511dbc51a8f",
41
41
  "packagetype": "bdist_wheel",
42
42
  "python_version": "py3",
43
43
  "requires_python": "<3.12,>=3.11",
44
- "size": 7254,
45
- "upload_time": "2025-05-07T18:41:19.082517Z",
46
- "upload_time_iso_8601": "2025-05-07T18:41:19.082517Z",
47
- "url": "./piplite-0.6.0a6-py3-none-any.whl",
44
+ "size": 7252,
45
+ "upload_time": "2025-05-15T06:32:07.843518Z",
46
+ "upload_time_iso_8601": "2025-05-15T06:32:07.843518Z",
47
+ "url": "./piplite-0.6.0b1-py3-none-any.whl",
48
48
  "yanked": false,
49
49
  "yanked_reason": null
50
50
  }
@@ -53,24 +53,24 @@
53
53
  },
54
54
  "pyodide-kernel": {
55
55
  "releases": {
56
- "0.6.0a6": [
56
+ "0.6.0b1": [
57
57
  {
58
58
  "comment_text": "",
59
59
  "digests": {
60
- "md5": "b59091b6a2b8c754f1967c95aa015ede",
61
- "sha256": "014b4d106f6428930c0c582bd01355133d4a1b5ac8cdb664b9ef667e999b8d90"
60
+ "md5": "d2639172c0562301f23f5602f90b6156",
61
+ "sha256": "a90bad0524cc2e6a23d12b6ebc0884652058a4cbb11eb404503b3a2336d81f38"
62
62
  },
63
63
  "downloads": -1,
64
- "filename": "pyodide_kernel-0.6.0a6-py3-none-any.whl",
64
+ "filename": "pyodide_kernel-0.6.0b1-py3-none-any.whl",
65
65
  "has_sig": false,
66
- "md5_digest": "b59091b6a2b8c754f1967c95aa015ede",
66
+ "md5_digest": "d2639172c0562301f23f5602f90b6156",
67
67
  "packagetype": "bdist_wheel",
68
68
  "python_version": "py3",
69
69
  "requires_python": "<3.12,>=3.11",
70
- "size": 11411,
71
- "upload_time": "2025-05-07T18:41:19.082517Z",
72
- "upload_time_iso_8601": "2025-05-07T18:41:19.082517Z",
73
- "url": "./pyodide_kernel-0.6.0a6-py3-none-any.whl",
70
+ "size": 11412,
71
+ "upload_time": "2025-05-15T06:32:07.843518Z",
72
+ "upload_time_iso_8601": "2025-05-15T06:32:07.843518Z",
73
+ "url": "./pyodide_kernel-0.6.0b1-py3-none-any.whl",
74
74
  "yanked": false,
75
75
  "yanked_reason": null
76
76
  }
@@ -83,19 +83,19 @@
83
83
  {
84
84
  "comment_text": "",
85
85
  "digests": {
86
- "md5": "c60448da43a2c5fea845219309483d09",
87
- "sha256": "901e64c7ae4560bd8f77ba92ee7011be85b06eff743b7d6c1fc45718601dce9d"
86
+ "md5": "7f79c99fe7822c09a432aed4ebf228ed",
87
+ "sha256": "47f41f03e2aa5c95ceb59385163003a1eab8fe00534cdabf9ef36c1bfe38ef6c"
88
88
  },
89
89
  "downloads": -1,
90
90
  "filename": "widgetsnbextension-3.6.999-py3-none-any.whl",
91
91
  "has_sig": false,
92
- "md5_digest": "c60448da43a2c5fea845219309483d09",
92
+ "md5_digest": "7f79c99fe7822c09a432aed4ebf228ed",
93
93
  "packagetype": "bdist_wheel",
94
94
  "python_version": "py3",
95
95
  "requires_python": "<3.12,>=3.11",
96
96
  "size": 2369,
97
- "upload_time": "2025-05-07T18:41:19.083517Z",
98
- "upload_time_iso_8601": "2025-05-07T18:41:19.083517Z",
97
+ "upload_time": "2025-05-15T06:32:07.843518Z",
98
+ "upload_time_iso_8601": "2025-05-15T06:32:07.843518Z",
99
99
  "url": "./widgetsnbextension-3.6.999-py3-none-any.whl",
100
100
  "yanked": false,
101
101
  "yanked_reason": null
@@ -105,19 +105,19 @@
105
105
  {
106
106
  "comment_text": "",
107
107
  "digests": {
108
- "md5": "ef8e80f38311771d1cd24c206ce62c59",
109
- "sha256": "343b63612da12c37086ae06885b8202e814a5d35154dcece93083f39517e3e39"
108
+ "md5": "b12eee750ed4c5dddcdb10774d8dbe1a",
109
+ "sha256": "8f57f68f7e6c2ae604b84baa16aaf8c57d0bf45c0f42f8b303a112590f12521a"
110
110
  },
111
111
  "downloads": -1,
112
112
  "filename": "widgetsnbextension-4.0.999-py3-none-any.whl",
113
113
  "has_sig": false,
114
- "md5_digest": "ef8e80f38311771d1cd24c206ce62c59",
114
+ "md5_digest": "b12eee750ed4c5dddcdb10774d8dbe1a",
115
115
  "packagetype": "bdist_wheel",
116
116
  "python_version": "py3",
117
117
  "requires_python": "<3.12,>=3.11",
118
118
  "size": 2370,
119
- "upload_time": "2025-05-07T18:41:19.083517Z",
120
- "upload_time_iso_8601": "2025-05-07T18:41:19.083517Z",
119
+ "upload_time": "2025-05-15T06:32:07.843518Z",
120
+ "upload_time_iso_8601": "2025-05-15T06:32:07.843518Z",
121
121
  "url": "./widgetsnbextension-4.0.999-py3-none-any.whl",
122
122
  "yanked": false,
123
123
  "yanked_reason": null
index e76f09d..ee13253 100644
Binary file