CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vue--repl

Vue component for editing Vue components with interactive REPL functionality.

Pending
Overview
Eval results
Files

file-system.mddocs/

File System

The file system provides the File class and compilation utilities for managing code files with compilation results, editor state persistence, and language detection.

Capabilities

File Class

Core file model representing a single file in the REPL with compilation state and editor persistence.

/**
 * Represents a file in the REPL with code content and compilation results
 */
class File {
  /** File path/name relative to project root */
  filename: string;
  /** Raw source code content */
  code: string;
  /** Whether file is hidden from file explorer UI */
  hidden: boolean;
  
  /** Compilation results for different output formats */
  compiled: {
    /** Compiled JavaScript code */
    js: string;
    /** Extracted/compiled CSS */
    css: string;
    /** Server-side rendering compiled code */
    ssr: string;
    /** Client-side source map */
    clientMap: string;
    /** SSR source map */
    ssrMap: string;
  };
  
  /** Monaco editor view state for cursor/scroll position persistence */
  editorViewState: editor.ICodeEditorViewState | null;
  
  /**
   * Create a new file instance
   * @param filename - File path/name
   * @param code - Initial file content
   * @param hidden - Whether file should be hidden from UI
   */
  constructor(filename: string, code?: string, hidden?: boolean);
  
  /** 
   * Detected language based on file extension
   * @returns Language identifier for syntax highlighting
   */
  readonly language: 'vue' | 'html' | 'css' | 'typescript' | 'javascript';
}

Usage Examples:

import { File } from "@vue/repl/core";

// Create new Vue component file
const vueFile = new File(
  'src/components/Button.vue',
  `<template>
  <button @click="handleClick">
    <slot />
  </button>
</template>

<script setup lang="ts">
const emit = defineEmits<{
  click: [event: MouseEvent]
}>();

const handleClick = (event: MouseEvent) => {
  emit('click', event);
};
</script>

<style scoped>
button {
  padding: 8px 16px;
  border-radius: 4px;
}
</style>`
);

// Create TypeScript utility file
const tsFile = new File(
  'src/utils/helpers.ts',
  `export const formatDate = (date: Date): string => {
  return date.toLocaleDateString();
};

export const debounce = <T extends (...args: any[]) => any>(
  fn: T,
  delay: number
): T => {
  let timeoutId: ReturnType<typeof setTimeout>;
  return ((...args: any[]) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn(...args), delay);
  }) as T;
};`
);

// Create hidden configuration file
const configFile = new File(
  'package.json',
  JSON.stringify({ name: 'my-app', version: '1.0.0' }),
  true // hidden from file explorer
);

// Access file properties
console.log(vueFile.language); // 'vue'
console.log(tsFile.language);  // 'typescript'
console.log(vueFile.compiled.js); // Compiled JavaScript after compilation

Compilation Function

Core compilation function that processes different file types into executable code.

/**
 * Compile a file based on its type and content
 * Handles Vue SFC, TypeScript/JavaScript, CSS, and JSON files
 * @param store - Store instance for compiler access and options
 * @param file - File instance to compile
 * @returns Promise resolving to array of compilation errors or empty array
 */
function compileFile(
  store: Store,
  file: File
): Promise<(string | Error)[]>;

Supported File Types:

  • .vue: Vue Single File Components with full SFC compilation
  • .ts, .tsx: TypeScript files with JSX support
  • .js, .jsx: JavaScript files with JSX support
  • .css: CSS stylesheets (passed through unchanged)
  • .json: JSON files (converted to ES module exports)

Usage Examples:

import { compileFile, File, useStore } from "@vue/repl/core";

const store = useStore();
const file = new File('src/App.vue', '<template><div>Hello</div></template>');

// Compile the file
const errors = await compileFile(store, file);

if (errors.length === 0) {
  console.log('Compiled successfully');
  console.log(file.compiled.js); // Compiled JavaScript
  console.log(file.compiled.css); // Extracted CSS
} else {
  console.error('Compilation errors:', errors);
}

// TypeScript file compilation
const tsFile = new File('utils.ts', `
export const add = (a: number, b: number): number => a + b;
`);

