Skip to content

Commit

Permalink
before esbuild refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenfiszel committed Jan 3, 2025
1 parent 334a62e commit a424edf
Show file tree
Hide file tree
Showing 38 changed files with 2,188 additions and 591 deletions.
118 changes: 91 additions & 27 deletions frontend/src/lib/components/Editor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@
import { parseTypescriptDeps } from '$lib/relative_imports'
import type { AiProviderTypes } from './copilot/lib'
import { scriptLangToEditorLang } from '$lib/scripts'
import * as htmllang from '$lib/svelteMonarch'
// import EditorTheme from './EditorTheme.svelte'
Expand All @@ -203,19 +204,18 @@
export let args: Record<string, any> | undefined = undefined
export let useWebsockets: boolean = true
export let small = false
export let scriptLang: Preview['language'] | 'bunnative' | 'tsx' | 'json'
export let scriptLang: Preview['language'] | 'bunnative' | 'tsx' | 'json' | undefined
export let disabled: boolean = false
export let lineNumbersMinChars = 3
export let files: Record<string, { code: string }> | undefined = {}
export let files: Record<string, { code: string; readonly?: boolean }> | undefined = {}
export let extraLib: string | undefined = undefined
let lang = scriptLangToEditorLang(scriptLang)
$: lang = scriptLangToEditorLang(scriptLang)
let filePath = computePath(path)
$: filePath = computePath(path)
let models: Record<string, meditor.ITextModel> = {}
let initialPath: string | undefined = path
$: path != initialPath &&
Expand All @@ -241,20 +241,29 @@
buildWorkerDefinition()
function computeUri(filePath: string, scriptLang: string | undefined) {
let file
if (filePath.includes('.')) {
file = filePath
} else {
file = `${filePath}.${scriptLang == 'tsx' ? 'tsx' : langToExt(lang)}`
}
if (file.startsWith('/')) {
file = file.slice(1)
}
return !['deno', 'go', 'python3'].includes(scriptLang ?? '')
? `file:///${filePath}.${scriptLang == 'tsx' ? 'tsx' : langToExt(lang)}`
: `file:///tmp/monaco/${filePath}.${langToExt(lang)}`
? `file:///${file}`
: `file:///tmp/monaco/${file}`
}
function computePath(path: string | undefined): string {
if (
['deno', 'go', 'python3'].includes(scriptLang ?? '') ||
path == '' ||
path == undefined ||
path.startsWith('/')
path == undefined //||path.startsWith('/')
) {
return randomHash()
} else {
console.log('path', path)
return path as string
}
}
Expand All @@ -263,15 +272,17 @@
if (editor) {
const uri = mUri.parse(path)
console.log('switching to file', path, lang)
if (models[path]) {
// vscode.workspace.fs.writeFile(uri, new TextEncoder().encode(value))
let nmodel = meditor.getModel(uri)
if (nmodel) {
console.log('using existing model', path)
editor.setModel(models[path])
editor.setModel(nmodel)
} else {
console.log('creating model', path)
const model = meditor.createModel(value, lang, uri)
models[path] = model
editor.setModel(model)
nmodel = meditor.createModel(value, lang, uri)
editor.setModel(nmodel)
}
model = nmodel
}
}
Expand Down Expand Up @@ -1135,8 +1146,55 @@
}
}
$: files && model && onFileChanges()
let svelteRegistered = false
function onFileChanges() {
if (files && Object.keys(files).find((x) => x.endsWith('.svelte')) != undefined) {
if (!svelteRegistered) {
svelteRegistered = true
languages.register({
id: 'svelte',
extensions: ['.svelte'],
aliases: ['Svelte', 'svelte'],
mimetypes: ['application/svelte']
})
languages.setLanguageConfiguration('svelte', htmllang.conf as any)
languages.setMonarchTokensProvider('svelte', htmllang.language as any)
}
}
if (files && model) {
for (const [path, { code, readonly }] of Object.entries(files)) {
const luri = mUri.file(path)
console.log('checking file', model.uri.toString(), luri.toString())
if (luri.toString() != model.uri.toString()) {
let nmodel = meditor.getModel(luri)
if (nmodel == undefined) {
const lmodel = meditor.createModel(code, extToLang(path?.split('.')?.pop()!), luri)
if (readonly) {
lmodel.onDidChangeContent((evt) => {
// This will effectively undo any new edits
if (lmodel.getValue() != code && code) {
lmodel.setValue(code)
}
})
}
} else {
const lmodel = meditor.getModel(luri)
if (lmodel && code) {
lmodel.setValue(code)
}
}
}
}
}
}
let timeoutModel: NodeJS.Timeout | undefined = undefined
async function loadMonaco() {
console.log('path', uri)
try {
console.log("Loading Monaco's language client")
await initializeVscode('editor')
Expand All @@ -1145,14 +1203,26 @@
console.log('error initializing services', e)
}
// vscode.languages.registerDefinitionProvider('*', {
// provideDefinition(document, position, token) {
// // Get the word under the cursor (this will be the import or function being clicked)
// const wordRange = document.getWordRangeAtPosition(position)
// const word = document.getText(wordRange)
// // Do something with the word (for example, log it or handle it)
// console.log('Clicked on import or symbol:', word)
// // Optionally, you can also return a definition location
// return null // If you don't want to override the default behavior
// }
// })
// console.log('bef ready')
// console.log('af ready')
initialized = true
try {
model = meditor.createModel(code, lang, mUri.parse(uri))
models[path ?? ''] = model
} catch (err) {
console.log('model already existed', err)
const nmodel = meditor.getModel(mUri.parse(uri))
Expand All @@ -1163,17 +1233,7 @@
}
model.updateOptions(lang == 'python' ? { tabSize: 4, insertSpaces: true } : updateOptions)
if (files) {
for (const [path, { code }] of Object.entries(files)) {
const luri = mUri.file(path)
if (luri.toString() != model.uri.toString()) {
if (!models[path] && meditor.getModel(luri) == undefined) {
const lmodel = meditor.createModel(code, extToLang(path?.split('.')?.pop()!), luri)
models[path] = lmodel
}
}
}
}
onFileChanges()
editor = meditor.create(divEl as HTMLDivElement, {
...editorConfig(code, lang, automaticLayout, fixedOverflowWidgets),
Expand All @@ -1194,7 +1254,7 @@
timeoutModel = setTimeout(() => {
let ncode = getCode()
code = ncode
dispatch('change', code)
dispatch('change', ncode)
}, 500)
ataModel && clearTimeout(ataModel)
Expand Down Expand Up @@ -1235,7 +1295,6 @@
!websocketAlive.go &&
!websocketInterval
) {
console.log('reconnecting to language servers on focus')
reloadWebsocket()
}
})
Expand Down Expand Up @@ -1263,6 +1322,11 @@
}
async function setTypescriptExtraLibsATA() {
if (extraLib) {
const uri = mUri.parse('file:///extraLib.d.ts')
languages.typescript.typescriptDefaults.addExtraLib(extraLib, uri.toString())
}
console.log('scriptLang ATA', scriptLang)
if (lang === 'typescript' && (scriptLang == 'bun' || scriptLang == 'tsx') && ata == undefined) {
const hostname = getHostname()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import Alert from '$lib/components/common/alert/Alert.svelte'
import LightweightSchemaForm from '$lib/components/LightweightSchemaForm.svelte'
import Popover from '$lib/components/Popover.svelte'
import { AppService, type ExecuteComponentData } from '$lib/gen'
import { type ExecuteComponentData } from '$lib/gen'
import { classNames, defaultIfEmptyString, emptySchema, sendUserToast } from '$lib/utils'
import { deepEqual } from 'fast-equals'
import { Bug } from 'lucide-svelte'
Expand All @@ -27,6 +27,7 @@
import RefreshButton from '$lib/components/apps/components/helpers/RefreshButton.svelte'
import { ctxRegex } from '../../utils'
import { computeWorkspaceS3FileInputPolicy } from '../../editor/appUtilsS3'
import { executeRunnable } from './executeRunnable'
// Component props
export let id: string
Expand Down Expand Up @@ -329,84 +330,22 @@
try {
jobId = await resultJobLoader?.abstractRun(async () => {
const nonStaticRunnableInputs = dynamicArgsOverride ?? {}
const staticRunnableInputs = {}
const allowUserResources: string[] = []
for (const k of Object.keys(fields ?? {})) {
let field = fields[k]
if (field?.type == 'static' && fields[k]) {
if (isEditor) {
staticRunnableInputs[k] = field.value
}
} else if (field?.type == 'user') {
nonStaticRunnableInputs[k] = args?.[k]
if (isEditor && field.allowUserResources) {
allowUserResources.push(k)
}
} else if (field?.type == 'eval' || (field?.type == 'evalv2' && inputValues[k])) {
const ctxMatch = field.expr.match(ctxRegex)
if (ctxMatch) {
nonStaticRunnableInputs[k] = '$ctx:' + ctxMatch[1]
} else {
nonStaticRunnableInputs[k] = await inputValues[k]?.computeExpr()
}
if (isEditor && field?.type == 'evalv2' && field.allowUserResources) {
allowUserResources.push(k)
}
} else {
if (isEditor && field?.type == 'connected' && field.allowUserResources) {
allowUserResources.push(k)
}
nonStaticRunnableInputs[k] = runnableInputValues[k]
}
}
const oneOfRunnableInputs = isEditor ? collectOneOfFields(fields, $app) : {}
const requestBody: ExecuteComponentData['requestBody'] = {
args: nonStaticRunnableInputs,
component: id,
force_viewer_static_fields: !isEditor ? undefined : staticRunnableInputs,
force_viewer_one_of_fields: !isEditor ? undefined : oneOfRunnableInputs,
force_viewer_allow_user_resources: !isEditor ? undefined : allowUserResources
}
if (runnable?.type === 'runnableByName') {
const { inlineScript } = inlineScriptOverride
? { inlineScript: inlineScriptOverride }
: runnable
if (inlineScript) {
if (inlineScript.id !== undefined) {
requestBody['id'] = inlineScript.id
}
requestBody['raw_code'] = {
content: inlineScript.id === undefined ? inlineScript.content : '',
language: inlineScript.language ?? '',
path: $appPath + '/' + inlineScript.id,
lock: inlineScript.id === undefined ? inlineScript.lock : undefined,
cache_ttl: inlineScript.cache_ttl
}
}
} else if (runnable?.type === 'runnableByPath') {
const { path, runType } = runnable
requestBody['path'] = runType !== 'hubscript' ? `${runType}/${path}` : `script/${path}`
}
if ($app.version !== undefined) {
requestBody['version'] = $app.version
}
const uuid = await AppService.executeComponent({
const uuid = await executeRunnable(
runnable,
workspace,
path: defaultIfEmptyString($appPath, `u/${$userStore?.username ?? 'unknown'}/newapp`),
requestBody
})
$app.version,
$userStore?.username,
$appPath,
id,
await buildRequestBody(dynamicArgsOverride),
inlineScriptOverride
)
if (isEditor) {
addJob(uuid)
}
return uuid
}, callbacks)
if (setRunnableJobEditorPanel && editorContext) {
editorContext.runnableJobEditorPanel.update((p) => {
return {
Expand All @@ -428,6 +367,51 @@
}
type Callbacks = { done: (x: any) => void; cancel: () => void; error: (e: any) => void }
export async function buildRequestBody(dynamicArgsOverride: Record<string, any> | undefined) {
const nonStaticRunnableInputs = dynamicArgsOverride ?? {}
const staticRunnableInputs = {}
const allowUserResources: string[] = []
for (const k of Object.keys(fields ?? {})) {
let field = fields[k]
if (field?.type == 'static' && fields[k]) {
if (isEditor) {
staticRunnableInputs[k] = field.value
}
} else if (field?.type == 'user') {
nonStaticRunnableInputs[k] = args?.[k]
if (isEditor && field.allowUserResources) {
allowUserResources.push(k)
}
} else if (field?.type == 'eval' || (field?.type == 'evalv2' && inputValues[k])) {
const ctxMatch = field.expr.match(ctxRegex)
if (ctxMatch) {
nonStaticRunnableInputs[k] = '$ctx:' + ctxMatch[1]
} else {
nonStaticRunnableInputs[k] = await inputValues[k]?.computeExpr()
}
if (isEditor && field?.type == 'evalv2' && field.allowUserResources) {
allowUserResources.push(k)
}
} else {
if (isEditor && field?.type == 'connected' && field.allowUserResources) {
allowUserResources.push(k)
}
nonStaticRunnableInputs[k] = runnableInputValues[k]
}
}
const oneOfRunnableInputs = isEditor ? collectOneOfFields(fields, $app) : {}
const requestBody: ExecuteComponentData['requestBody'] = {
args: nonStaticRunnableInputs,
component: id,
force_viewer_static_fields: !isEditor ? undefined : staticRunnableInputs,
force_viewer_one_of_fields: !isEditor ? undefined : oneOfRunnableInputs,
force_viewer_allow_user_resources: !isEditor ? undefined : allowUserResources
}
return requestBody
}
export async function runComponent(
noToast = true,
inlineScriptOverride?: InlineScript,
Expand Down
Loading

0 comments on commit a424edf

Please sign in to comment.