Using Kotlin/JS compiler in Svelte "compiler"

Hi,

I am trying to use Kotlin/JS to develop a Svelte application, since Svelte is basically a compiler, any language targeting Javascript could theoretically be used to create a Svelte Web application. The Svelte framework use a tag to delimit any dynamic behavior in javascript. A project which is called svelte-preprocess takes what inside the script tag and converts it to pure Javascript. The project already supports coffeescript and typescript.

Here is how a .svelte file looks with javascript:

<script>
	let name = 'world';
</script>

<h1>Hello {name}!</h1>

the same in typescript:

<script lang="typescript">
    export let name: string = 'world'
</script>

<h1>Hello {name}!</h1>

And what I would like to be able to do in Kotlin:

<script lang="kotlin">
    val name = "world"
</script>

<h1>Hello {name}!</h1>

I am close to a solution with Kotlin/JS but the Kotlin/JS compiler is built around the concept of “output file” which is way to tell the compiler where to write the side effect of running it. This way of doing thing does not play nicely with the process used by Svelte,

Here is for example the typescript code handling typescript in svelte-preprocess:

  const {
    outputText: code,
    sourceMapText: map,
    diagnostics,
  } = ts.transpileModule(content, {
    fileName: filename,
    compilerOptions,
    reportDiagnostics: options.reportDiagnostics !== false,
    transformers: {
      before: [importTransformer],
    },
  });

We can see that the compiler takes a string as input and returns the transformed javascript code, plus the source map and some diagnostics information. The precise definition of the return type is:

declare namespace ts {
    interface TranspileOptions {
        compilerOptions?: CompilerOptions;
        fileName?: string;
        reportDiagnostics?: boolean;
        moduleName?: string;
        renamedDependencies?: MapLike<string>;
        transformers?: CustomTransformers;
    }
    interface TranspileOutput {
        outputText: string;
        diagnostics?: Diagnostic[];
        sourceMapText?: string;
    }
    function transpileModule(input: string, transpileOptions: TranspileOptions): TranspileOutput;
    function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string;
}

Would it be possible to include such changes in the kotlin/JS trans/compiler? What would be the best way to push for such a change? Or, maybe I am wrong, and there is already a way… or a technical solution I am not thinking about. I thought about writing temporary files but this solution seems quite inelegant to me, I may resort to it as a last option though.

I personally think Svelte would be quite a nice addition to the web frameworks supported by Kotlin/JS. It’s a new framework but the potential is definitely there and I think the steps to better integrate with from the Kotlin side are quite minimal.

Thanks!
Sébastien

3 Likes

This is a super interesting idea! Although there weren’t any replies yet, I wonder whether you made any progress towards integrating Kotlin/JS into the Svelte compiler yet?

For now, the project is pretty much on hold.

I thought there would be interest from the Kotlin team for what I consider an “easy target” or “low hanging fruit” but for now without this change to the compiler (which would probably makes it also easier to integrate Kotlin/JS in other toolchains) I have to resort to some hacks that I am reluctant to apply. Sadly, without a clear will from Kotlin team, I will not go forward with this.

There is also the question of bad symbols handling that I needed to test e.g. this line in the following code

$: clicks = proofCount + replayCount,
		 feedback = clicks > 20 && clicks < 50? 'that\'s a lot of damage' : clicks >= 50? 'your dedication is impressive' : '';

Taken from:

    import { fly } from 'svelte/transition';
	import { onMount } from 'svelte';		
	import { backOut, elasticOut } from 'svelte/easing';
	import { data } from './paths.js';
	
	let loaded, skew, color, proof, replayCount = 0, proofCount = 0, clicks, feedback;
	
	onMount(() => {
		loaded = true; 
		setTimeout(()=> skew = true, 1075);
		setTimeout(()=> color = true, 1100);
	});
	
	$: clicks = proofCount + replayCount,
		 feedback = clicks > 20 && clicks < 50? 'that\'s a lot of damage' : clicks >= 50? 'your dedication is impressive' : '';
	
	function prove() {
		proofCount += 1;
		proof = !proof	
	}
	
	function replay() {
		replayCount += 1;
		if (color) {
			loaded = false;
			skew = false;
			color = false;
			setTimeout(()=> loaded = true, 25);
			setTimeout(()=> skew = true, 1100);
			setTimeout(()=> color = true, 1125);
			return;
		}
		return;
	}

The compiler needs to leave them as is for svelte to work properly, I have no idea at this point how Kotlin/JS compiler is handling this.

The other question would be: does dukat could convert these libraries:

    import { fly } from 'svelte/transition';
	import { onMount } from 'svelte';		
	import { backOut, elasticOut } from 'svelte/easing';
	import { data } from './paths.js';

So, there is some work to do even if it is mostly validating things here and there, but the core, is the compiler. One, could fork it, but then have to maintain a separate branch which in itself might be a lot of work.

This is pretty much where things stands at this moment.

Anyway, thanks for the interest :slight_smile: I also thought it was a good idea!