import { Expression, Instruction, InstructionType, Jump, Scope, Tag, XmlError, xmlFormat, parseXML } from "@cyklang/core"; import loglevel from 'loglevel' const logger = loglevel.getLogger('LocalStorage') logger.setLevel('debug') export class LocalStorageInstructionType extends InstructionType { constructor() { super('localstorage') } async parseInstruction(tag: Tag, scope: Scope): Promise { return new LocalStorageInstruction(tag) } } class LocalStorageInstruction extends Instruction { constructor(tag: Tag) { super(tag) } async execute(scope: Scope): Promise { try { if (this.tag.attributes.READ_INTO) { await getItem(scope, this.tag.attributes.NAME, this.tag.attributes.READ_INTO) } else if (this.tag.attributes.WRITE_FROM) { await setItem(scope, this.tag.attributes.NAME, this.tag.attributes.WRITE_FROM) } else { throw 'one of read_into or write_from attribute is mandatory' } } catch (err) { if (err instanceof XmlError) throw err throw new XmlError(String(err), this.tag) } } } /** * * @param scope * @param name * @param read_into */ async function getItem(scope: Scope, name: string, read_into: string) { try { const express = new Expression(scope) const varinto = await express.LValue(read_into) if (!varinto) throw 'READ_INTO variable ' + read_into + ' not found ' const item = localStorage.getItem(name) if (item === null) return const tagItem = parseXML('READ_INTO', item) const data = await varinto.dataType.parseData(tagItem, scope) varinto.data = data } catch (err) { logger.error(err) } } /** * * @param scope * @param name * @param write_from */ async function setItem(scope: Scope, name: string, write_from: string) { const express = new Expression(scope) const data = await express.evaluate(write_from) if (data === undefined || data === null) { localStorage.removeItem(name) } else { const xml = xmlFormat(data) localStorage.setItem(name, xml) } }