Skip to content

Commit

Permalink
chore: adds worker output logging
Browse files Browse the repository at this point in the history
  • Loading branch information
justin-schroeder committed Jan 31, 2024
1 parent 7bf9dab commit 058f8cc
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 11 deletions.
33 changes: 25 additions & 8 deletions docs/components/CodeExample.client.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const code = ref("")
const el = ref<null | HTMLDivElement>(null)
const value = await import(`../examples/${props.file}.ts?raw`)
code.value = value.default
const result = ref()
const result = ref<Array<string[]>>([])
const error = ref("")
const stopWatch = watch(el, () => {
Expand All @@ -31,6 +31,7 @@ const stopWatch = watch(el, () => {
lineNumbers: "off",
glyphMargin: false,
folding: false,
renderLineHighlight: "none",
})
stopWatch()
Expand All @@ -55,7 +56,7 @@ const stopWatch = watch(el, () => {
if (code === "") return
code = processPlaygroundCode(code)
if (worker) worker.terminate()
result.value = ""
result.value = []
error.value = ""
worker = new Worker(
Expand All @@ -64,20 +65,32 @@ const stopWatch = watch(el, () => {
type: "module",
}
)
worker.postMessage(code)
worker.onmessage = (e) => {
result.value = e.data
worker.onmessage = (e: {
data: { lineNumber: number; value: unknown }
}) => {
result.value[e.data.lineNumber] ??= []
if (e.data.value instanceof Date) {
result.value[e.data.lineNumber].push(
`Date: ${e.data.value.toISOString()}`
)
} else {
result.value[e.data.lineNumber].push(String(e.data.value))
}
}
worker.onerror = (e) => {
result.value = ""
result.value = []
error.value = "Your code contains errors."
}
}
let debounceTimer: NodeJS.Timeout | number | null = null
editor.onDidChangeModelContent(() => {
code.value = editor.getValue()
updateSize()
runInsideWorker(code.value)
if (debounceTimer) clearTimeout(debounceTimer)
debounceTimer = setTimeout(() => runInsideWorker(code.value), 500)
})
updateSize()
Expand All @@ -89,8 +102,12 @@ const stopWatch = watch(el, () => {
<template>
<div class="rounded-md bg-slate-100 dark:bg-slate-800 flex">
<div class="w-1/2" ref="el"></div>
<div class="w-1/2 bg-slate-200 font-mono whitespace-pre p-4">
<div v-if="result">{{ result }}</div>
<div class="w-1/2 bg-slate-200 font-mono p-4 overflow-auto">
<ul v-if="result">
<li v-for="logs in result" class="text-nowrap h-6 text-slate-600">
{{ logs ? logs.join(", ") : "" }}
</li>
</ul>
<div class="bg-red-500 font-mono p-4" v-else-if="error">
{{ error }}
</div>
Expand Down
4 changes: 3 additions & 1 deletion docs/examples/example1.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { format } from "@formkit/tempo"
import { format, parse } from "@formkit/tempo"

const x = format(new Date(), "MM/DD/YYYY")

parse("2012-01-01")

console.log(x)
4 changes: 2 additions & 2 deletions docs/src/playground.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ async function loadTempo() {
return await import("@formkit/tempo")
}

function logOut(...args: string[]) {
self.postMessage(args.join(", "))
function logOut(lineNumber: number, value: unknown) {
self.postMessage({ lineNumber, value })
}
self.onmessage = function (event) {
eval(event.data)
Expand Down
28 changes: 28 additions & 0 deletions docs/src/processPlaygroundCode.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* Preprocess source code examples for use in the playground. This allows us to
* use actual import statements, and also wrap all the functions a logging
* system so we get repl like behavior.
*
* @param rawSource - Source code to process
*/
export function processPlaygroundCode(rawSource: string): string {
const fns = new Set<string>()
// Replace the import statement with a dynamic import, and create a set of
Expand Down Expand Up @@ -38,6 +45,19 @@ export function processPlaygroundCode(rawSource: string): string {
return `(async () => { ${code} })()`
}

/**
* Parses javascript code and wraps all the functions in the fns array with the
* wrapFn function call. The wrapFn function call will be passed the line number
* of the function call as the first argument. This is useful for logging out
* results of the function calls in the playground.
*
* This function is not perfect, but much small and faster than a full AST
* parser and manipulator.
*
* @param code - Source code to wrap
* @param fns - List of functions to wrap
* @param wrapFn - Wrap all the above functions in this function call
*/
function wrapFunctions(code: string, fns: string[], wrapFn: string): string {
const chars = [...code]
let quote = ""
Expand Down Expand Up @@ -98,6 +118,14 @@ function wrapFunctions(code: string, fns: string[], wrapFn: string): string {
return chars.join("")
}

/**
* Checks if the next character could be part of a function name.
*
* @param char - The character to check
* @param currentFnStr - The current function string we are building
* @param fns - The list of functions we are looking for
* @param possibleFns - List of functions we have narrowed it down to
*/
function isNextChar(
char: string,
currentFnStr: string,
Expand Down

0 comments on commit 058f8cc

Please sign in to comment.