diff --git a/frontend/src/lib/components/Editor.svelte b/frontend/src/lib/components/Editor.svelte index 372fb5f59d..1bfe15aac9 100644 --- a/frontend/src/lib/components/Editor.svelte +++ b/frontend/src/lib/components/Editor.svelte @@ -80,19 +80,27 @@ } export let shouldBindKey: boolean = true export let fixedOverflowWidgets = true - export let path: string = randomHash() + export let path: string | undefined = undefined export let yContent: Text | undefined = undefined export let awareness: any | undefined = undefined - if (path == '' || path == undefined || path.startsWith('/')) { - path = randomHash() + const rHash = randomHash() + $: filePath = computePath(path) + + function computePath(path: string | undefined): string { + if (path == '' || path == undefined || path.startsWith('/')) { + return rHash + } else { + return path as string + } } - let initialPath: string = path + let initialPath: string | undefined = path $: path != initialPath && lang == 'typescript' && handlePathChange() - let websockets: [MonacoLanguageClient, WebSocket][] = [] + let websockets: WebSocket[] = [] + let languageClients: MonacoLanguageClient[] = [] let websocketInterval: NodeJS.Timer | undefined let lastWsAttempt: Date = new Date() let nbWsAttempt = 0 @@ -101,7 +109,7 @@ const uri = lang == 'typescript' - ? `file:///${path}.${langToExt(lang)}` + ? `file:///${filePath}.${langToExt(lang)}` : `file:///tmp/monaco/${randomHash()}.${langToExt(lang)}` buildWorkerDefinition('../../../workers', import.meta.url, false) @@ -271,7 +279,7 @@ ) { try { const webSocket = new WebSocket(url) - + websockets.push(webSocket) webSocket.onopen = async () => { const socket = toSocket(webSocket) const reader = new WebSocketMessageReader(socket) @@ -285,7 +293,7 @@ // if (middlewareOptions != undefined) { // languageClient.registerNotUsedFeatures() // } - websockets.push([languageClient, webSocket]) + languageClients.push(languageClient) // HACK ALERT: for some reasons, the client need to be restarted to take into account the 'go get ' command // the only way I could figure out to listen for this event is this. I'm sure there is a better way to do this @@ -355,7 +363,7 @@ let encodedImportMap = '' if (lang == 'typescript') { - if (path && path.split('/').length > 2) { + if (filePath && filePath.split('/').length > 2) { let expiration = new Date() expiration.setHours(expiration.getHours() + 2) const token = await UserService.createToken({ @@ -367,7 +375,7 @@ 'file:///': root + '/' } } - let path_splitted = path.split('/') + let path_splitted = filePath.split('/') for (let c = 0; c < path_splitted.length; c++) { let key = 'file://./' for (let i = 0; i < c; i++) { @@ -551,28 +559,35 @@ let pathTimeout: NodeJS.Timeout | undefined = undefined function handlePathChange() { + console.log('path changed, reloading language server', initialPath, path) initialPath = path pathTimeout && clearTimeout(pathTimeout) - pathTimeout = setTimeout(reloadWebsocket, 3000) + pathTimeout = setTimeout(reloadWebsocket, 1000) } async function closeWebsockets() { command && command.dispose() command = undefined - for (const x of websockets) { + + console.debug(`disposing ${websockets.length} language clients and closing websockets`) + for (const x of languageClients) { try { - await x[0].dispose() - x[1].close() + await x.dispose() } catch (err) { - console.log('error disposing language client, closing websocket', err) - try { - x[1].close() - } catch (err) { - console.log('error disposing websocket, closin', err) - } + console.debug('error disposing language client', err) } } - console.log('disposed language client and closed websocket') + languageClients = [] + + for (const x of websockets) { + try { + await x.close() + } catch (err) { + console.debug('error closing websocket', err) + } + } + + console.debug('done closing websockets') websockets = [] websocketInterval && clearInterval(websocketInterval) } @@ -642,6 +657,7 @@ !websocketAlive.go && !websocketInterval ) { + console.log('reconnecting to language servers on focus') reloadWebsocket() } }) diff --git a/frontend/src/lib/components/InputTransformForm.svelte b/frontend/src/lib/components/InputTransformForm.svelte index 47ceb2f4e3..615ccf0a57 100644 --- a/frontend/src/lib/components/InputTransformForm.svelte +++ b/frontend/src/lib/components/InputTransformForm.svelte @@ -250,7 +250,7 @@ {/if} {#if isStaticTemplate(inputCat) && propertyType == 'static' && !noDynamicToggle} -
+
{#if arg} ) { + args = nargs + } + function removeExtraKey() { const nargs = {} Object.keys(args ?? {}).forEach((key) => { @@ -57,7 +61,7 @@ {#if keys.length > 0} {#each keys as argName (argName)} {#if (!filter || filter.includes(argName)) && Object.keys(schema.properties ?? {}).includes(argName)} -
+
= value.input_transforms - - $: value.input_transforms = inputTransforms - $: stepPropPicker = failureModule ? { pickableProperties: { @@ -91,16 +84,15 @@ } } + let inputTransformSchemaForm: InputTransformSchemaForm | undefined = undefined async function reload(flowModule: FlowModule) { try { const { input_transforms, schema } = await loadSchemaFromModule(flowModule) validCode = true - setTimeout(() => { - if (!deepEqual(value.input_transforms, input_transforms)) { - inputTransforms = input_transforms - } - }) + inputTransformSchemaForm?.setArgs(input_transforms) + + await tick() if (!deepEqual(schema, $flowStateStore[flowModule.id]?.schema)) { if (!$flowStateStore[flowModule.id]) { $flowStateStore[flowModule.id] = { schema } @@ -127,15 +119,12 @@ totalTopGap = panesTop - wrapperTop }) - let isScript = true - $: isScript != (value.type === 'script') && (isScript = value.type === 'script') - let forceReload = 0 -{#if value} +{#if flowModule.value}
@@ -173,12 +162,12 @@ /> - {#if value.type === 'rawscript'} + {#if flowModule.value.type === 'rawscript'}
@@ -191,65 +180,68 @@ style="max-height: calc(100% - {totalTopGap}px) !important;" > - - {#if value.type === 'rawscript'} - { - selected = 'test' - if ($selectedId == flowModule.id) { - if (value.type === 'rawscript') { - value.content = editor.getCode() + + {#if flowModule.value.type === 'rawscript'} + {#key flowModule.id} + { + selected = 'test' + if ($selectedId == flowModule.id) { + if (flowModule.value.type === 'rawscript') { + flowModule.value.content = editor.getCode() + } + await reload(flowModule) + modulePreview?.runTestWithStepArgs() + } + }} + on:change={async (event) => { + if (flowModule.value.type === 'rawscript') { + flowModule.value.content = event.detail } await reload(flowModule) - modulePreview?.runTestWithStepArgs() - } - }} - on:change={async (event) => { - if (flowModule.value.type === 'rawscript') { - flowModule.value.content = event.detail - } - await reload(flowModule) - }} - formatAction={() => { - reload(flowModule) - saveDraft() - }} - fixedOverflowWidgets={true} - /> - {:else if value.type === 'script'} - {#key forceReload} - + }} + formatAction={() => { + reload(flowModule) + saveDraft() + }} + fixedOverflowWidgets={true} + /> {/key} - {:else if value.type === 'flow'} - + {:else if flowModule.value.type === 'script'} + {#key forceReload} + + {/key} + {:else if flowModule.value.type === 'flow'} + {/if} - + Step Input Test this step Advanced
- {#if selected === 'inputs'} + {#if selected === 'inputs' && (flowModule.value.type == 'rawscript' || flowModule.value.type == 'script' || flowModule.value.type == 'flow')}
diff --git a/react-sdk/index.html b/react-sdk/index.html index ca4571c175..3155b1e1c0 100644 --- a/react-sdk/index.html +++ b/react-sdk/index.html @@ -7,6 +7,7 @@ Windmill SDK example + Windmill