repl-sdk

The repl-sdk is a singleton per window. There is a Compiler class that has two responsibilities, once configured. Those two responsibilities:

  • render something based on the input (text + format)
    This includes:
    • downloading imported dependencies from npm
    • dynamically loading support for implemented compilers
    • handle custom compilers provided by a consumer
    • out of the box compilers are configurable
  • (optionally) create an editor with syntax highlighting, folding, etc

Install

With your favorite package manager

npm add repl-sdk

Bundled Compilers

repl-sdk will not load any compiler out of the box on its, unless a compile request is made for that compiler's registered format (sometimes narrowed by a "flavor").

Each format represents a file extension. For some formats, there are multiple flavors, like for jsx.

gjs

This is the Glimmer-flavored JavaScript syntax from Ember JS .

import { Compiler } from 'repl-sdk';

const compiler = new Compiler();

const { element, destroy } = await compiler.compile(
  'gjs',
  '... file contents ...',
  { /* options */ });

API Overview

There is only available module, and two exports from that module

import {
  Compiler,
  defaults
} from 'repl-sdk';

Compiler from repl-sdk

By default, no configuration is needed.

import { Compiler } from 'repl-sdk';

const compiler = new Compiler();
Debug logging can be configured on or conditionally on via any means you choose. Here we can configure logging when debug is present in the query params. This is very noisy for some module graphs, but is helpful in debugging the internal of repl-sdk.
import { Compiler } from 'repl-sdk';

const compiler = new Compiler({
  logging: location.search.includes('debug'),
});
If you want to wire up the higher-level messaging from each compiler to your UI, there is this on.log function that can be configured to push log messages outside of the Compiler
import { Compiler } from 'repl-sdk';

const compiler = new Compiler({
  on: {
    log: (type, message) => {
      // put log messages somewhere
    }
  }
});
The Compiler can take an options object for configuring each of the compilers. They each may take a different configuration, and will ignore any options that are not expected.
import { Compiler } from 'repl-sdk';

const compiler = new Compiler({
  options: {
    md: {
      remarkPlugins: [ /* ... */ ]
    },
    gjs: {
      owner: {
        lookup: () => {}
        resolveRegistration: () => {}
      }
    },
    jsx: {
      react: {
        /* ... */
      }
    }
  }
});

<Compiler#compile>

Calling compile takes 2 to 3 arguments, the file format, the file to compile, and then an optional set of options. The options are optional for all file formats except when there is some ambiguity -- such as for the jsx and hbs file formats.

The element doesn't need to be immediately attached anywhere, but in order for the user to view what was compiled, it will need to be placed somewhere.

import { Compiler } from 'repl-sdk';

const compiler = new Compiler();

const { element, destroy }
  = await compiler.compile('vue', '...', { /* options */ });

document.body.appendChild(element);

// sometime later, cleanup
destroy();

<Compiler#createEditor>

This editor uses codemirror which supports editing on both mobile and desktop devices, as well as proper keyboard accessibility.

It has all extensions and syntax configured for each of the supported language formats.

This is await import'd, so if you don't want to use codemirror, you will not pay for the bytes of codemirror in your bundled project.

import { Compiler } from 'repl-sdk';

const compiler = new Compiler();


await compiler.createEditor(
  // where to mount the editor
  element,
  {
    // initial text
    text,
    // initial file format (selects which plugins / syntax extensions to activate)
    format,
    // function to handle when the editor wants to submit updated text
    handleUpdate,
    // additional configuration of CodeMirror
    extensions: [ /* ... */ ],
  }
);

defaults from repl-sdk

This is the default configuration for the Compiler. It provides only the formats configuration with all the default compilers.

This can be used to add custom compilers, remove existing compilers, or replace them entirely.

import { Compiler, defaults } from 'repl-sdk';

const { formats } = defaults;

const compiler = new Compiler({
  formats: {
    // Only configure the compiler for Svelte and Vue
    svelte: formats.svelte,
    vue: formats.vue,
  }
})
Each compiler is await import'd so omitting compilers from this options object will omit their code from your final bundles.