forked from denoland/vscode_deno
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improved Deno.jupyter support on repl kernel
- Loading branch information
Showing
7 changed files
with
143 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
client/src/notebook-controllers/repl-controller/boot/boot.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import { encodeBase64 } from "jsr:@std/encoding/base64"; | ||
|
||
|
||
globalThis.Deno.jupyter = (function () { | ||
|
||
const $display = Symbol.for("Jupyter.display"); | ||
|
||
const _displayFunc = async (obj: unknown, options: Deno.jupyter.DisplayOptions = { raw: true }): Promise<void> => { | ||
let data = (obj as any)[$display] ? (await ((obj as any)[$display])()) : obj; | ||
if (!options.raw) { | ||
data = JSON.stringify(data); | ||
} | ||
console.log(`##DISPLAYDATA#2d522e5a-4a6c-4aae-b20c-91c5189948d9##${JSON.stringify(data)}`); | ||
} | ||
|
||
function makeDisplayable(obj: unknown): Deno.jupyter.Displayable { | ||
return { [$display]: () => obj } as any; | ||
} | ||
|
||
function createTaggedTemplateDisplayable(mediatype: string) { | ||
return (strings: TemplateStringsArray, ...values: unknown[]) => { | ||
const payload = strings.reduce( | ||
(acc, string, i) => | ||
acc + string + (values[i] !== undefined ? values[i] : ""), | ||
"", | ||
); | ||
return makeDisplayable({ [mediatype]: payload }); | ||
}; | ||
} | ||
|
||
|
||
function isJpg(obj: any) { | ||
// Check if obj is a Uint8Array | ||
if (!(obj instanceof Uint8Array)) { | ||
return false; | ||
} | ||
|
||
// JPG files start with the magic bytes FF D8 | ||
if (obj.length < 2 || obj[0] !== 0xFF || obj[1] !== 0xD8) { | ||
return false; | ||
} | ||
|
||
// JPG files end with the magic bytes FF D9 | ||
if ( | ||
obj.length < 2 || obj[obj.length - 2] !== 0xFF || | ||
obj[obj.length - 1] !== 0xD9 | ||
) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
function isPng(obj: any) { | ||
// Check if obj is a Uint8Array | ||
if (!(obj instanceof Uint8Array)) { | ||
return false; | ||
} | ||
|
||
// PNG files start with a specific 8-byte signature | ||
const pngSignature = [137, 80, 78, 71, 13, 10, 26, 10]; | ||
|
||
// Check if the array is at least as long as the signature | ||
if (obj.length < pngSignature.length) { | ||
return false; | ||
} | ||
|
||
// Check each byte of the signature | ||
for (let i = 0; i < pngSignature.length; i++) { | ||
if (obj[i] !== pngSignature[i]) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
|
||
|
||
const _mdFunc = createTaggedTemplateDisplayable("text/markdown"); | ||
const _svgFunc = createTaggedTemplateDisplayable("image/svg+xml"); | ||
const _htmlFunc = createTaggedTemplateDisplayable("text/html"); | ||
const _imageFunc = (obj: any) => { | ||
if (typeof obj === "string") { | ||
try { | ||
obj = Deno.readFileSync(obj); | ||
} catch { | ||
// pass | ||
} | ||
} | ||
|
||
if (isJpg(obj)) { | ||
return makeDisplayable({ "image/jpeg": encodeBase64(obj) }); | ||
} | ||
|
||
if (isPng(obj)) { | ||
return makeDisplayable({ "image/png": encodeBase64(obj) }); | ||
} | ||
|
||
throw new TypeError( | ||
"Object is not a valid image or a path to an image. `Deno.jupyter.image` supports displaying JPG or PNG images.", | ||
); | ||
} | ||
|
||
return { | ||
$display: $display as any as (typeof Deno.jupyter.$display), | ||
display: _displayFunc, | ||
md: _mdFunc, | ||
svg: _svgFunc, | ||
html: _htmlFunc, | ||
image: _imageFunc | ||
} | ||
|
||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
821bdd2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what this mean?
821bdd2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wrote an experimental controller based on the deno repl instead of the deno jupyter kernel, to play a bit with it.
I've also slightly rewritten the main controller and fixed the reference to zeromq in the build process.
821bdd2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If successful, we can even do away with Deno.jupyter.display? nice~
821bdd2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about that. The REPL does not automatically evaluate the [Deno.jupyter.$display] method on objects like the kernel does.