• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

source-academy / js-slang / 23995741899

05 Apr 2026 06:14AM UTC coverage: 77.093% (+0.002%) from 77.091%
23995741899

push

github

web-flow
Upgrade to TypeScript 6 and Prettier improvements (#1936)

* Upgrade TypeScript to v6

* Fix import source

* Fix tsconfig

* Fix preexisting type errors

* Remove scm-slang

* Bump node types

* Fix tsconfig

* Fix node types specifier

* Enable trailing commas

* Enable semicolons

* Check and commit files with changed line numbers

* Update Yarn to 4.13.0

* Remove unneeded sicp package deps

3112 of 4282 branches covered (72.68%)

Branch coverage included in aggregate %.

3761 of 5218 new or added lines in 152 files covered. (72.08%)

26 existing lines in 9 files now uncovered.

7136 of 9011 relevant lines covered (79.19%)

175254.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.0
/src/runner/sourceRunner.ts
1
import * as _ from 'lodash';
2
import type { RawSourceMap } from 'source-map';
3

4
import { JSSLANG_PROPERTIES } from '../constants';
5
import { CSEResultPromise, evaluate as CSEvaluate } from '../cse-machine/interpreter';
6
import { ExceptionError } from '../errors/errors';
7
import { RuntimeSourceError } from '../errors/runtimeSourceError';
8
import { TimeoutError } from '../errors/timeoutErrors';
9
import { getSteps } from '../tracer/steppers';
10
import { sandboxedEval } from '../transpiler/evalContainer';
11
import { transpile } from '../transpiler/transpiler';
12
import { toSourceError } from './errors';
13
import fullJSRunner from './fullJSRunner';
14
import type { Runner } from './types';
15

16
let isPreviousCodeTimeoutError = false;
53✔
17
const runners = {
53✔
18
  fulljs: fullJSRunner,
19
  'cse-machine': (program, context, options) => {
20
    const value = CSEvaluate(program, context, options);
929✔
21
    return CSEResultPromise(context, value);
929✔
22
  },
23
  substitution: (program, context, options) => {
NEW
24
    const steps = getSteps(program, context, options);
×
25
    if (context.errors.length > 0) {
×
NEW
26
      return Promise.resolve({ status: 'error', context });
×
27
    }
28
    return Promise.resolve({
×
29
      status: 'finished',
30
      context,
31
      value: steps,
32
    });
33
  },
34
  native: async (program, context, options) => {
35
    if (!options.isPrelude) {
712✔
36
      if (context.shouldIncreaseEvaluationTimeout && isPreviousCodeTimeoutError) {
413✔
37
        context.nativeStorage.maxExecTime *= JSSLANG_PROPERTIES.factorToIncreaseBy;
3✔
38
      } else {
39
        context.nativeStorage.maxExecTime = options.originalMaxExecTime;
410✔
40
      }
41
    }
42

43
    // For whatever reason, the transpiler mutates the state of the AST as it is transpiling and inserts
44
    // a bunch of global identifiers to it. Once that happens, the infinite loop detection instrumentation
45
    // ends up generating code that has syntax errors. As such, we need to make a deep copy here to preserve
46
    // the original AST for future use, such as with the infinite loop detector.
47
    const transpiledProgram = _.cloneDeep(program);
712✔
48
    let transpiled;
49
    let sourceMapJson: RawSourceMap | undefined;
50
    try {
712✔
51
      ({ transpiled, sourceMapJson } = transpile(transpiledProgram, context));
712✔
52
      let value = sandboxedEval(transpiled, context.nativeStorage);
712✔
53

54
      if (!options.isPrelude) {
712✔
55
        isPreviousCodeTimeoutError = false;
346✔
56
      }
57

58
      return {
645✔
59
        status: 'finished',
60
        context,
61
        value,
62
      };
63
    } catch (error) {
64
      if (error instanceof RuntimeSourceError) {
67✔
65
        context.errors.push(error);
19✔
66
        if (error instanceof TimeoutError) {
19✔
67
          isPreviousCodeTimeoutError = true;
7✔
68
        }
69
        return { status: 'error', context };
19✔
70
      }
71
      if (error instanceof ExceptionError) {
48✔
72
        // if we know the location of the error, just throw it
73
        if (error.location.start.line !== -1) {
45✔
74
          context.errors.push(error);
40✔
75
          return { status: 'error', context };
40✔
76
        } else {
77
          error = error.error; // else we try to get the location from source map
5✔
78
        }
79
      }
80

81
      const sourceError = await toSourceError(error, sourceMapJson);
8✔
82
      context.errors.push(sourceError);
8✔
83
      return { status: 'error', context };
8✔
84
    }
85
  },
86
} satisfies Record<string, Runner>;
87

88
export default runners;
89

90
export type RunnerTypes = keyof typeof runners;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc