{"version":3,"sources":["https://lively-kernel.org/lively4/lively4-RP19-4/src/client/vivide/vividescriptstep.js"],"names":["boundEval","uuid","functionMetaInfo","stepFolder","VivideObject","ScriptProcessor","computeModel","data","startingStep","_modules","transform","extract","descentStep","applyUntil","step","callback","shouldContinue","getNextExecutionStep","s","type","applyStep","hasNextExecutionStep","transformedForest","processData","fn","config","getExecutable","push","prepareDescent","asList","d","undefined","Array","isArray","flatten","result","forEach","singleTransform","module","Promise","all","toArray","input","slice","dataToForest","forest","model","properties","add","object","descentObject","childData","ScriptStep","constructor","source","id","json","cursor","route","_prevLinearStep","_nextLinearStep","_loopTargetStep","getCursorPosition","anchor","head","console","warn","line","ch","setCursorPosition","getRoute","setRoute","removeLoopTargetStep","setLoopTargetStep","find","condition","found","iterateLinear","cb","iterateLinearAsync","insertAfter","stepToBeInserted","nextStep","remove","prevStep","insertAsLastStep","lastStep","getLastStep","setScript","script","_script","update","lively","notify","gotUpdated","toJSO","scriptJson","toJSON","JSON","stringify","value","newFromTemplate","stepTemplateURL","URL","stepTemplate","fetch","then","r","newFromJSON","document","querySelectorAll","vv","myCurrentScript","stepsAsArray","migrateTo","__proto__","prototype"],"mappings":"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","file":"vividescriptstep.js","sourcesContent":["import boundEval from \"src/client/bound-eval.js\";\nimport { uuid, functionMetaInfo } from 'utils';\nimport { stepFolder } from 'src/client/vivide/utils.js';\n\nimport VivideObject from 'src/client/vivide/vivideobject.js';\n\nexport class ScriptProcessor {\n\n  async computeModel(data, startingStep) {\n    const _modules = {\n      transform: [],\n      extract: []\n    };\n    let descentStep;\n    \n    async function applyUntil(step, callback, shouldContinue) {\n      if(!step) { return; }\n\n      await callback(step);\n\n      if(shouldContinue(step)) {\n        await applyUntil(step.getNextExecutionStep(), callback, shouldContinue);\n      }\n    }\n\n    await applyUntil(\n      startingStep,\n      async s => {\n        if(s.type === 'descent') {\n          descentStep = s;\n        } else {\n          await this.applyStep(s, _modules);\n        }\n      },\n      s => s.type !== 'descent' && s.hasNextExecutionStep()\n    );\n\n    const transformedForest = await this.processData(data, _modules, descentStep);\n    return transformedForest;\n  }\n\n  async applyStep(step, _modules) {\n    const [fn, config] = await step.getExecutable();\n    _modules[step.type].push(fn);\n  }\n\n  async processData(data, _modules, descentStep) {\n    const transformedForest = await this.transform(data, _modules);\n    await this.extract(transformedForest, _modules);\n    await this.prepareDescent(transformedForest, descentStep);\n    \n    return transformedForest;\n  }\n  \n  // Vivide/S's asList\n  asList(d) {\n    if(d === undefined) {\n      // pass\n      return [];\n    } else if(Array.isArray(d)) {\n      return d;\n    } else {\n      // normal singular object\n      return [d];\n    }\n  }\n  // #TODO: use Array::flatten native function\n  flatten(data) {\n    let result = [];\n\n    data.forEach(d => result.push(...this.asList(d)));\n    \n    return result;\n  }\n  \n  async singleTransform(data, module) {\n    return await Promise.all(await module.toArray(data));\n  }\n  async transform(data, _modules) {\n    let input = data.slice(0);\n    \n    for (let module of _modules.transform) {\n      input = await this.singleTransform(input, module);\n      input = this.flatten(input);\n    }\n\n    return VivideObject.dataToForest(input);\n  }\n  \n  async extract(forest, _modules) {\n    for (let module of _modules.extract) {\n      for (let model of forest) {\n        model.properties.add(await module(model.object));\n      }\n    }\n  }\n  \n  async prepareDescent(forest, descentStep) {\n    for (let model of forest) {\n      model.descentStep = descentStep;\n    }\n  }\n  \n  async descentObject(object, descentStep) {\n    const [fn, config] = await descentStep.getExecutable();\n    const childData = await fn(object);\n    return this.computeModel(childData, descentStep.getNextExecutionStep());\n  }\n}\n\nexport default class ScriptStep {\n  constructor(source, type, id = null, json) {\n    this.id = id != null ? id : uuid();\n    this.source = source;\n    this.type = type;\n    this.cursor = json ? json.cursor : undefined;\n    this.route = json ? json.route : undefined;\n    \n    this._prevLinearStep = undefined;\n    this._nextLinearStep = undefined;\n    this._loopTargetStep = undefined;\n  }\n  \n  getCursorPosition() {\n    if(this.cursor) {\n      return [this.cursor.anchor, this.cursor.head];\n    }\n    // #TODO is it important to persists cursor position, and should we restore it?\n    console.warn('no cursor available', 'fallback for default cursor position');\n    return [{ line: 1, ch: 0}, { line: 1, ch: 0}];\n  }\n  setCursorPosition(anchor, head) {\n    this.cursor = { anchor, head };\n  }\n  \n  getRoute() {\n    return this.route && this.route.slice();\n  }\n  setRoute(route) {\n    this.route = route.slice();\n  }\n  \n  // rename to ComputationalStep\n  hasNextExecutionStep() { return !!this.getNextExecutionStep(); }\n  getNextExecutionStep() { return this._nextLinearStep || this._loopTargetStep; }\n  \n  removeLoopTargetStep() {\n    this._loopTargetStep = undefined;\n  }\n  setLoopTargetStep(step) {\n    this._loopTargetStep = step;\n  }\n  \n  find(condition) {\n    let found;\n    \n    this.iterateLinear(step => {\n      if(!found && condition(step)) {\n        found = step;\n      }\n    });\n    \n    return found;\n  }\n  \n  iterateLinear(cb) {\n    cb(this);\n    \n    if(this._nextLinearStep) {\n      this._nextLinearStep.iterateLinear(cb);\n    }\n  }\n  \n  // #TODO: remove duplicate\n  async iterateLinearAsync(cb) {\n    await cb(this);\n    \n    if(this._nextLinearStep) {\n      await this._nextLinearStep.iterateLinearAsync(cb);\n    }\n  }\n  \n  insertAfter(stepToBeInserted) {\n    const nextStep = this._nextLinearStep;\n    this._nextLinearStep = stepToBeInserted;\n    stepToBeInserted._nextLinearStep = nextStep;\n    if(nextStep) {\n      nextStep._prevLinearStep = stepToBeInserted;\n    }\n    stepToBeInserted._prevLinearStep = this;\n\n    if(this._loopTargetStep) {\n      stepToBeInserted._loopTargetStep = this._loopTargetStep;\n      this._loopTargetStep = undefined;\n    }\n  }\n  \n  remove() {\n    const prevStep = this._prevLinearStep;\n    const nextStep = this._nextLinearStep;\n\n    if(prevStep) {\n      prevStep._nextLinearStep = nextStep;\n    }\n    if(nextStep) {\n      nextStep._prevLinearStep = prevStep;\n    }\n    \n    if(this._loopTargetStep && prevStep) {\n      prevStep._loopTargetStep = this._loopTargetStep;\n      this._loopTargetStep = undefined;\n    }\n  }\n  \n  insertAsLastStep(step) {\n    const lastStep = this.getLastStep();\n    lastStep.insertAfter(step);\n  }\n  \n  getLastStep() {\n    let step = this;\n    while (step._nextLinearStep) {\n      step = step._nextLinearStep;\n    }\n    \n    return step;\n  }\n  \n  setScript(script) { this._script = script; }\n  update() {\n    lively.notify('VivideStep::update')\n    this._script.gotUpdated();\n  }\n  async processData(childData) {\n    return new ScriptProcessor().computeModel(childData, this);\n  }\n  async descentObject(object) {\n    return new ScriptProcessor().descentObject(object, this);\n  }\n  \n  // #TODO: implement properly\n  toJSO() {\n    const scriptJson = {\n      type: this.type,\n      source: this.source,\n      cursor: this.cursor,\n      route: this.route\n    };\n    \n    // #TODO: maybe need to save next step id or loop target\n    \n    return scriptJson\n  }\n  \n  toJSON() {\n    return JSON.stringify(this.toJSO())\n  }\n  \n  async getExecutable() {\n    const module = await boundEval(this.source);\n    \n    return module.value;\n  }\n  \n  static async newFromTemplate(type) {\n    const stepTemplateURL = new URL(type + '-step-template.json', stepFolder);\n    const stepTemplate = await fetch(stepTemplateURL).then(r => r.json());\n\n    return this.newFromJSON(stepTemplate);\n  }\n  \n  static newFromJSON(json) {\n    return new ScriptStep(json.script, json.type, undefined, json);\n  }\n}\n\n// #UPDATE_INSTANCES\n// #TODO: idea: using a list of all object, we can make them become anew\n// go through all object reachable from window\ndocument.querySelectorAll(\"vivide-view\").forEach(vv => {\n  if(!vv.myCurrentScript) { return; }\n\n  vv.myCurrentScript.stepsAsArray().forEach(s => {\n    s.migrateTo(ScriptStep);\n    s.__proto__ = ScriptStep.prototype;\n  });\n})\n"]}