import { Expression, Instruction, InstructionType, Jump, ObjectData, ObjectDataType, PrimitiveData, Scope, Tag, XmlError } from '@cyklang/core' import loglevel from 'loglevel' const logger = loglevel.getLogger('GeoLocation') logger.setLevel('debug') export class GeoLocationInstructionType extends InstructionType { constructor() { super('geolocation') } async parseInstruction(tag: Tag, scope: Scope): Promise { return new GeoLocation(tag) } } class GeoLocation extends Instruction { constructor(tag: Tag) { super(tag) } async execute(scope: Scope): Promise { try { const into = this.tag.attributes.INTO if (!into) throw 'attribute INTO is missing' const express = new Expression(scope) const varinto = await express.LValue(into) if (!varinto) throw 'INTO variable ' + into + ' not found' if (varinto.dataType.isPrimitive()) throw 'INTO is ' + varinto.dataType.name + ' and should be an object' const object = new ObjectData(varinto.dataType as ObjectDataType, new Tag(''), scope) const varOk = object.variables.addVariable('ok', scope.structure.booleanDataType) const varError = object.variables.addVariable('error', scope.structure.stringDataType) const varLat = object.variables.addVariable('latitude', scope.structure.numberDataType) const varLon = object.variables.addVariable('longitude', scope.structure.numberDataType) const varAlt = object.variables.addVariable('altitude', scope.structure.numberDataType) varinto.data = object try { if (!("geolocation" in navigator)) throw 'geolocation is not in navigator' const position = await new Promise((resolve, reject) => { const watchId = navigator.geolocation.watchPosition((position) => { logger.debug('position: ', position) navigator.geolocation.clearWatch(watchId) resolve(position) }, (error) => { reject(String(error)) } ) }) varOk.data = scope.structure.trueData varLat.data = new PrimitiveData(scope.structure.numberDataType, position.coords.latitude) varLon.data = new PrimitiveData(scope.structure.numberDataType, position.coords.longitude) varAlt.data = new PrimitiveData(scope.structure.numberDataType, position.coords.altitude) } catch (err) { varOk.data = scope.structure.falseData varError.data = new PrimitiveData(scope.structure.stringDataType, String(err)) } } catch (err) { if (err instanceof XmlError) throw err throw new XmlError(String(err), this.tag) } } }