Repository: pyscript/pyscript
File: pyscriptjs/src/components/pyconfig.ts (TypeScript)

Code before:
 * automatically, etc.
 *
 * Also initializes the different runtimes passed. If no runtime is passed,
 * the default runtime based on Pyodide is used.
 */

export class PyConfig extends BaseEvalElement {
    widths: Array<string>;
    label: string;
    mount_name: string;
    details: HTMLElement;
    operation: HTMLElement;
    values: AppConfig;
    constructor() {
        super();
    }

    connectedCallback() {
        let loadedValues: object = {};
        let srcConfig: object = {};
        let inlineConfig: object = {};

        // load config from src and inline
        if (this.hasAttribute('src') && this.innerHTML!=='')
        {
            srcConfig = JSON.parse(readTextFromPath(this.getAttribute('src')));
            this.code = this.innerHTML;
            this.innerHTML = '';
            inlineConfig = JSON.parse(this.code);
            loadedValues = mergeConfig(inlineConfig, srcConfig);
            logger.info('config set from src attribute and inline both, merging', JSON.stringify(loadedValues));
        }
        // load config from src only
        else if (this.hasAttribute('src'))
        {
            const srcText = readTextFromPath(this.getAttribute('src'));
            srcConfig = JSON.parse(srcText);
            logger.info('config set from src attribute', srcText);
            loadedValues = srcConfig;
        }
        // load config from inline
        else if (this.innerHTML!=='')
        {
            this.code = this.innerHTML;
            this.innerHTML = '';
            inlineConfig = JSON.parse(this.code);
            logger.info('config set from inline, merging with default', this.code);
            loadedValues = mergeConfig(inlineConfig, inJest() ? defaultConfig : JSON.parse(defaultConfig));
        }
        // load from default if still undefined
        if (Object.keys(loadedValues).length === 0) {

Review comment (suggestion):
JSON.parse needs error handling for SyntaxError. How do we convey this error to developers?
```javascript
try{
  const result = JSON.parse({});
} catch (err) {
  // SyntaxError
  console.log(err.message);
}
```

Code after:
 * Also initializes the different runtimes passed. If no runtime is passed,
 * the default runtime based on Pyodide is used.
 */

export class PyConfig extends BaseEvalElement {
    widths: Array<string>;
    label: string;
    mount_name: string;
    details: HTMLElement;
    operation: HTMLElement;
    values: AppConfig;
    constructor() {
        super();
    }

    extractFromSrc() {
        if (this.hasAttribute('src'))
        {
            logger.info('config set from src attribute');
            return validateConfig(readTextFromPath(this.getAttribute('src')));
        }
        return {};
    }

    extractFromInline() {
        if (this.innerHTML!=='')
        {
            this.code = this.innerHTML;
            this.innerHTML = '';
            logger.info('config set from inline');
            return validateConfig(this.code);
        }
        return {};
    }

    injectMetadata() {
        this.values.pyscript = {
            "version": version,
            "time": new Date().toISOString()
        };
    }

    connectedCallback() {
        let srcConfig = this.extractFromSrc();
        const inlineConfig = this.extractFromInline();
        // first make config from src whole if it is partial
        srcConfig = mergeConfig(srcConfig, defaultConfig);
        // then merge inline config and config from src
        this.values = mergeConfig(inlineConfig, srcConfig);
        this.injectMetadata();