Skip to content

Commit

Permalink
Merge pull request #52 from stateful/wasm-interface-and-praser
Browse files Browse the repository at this point in the history
New wasm interface
  • Loading branch information
sourishkrout authored Nov 11, 2022
2 parents 0629512 + 83f7559 commit 658ea85
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 46 deletions.
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ jobs:
pat: ${{ secrets.OPEN_VSX_TOKEN }}
extensionFile: ./runme-${{ env.RELEASE_VERSION }}.vsix
- name: Push Tags
continue-on-error: true
run: |
git log -1 --stat
git push origin main --tags
Expand Down
12 changes: 8 additions & 4 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This markdown file contains some custom examples to test the execution within a

## Shell Executions

```sh
```
echo "Hello World!"
```
## More Shell
Expand Down Expand Up @@ -45,7 +45,10 @@ node ./scripts/stdin.js
You can also run TypeScript or JavaScript:

```js
document.body.innerHTML += 'script attached!'
function attach() {
document.body.innerHTML += 'script attached!'
}
attach()
```

## Environment Variables
Expand All @@ -64,7 +67,7 @@ echo "DENO_ACCESS_TOKEN: $DENO_ACCESS_TOKEN"

Supports multiple lines where the export is just somewhere in between:

```sh
```
echo "Auth token for service foo"
export SERVICE_FOO_TOKEN=foobar
echo "Auth token for service bar"
Expand Down Expand Up @@ -99,7 +102,7 @@ echo "LICENSE: $LICENSE"

Support multiline exports:

```
```sh
export PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA04up8hoqzS1+
...
Expand All @@ -126,5 +129,6 @@ openssl rand -base64 32
These are shown as simple markdown, e.g:

```py { readonly=true }
def hello():
print("Hello World")
```
65 changes: 37 additions & 28 deletions src/extension/notebook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
NotebookSerializer, ExtensionContext, Uri, workspace, NotebookData, NotebookCellData, NotebookCellKind
} from 'vscode'

import type { ParsedDocument } from '../types'
import type { WasmLib } from '../types'

import executor from './executors'
import Languages from './languages'
Expand All @@ -25,7 +25,7 @@ export class Serializer implements NotebookSerializer {
this.ready = this.#initWasm()
}

async #initWasm () {
async #initWasm() {
const go = new globalThis.Go()
const wasmUri = Uri.joinPath(this.context.extensionUri, 'wasm', 'runme.wasm')
const wasmFile = await workspace.fs.readFile(wasmUri)
Expand All @@ -42,9 +42,12 @@ export class Serializer implements NotebookSerializer {
const err = await this.ready

const md = content.toString()
const doc = globalThis.GetDocument(md) as ParsedDocument
const { Runme } = globalThis as WasmLib.Runme

if (!doc || err) {
Runme.initialize(md)
const res = Runme.getCells() as WasmLib.Cells

if (!res || err) {
return this.#printCell(
'⚠️ __Error__: document could not be loaded' +
(err ? `\n<small>${err.message}</small>` : '') +
Expand All @@ -53,70 +56,70 @@ export class Serializer implements NotebookSerializer {
)
}

let snippets = doc.document ?? []
if (snippets.length === 0) {
let parsedCells = res.cells ?? []
if (parsedCells.length === 0) {
return this.#printCell('⚠️ __Error__: no cells found!')
}

try {
snippets = await Promise.all(snippets.map(s => {
const content = s.content
if (content && s.language === undefined) {
return this.languages.guess(content, PLATFORM_OS).then(guessed => {
s.language = guessed
return s
parsedCells = await Promise.all(parsedCells.map(elem => {
if (elem.type === 'code' && elem.source && !elem.executable) {
const norm = Serializer.normalize(elem.source)
return this.languages.guess(norm, PLATFORM_OS).then(guessed => {
elem.executable = guessed
return elem
})
}
return Promise.resolve(s)
return Promise.resolve(elem)
}))
} catch (err: any) {
console.error(`Error guessing snippet languages: ${err}`)
}

const cells = snippets.reduce((acc, s, i) => {
const cells = parsedCells.reduce((acc, elem, i) => {
/**
* code block description
*/
if (s.markdown) {
if (elem.type === 'markdown') {
const cell = new NotebookCellData(
NotebookCellKind.Markup,
s.markdown,
elem.source,
'markdown'
)
cell.metadata = { id: i }
acc.push(cell)
return acc
}

const isSupported = Object.keys(executor).includes(s.language || '')
if (s.lines && isSupported) {
const lines = s.lines.join('\n')
const language = normalizeLanguage(s.language)
const isSupported = Object.keys(executor).includes(elem.executable ?? '')
if (elem.lines && isSupported && elem.editable) {
const lines = elem.lines.join('\n')
const language = normalizeLanguage(elem.executable)
const cell = new NotebookCellData(
NotebookCellKind.Code,
/**
* for JS content we want to keep indentation
*/
LANGUAGES_WITH_INDENTATION.includes(language || '')
? (s.content || '').trim()
LANGUAGES_WITH_INDENTATION.includes(language || '')
? (Serializer.normalize(elem.source || '')).trim()
: lines.trim(),
/**
* with custom vercel execution
* lines.startsWith('vercel ') ? 'vercel' : s.executable
*/
language || DEFAULT_LANG_ID
)
const attributes = s.attributes
const cliName = s.name
const attributes = elem.attributes
const cliName = elem.name
cell.metadata = { id: i, source: lines, attributes, cliName }
/**
* code block
*/
acc.push(cell)
} else if (s.language) {
const mdContent = s.content ?? (s.lines || []).join('\n').trim()
} else if (elem.source) {
const cell = new NotebookCellData(
NotebookCellKind.Markup,
`\`\`\`${s.language}\n${mdContent}\n\`\`\``,
elem.source,
'markdown'
)
cell.metadata = { id: i }
Expand All @@ -127,6 +130,12 @@ export class Serializer implements NotebookSerializer {
return new NotebookData(cells)
}

public static normalize(source: string): string {
const lines = source.split('\n')
const normed = lines.filter(l => !(l.trim().startsWith('```') || l.trim().endsWith('```')))
return normed.join('\n')
}

public async serializeNotebook(
// data: NotebookData,
// token: CancellationToken
Expand Down Expand Up @@ -175,7 +184,7 @@ export class Serializer implements NotebookSerializer {
// return Promise.resolve(Buffer.from(this.fileContent))
}

#printCell (content: string, languageId = 'markdown') {
#printCell(content: string, languageId = 'markdown') {
return new NotebookData([
new NotebookCellData(NotebookCellKind.Markup, content, languageId)
])
Expand Down
44 changes: 30 additions & 14 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
import { OutputType, ClientMessages } from './constants'

export interface ParsedReadmeEntry {
name?: string
content?: string
description?: string
markdown?: string
language?: string
lines?: string[]
attributes?: Metadata
}
export namespace WasmLib {
export interface Runme {
Runme: {
initialize: (source: string) => void
getCell: () => Cell
getCells: () => Cells
getSource: () => string
updateCell: (id: number, md: string) => Error | null
prepareScript: (lines: string[]) => string
}
}
export type Cell = {
editable: boolean
source: string
type: 'markdown'
} | {
attributes?: Attribute
editable: boolean
executable?: string
lines?: string[]
name: string
source: string
type: 'code'
}

export interface ParsedDocument {
document?: ParsedReadmeEntry[]
}
export interface Cells {
cells?: Cell[]
}

export interface Metadata {
[key: string]: any
export interface Attribute {
[key: string]: any
}
}

export interface CellOutput<T extends OutputType> {
Expand Down

0 comments on commit 658ea85

Please sign in to comment.