@basthon/kernel-base 0.64.3 → 0.64.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/lib/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "0.64.3";
1
+ export declare const VERSION = "0.64.4";
package/lib/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "0.64.3";
1
+ export const VERSION = "0.64.4";
@@ -46,7 +46,7 @@ export declare class KernelMainBase<Type extends KernelWorkerBase> extends Kerne
46
46
  data: any;
47
47
  type: string;
48
48
  content: any;
49
- }): void;
49
+ }): Promise<void>;
50
50
  evalAsync(code: string, outCallback: (_: string) => void, errCallback: (_: string) => void, data?: any): Promise<any>;
51
51
  /**
52
52
  * Put a file on the local (emulated) filesystem.
@@ -128,7 +128,7 @@ export class KernelMainBase extends KernelBase {
128
128
  /**
129
129
  * Process messages from worker (if any).
130
130
  */
131
- processWorkerMessage(msg) {
131
+ async processWorkerMessage(msg) {
132
132
  switch (msg.type) {
133
133
  case "stream":
134
134
  const { stream, text } = msg.content;
@@ -142,18 +142,27 @@ export class KernelMainBase extends KernelBase {
142
142
  this.download(content, filename);
143
143
  break;
144
144
  case "display":
145
+ if (msg.data?.display_type === "dom-node") {
146
+ // we should be in legacy mode here
147
+ if (!this.isLegacy())
148
+ throw new Error("internal error");
149
+ const id = msg.data?.content;
150
+ //@ts-ignore
151
+ msg.data.content = await self.basthon?.popDOMNode(id);
152
+ }
145
153
  this.dispatchEvent("eval.display", msg.data);
146
154
  break;
155
+ case "clear_output":
156
+ this.dispatchEvent("eval.clear-output", msg.data);
157
+ break;
147
158
  case "input":
148
159
  const { prompt, password, data } = msg.content;
149
- (async () => {
150
- const res = (await this.inputAsync(prompt, password, data));
151
- if (this._sab == null)
152
- return;
153
- const encodedRes = new TextEncoder().encode(res);
154
- new Uint8Array(this._sab).set(encodedRes.subarray(0, this._sab.byteLength));
155
- Atomics.notify(new Int32Array(this._sab), 0, 1);
156
- })();
160
+ const res = (await this.inputAsync(prompt, password, data));
161
+ if (this._sab == null)
162
+ return;
163
+ const encodedRes = new TextEncoder().encode(res);
164
+ new Uint8Array(this._sab).set(encodedRes.subarray(0, this._sab.byteLength));
165
+ Atomics.notify(new Int32Array(this._sab), 0, 1);
157
166
  break;
158
167
  default: // ignoring (probably a comlink message)
159
168
  }
@@ -22,6 +22,7 @@ declare class KernelWorkerBase {
22
22
  protected __eval_data__: any;
23
23
  protected postMessage?: InstanceType<typeof MessagePort>["postMessage"];
24
24
  private _sab?;
25
+ private _domNodeBus?;
25
26
  constructor(options?: any);
26
27
  /**
27
28
  * Is this a legacy worker? i.e. not runing in a worker.
@@ -69,6 +70,15 @@ declare class KernelWorkerBase {
69
70
  * Display an element like a canvas, ... in the frontend.
70
71
  */
71
72
  display(element: any): void;
73
+ /**
74
+ * Clear the current output.
75
+ */
76
+ clearOutput(wait: boolean): void;
77
+ /**
78
+ * Pop a DOM node from domNodeBus
79
+ * (used to transfer HTMLElement from main thread to worker thread in legacy mode)
80
+ */
81
+ popDOMNode(id: number): any;
72
82
  /**
73
83
  * Evaluate code and return an object with mime type keys and string value.
74
84
  * To be overloaded.
@@ -1,6 +1,7 @@
1
1
  import { PromiseDelegate } from "promise-delegate";
2
2
  import { NotImplementedError, mockFetch } from "../commons";
3
3
  import { wrap } from "comlink";
4
+ import { DOMNodeBus } from "./worker-utils";
4
5
  class KernelWorkerBase {
5
6
  constructor(options) {
6
7
  this._ready = new PromiseDelegate();
@@ -31,6 +32,10 @@ class KernelWorkerBase {
31
32
  if (self._prompt == null)
32
33
  self._prompt = globalThis.prompt;
33
34
  globalThis.prompt = (p) => this.input(p);
35
+ // DOM node bus in legacy mode
36
+ // (to transfer elements from worker to main thread, they are the same!)
37
+ if (this.isLegacy())
38
+ this._domNodeBus = new DOMNodeBus();
34
39
  }
35
40
  /**
36
41
  * Is this a legacy worker? i.e. not runing in a worker.
@@ -137,11 +142,33 @@ class KernelWorkerBase {
137
142
  .then((blob) => this.displayBlob(blob, data));
138
143
  }
139
144
  else {
140
- data["display_type"] = "multiple";
141
- data["content"] = element;
145
+ // in legacy mode, send HTML elements via DOM node bus
146
+ if (this.isLegacy() && element instanceof HTMLElement) {
147
+ data["display_type"] = "dom-node";
148
+ data["content"] = this._domNodeBus?.push?.(element);
149
+ }
150
+ else {
151
+ data["display_type"] = "multiple";
152
+ data["content"] = element;
153
+ }
142
154
  this.postMessage?.({ data, type: "display" });
143
155
  }
144
156
  }
157
+ /**
158
+ * Clear the current output.
159
+ */
160
+ clearOutput(wait) {
161
+ const data = this.clone(this.__eval_data__);
162
+ data["content"] = { wait };
163
+ this.postMessage?.({ data, type: "clear_output" });
164
+ }
165
+ /**
166
+ * Pop a DOM node from domNodeBus
167
+ * (used to transfer HTMLElement from main thread to worker thread in legacy mode)
168
+ */
169
+ popDOMNode(id) {
170
+ return this._domNodeBus?.pop(id);
171
+ }
145
172
  /**
146
173
  * Evaluate code and return an object with mime type keys and string value.
147
174
  * To be overloaded.
@@ -4,3 +4,17 @@ declare global {
4
4
  }
5
5
  }
6
6
  export declare const expose: (kwc: any) => void;
7
+ /**
8
+ * DOM node exchanger (Bus) to bypass stringifying
9
+ * messages between frontend and kernel that prevents DOMNode sharing.
10
+ */
11
+ export declare class DOMNodeBus extends Map<number, any> {
12
+ /**
13
+ * Push an object to the bus and get back an id to later pop it.
14
+ */
15
+ push(obj: any): number;
16
+ /**
17
+ * Remove an object from the bus from its id.
18
+ */
19
+ pop(id: number): any;
20
+ }
@@ -19,3 +19,28 @@ export const expose = (kwc) => {
19
19
  self._commPort = undefined; // no more needed
20
20
  }
21
21
  };
22
+ /**
23
+ * DOM node exchanger (Bus) to bypass stringifying
24
+ * messages between frontend and kernel that prevents DOMNode sharing.
25
+ */
26
+ export class DOMNodeBus extends Map {
27
+ /**
28
+ * Push an object to the bus and get back an id to later pop it.
29
+ */
30
+ push(obj) {
31
+ let id = 0;
32
+ for (; id < this.size; id++)
33
+ if (!this.has(id))
34
+ break;
35
+ this.set(id, obj);
36
+ return id;
37
+ }
38
+ /**
39
+ * Remove an object from the bus from its id.
40
+ */
41
+ pop(id) {
42
+ const res = this.get(id);
43
+ this.delete(id);
44
+ return res;
45
+ }
46
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basthon/kernel-base",
3
- "version": "0.64.3",
3
+ "version": "0.64.4",
4
4
  "description": "Basthon - Base Kernel",
5
5
  "homepage": "https://basthon.fr",
6
6
  "bugs": {
@@ -44,5 +44,5 @@
44
44
  "publishConfig": {
45
45
  "access": "public"
46
46
  },
47
- "gitHead": "ef45edbf7dcdde8400ffc6ec89cd2d513b8776ee"
47
+ "gitHead": "ac29889e2ccaf40fa7a85d835f7e6d0d1836dad0"
48
48
  }