const tsErrors = await compileFile(store, tsFile);
console.log(tsFile.compiled.js); // Compiled JavaScript without types

Language Detection

Files automatically detect their language based on file extensions for proper syntax highlighting and compilation.

/**
 * Language detection based on file extension
 */
type FileLanguage = 'vue' | 'html' | 'css' | 'typescript' | 'javascript';

/**
 * Language detection mapping
 */
const languageMap = {
  '.vue': 'vue',
  '.html': 'html', 
  '.css': 'css',
  '.ts': 'typescript',
  '.tsx': 'typescript',
  '.js': 'javascript',
  '.jsx': 'javascript'
};

Usage Example:

const files = [
  new File('App.vue'),
  new File('utils.ts'),
  new File('styles.css'),
  new File('config.json')
];

files.forEach(file => {
  console.log(`${file.filename}: ${file.language}`);
});
// Output:
// App.vue: vue
// utils.ts: typescript
// styles.css: css
// config.json: javascript (default)

Editor State Persistence

Files maintain editor view state for cursor position, scroll position, and selections across editor switches.

/**
 * Monaco editor view state interface
 */
interface ICodeEditorViewState {
  cursorState: ICursorState[];
  viewState: IViewState;
  contributionsState: { [id: string]: any };
}

Usage Example:

// View state is automatically managed by the editor components
// No manual intervention needed - handled by Monaco/CodeMirror editors

// Access view state if needed
const file = store.activeFile;
if (file.editorViewState) {
  console.log('File has saved editor state');
}

File Naming Conventions

The file system uses specific naming conventions for special files:

/** Standard filename for import map configuration */
const importMapFile = 'import-map.json';

/** Standard filename for TypeScript configuration */
const tsconfigFile = 'tsconfig.json';

/**
 * Add src/ prefix to relative file paths
 * @param file - File path
 * @returns Path with src/ prefix if needed
 */
function addSrcPrefix(file: string): string;

/**
 * Remove src/ prefix from file paths for export
 * @param file - File path with potential src/ prefix
 * @returns Path without src/ prefix
 */
function stripSrcPrefix(file: string): string;

Usage Examples:

import { stripSrcPrefix } from "@vue/repl/core";

// File path normalization
console.log(addSrcPrefix('App.vue'));        // 'src/App.vue'
console.log(addSrcPrefix('src/App.vue'));    // 'src/App.vue' (unchanged)
console.log(stripSrcPrefix('src/App.vue'));  // 'App.vue'

// Special files bypass src/ prefix
console.log(addSrcPrefix('import-map.json')); // 'import-map.json'
console.log(addSrcPrefix('tsconfig.json'));   // 'tsconfig.json'

Compilation Details

Vue SFC Compilation

Vue Single File Components undergo comprehensive compilation:

  1. Parsing: Template, script, and style blocks extracted
  2. Script compilation: TypeScript/JavaScript processing with imports
  3. Template compilation: Vue template syntax to render functions
  4. Style processing: CSS extraction and scoping
  5. Source map generation: Debugging support with original source mapping

Compilation Options:

The compilation process respects store SFC options:

// SFC compilation can be customized via store
store.sfcOptions = {
  script: {
    babelParserPlugins: ['jsx', 'decorators-legacy']
  },
  template: {
    compilerOptions: {
      isCustomElement: (tag) => tag.startsWith('custom-')
    }
  },
  style: {
    trim: true
  }
};

Error Handling

Compilation errors are comprehensive and helpful:

  • Syntax errors: Parser errors with line/column information
  • Type errors: TypeScript compilation issues
  • Template errors: Vue template syntax problems
  • Import errors: Module resolution failures
  • Preprocessing errors: Unsupported language features
// Errors are returned as array of strings or Error objects
const errors = await compileFile(store, file);
errors.forEach(error => {
  if (typeof error === 'string') {
    console.error('Compilation error:', error);
  } else {
    console.error('Exception:', error.message, error.stack);
  }
});

Install with Tessl CLI

npx tessl i tessl/npm-vue--repl

docs

editor-components.md

file-system.md

import-map-management.md

index.md

preview-system.md

repl-component.md

store-management.md

tile.json