{"version":3,"sources":["../yjs/node_modules/browser-pack/_prelude.js","src/Map.js"],"names":[],"mappings":";;;;;;AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"y-map.es6","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})","/* global Y */\n'use strict'\n\nfunction extend (Y /* :any */) {\n  class YMap extends Y.utils.CustomType {\n    /* ::\n    _model: Id;\n    os: Y.AbstractDatabase;\n    map: Object;\n    contents: any;\n    opContents: Object;\n    eventHandler: Function;\n    */\n    constructor (os, model, contents, opContents) {\n      super()\n      this._model = model.id\n      this._parent = null\n      this._deepEventHandler = new Y.utils.EventListenerHandler()\n      this.os = os\n      this.map = Y.utils.copyObject(model.map)\n      this.contents = contents\n      this.opContents = opContents\n      this.eventHandler = new Y.utils.EventHandler(op => {\n        var oldValue\n        // key is the name to use to access (op)content\n        var key = op.struct === 'Delete' ? op.key : op.parentSub\n\n        // compute oldValue\n        if (this.opContents[key] != null) {\n          oldValue = this.os.getType(this.opContents[key])\n        } else {\n          oldValue = this.contents[key]\n        }\n        // compute op event\n        if (op.struct === 'Insert') {\n          if (op.left === null && !Y.utils.compareIds(op.id, this.map[key])) {\n            var value\n            // TODO: what if op.deleted??? I partially handles this case here.. but need to send delete event instead. somehow related to #4\n            if (op.opContent != null) {\n              value = this.os.getType(op.opContent)\n              value._parent = this._model\n              delete this.contents[key]\n              if (op.deleted) {\n                delete this.opContents[key]\n              } else {\n                this.opContents[key] = op.opContent\n              }\n            } else {\n              value = op.content[0]\n              delete this.opContents[key]\n              if (op.deleted) {\n                delete this.contents[key]\n              } else {\n                this.contents[key] = op.content[0]\n              }\n            }\n            this.map[key] = op.id\n            if (oldValue === undefined) {\n              Y.utils.bubbleEvent(this, {\n                name: key,\n                object: this,\n                type: 'add',\n                value: value\n              })\n            } else {\n              Y.utils.bubbleEvent(this, {\n                name: key,\n                object: this,\n                oldValue: oldValue,\n                type: 'update',\n                value: value\n              })\n            }\n          }\n        } else if (op.struct === 'Delete') {\n          if (Y.utils.compareIds(this.map[key], op.target)) {\n            delete this.opContents[key]\n            delete this.contents[key]\n            Y.utils.bubbleEvent(this, {\n              name: key,\n              object: this,\n              oldValue: oldValue,\n              type: 'delete'\n            })\n          }\n        } else {\n          throw new Error('Unexpected Operation!')\n        }\n      })\n    }\n    _getPathToChild (childId) {\n      return Object.keys(this.opContents).find(key =>\n        Y.utils.compareIds(this.opContents[key], childId)\n      )\n    }\n    _destroy () {\n      this.eventHandler.destroy()\n      this.eventHandler = null\n      this.contents = null\n      this.opContents = null\n      this._model = null\n      this._parent = null\n      this.os = null\n      this.map = null\n    }\n    get (key) {\n      // return property.\n      // if property does not exist, return null\n      // if property is a type, return it\n      if (key == null || typeof key !== 'string') {\n        throw new Error('You must specify a key (as string)!')\n      }\n      if (this.opContents[key] == null) {\n        return this.contents[key]\n      } else {\n        return this.os.getType(this.opContents[key])\n      }\n    }\n    keys () {\n      return Object.keys(this.contents).concat(Object.keys(this.opContents))\n    }\n    keysPrimitives () {\n      return Object.keys(this.contents)\n    }\n    keysTypes () {\n      return Object.keys(this.opContents)\n    }\n    /*\n      If there is a primitive (not a custom type), then return it.\n      Returns all primitive values, if propertyName is specified!\n      Note: modifying the return value could result in inconsistencies!\n        -- so make sure to copy it first!\n    */\n    getPrimitive (key) {\n      if (key == null) {\n        return Y.utils.copyObject(this.contents)\n      } else if (typeof key !== 'string') {\n        throw new Error('Key is expected to be a string!')\n      } else {\n        return this.contents[key]\n      }\n    }\n    getType (key) {\n      if (key == null || typeof key !== 'string') {\n        throw new Error('You must specify a key (as string)!')\n      } else if (this.opContents[key] != null) {\n        return this.os.getType(this.opContents[key])\n      } else {\n        return null\n      }\n    }\n    delete (key) {\n      var right = this.map[key]\n      if (right != null) {\n        var del = {\n          target: right,\n          struct: 'Delete'\n        }\n        var eventHandler = this.eventHandler\n        var modDel = Y.utils.copyObject(del)\n        modDel.key = key\n        this.os.requestTransaction(function *() {\n          yield* eventHandler.awaitOps(this, this.applyCreatedOperations, [[del]])\n        })\n        // always remember to do that after this.os.requestTransaction\n        // (otherwise values might contain a undefined reference to type)\n        eventHandler.awaitAndPrematurelyCall([modDel])\n      }\n    }\n    set (key, value) {\n      // set property.\n      // if property is a type, return it\n      // if not, apply immediately on this type an call event\n\n      var right = this.map[key] || null\n      var insert /* :any */ = {\n        id: this.os.getNextOpId(1),\n        left: null,\n        right: right,\n        origin: null,\n        parent: this._model,\n        parentSub: key,\n        struct: 'Insert'\n      }\n      var eventHandler = this.eventHandler\n      var typeDefinition = Y.utils.isTypeDefinition(value)\n      if (typeDefinition !== false) {\n        var type = this.os.createType(typeDefinition)\n        insert.opContent = type._model\n        // construct a new type\n        this.os.requestTransaction(function *() {\n          yield* eventHandler.awaitOps(this, this.applyCreatedOperations, [[insert]])\n        })\n        // always remember to do that after this.os.requestTransaction\n        // (otherwise values might contain a undefined reference to type)\n        eventHandler.awaitAndPrematurelyCall([insert])\n        return type\n      } else {\n        insert.content = [value]\n        this.os.requestTransaction(function * () {\n          yield* eventHandler.awaitOps(this, this.applyCreatedOperations, [[insert]])\n        })\n        // always remember to do that after this.os.requestTransaction\n        // (otherwise values might contain a undefined reference to type)\n        eventHandler.awaitAndPrematurelyCall([insert])\n        return value\n      }\n    }\n    observe (f) {\n      this.eventHandler.addEventListener(f)\n    }\n    observeDeep (f) {\n      this._deepEventHandler.addEventListener(f)\n    }\n    unobserve (f) {\n      this.eventHandler.removeEventListener(f)\n    }\n    unobserveDeep (f) {\n      this._deepEventHandler.removeEventListener(f)\n    }\n    /*\n      Observe a path.\n\n      E.g.\n      ```\n      o.set('textarea', Y.TextBind)\n      o.observePath(['textarea'], function(t){\n        // is called whenever textarea is replaced\n        t.bind(textarea)\n      })\n\n      returns a function that removes the observer from the path.\n    */\n    observePath (path, f) {\n      var self = this\n      var propertyName\n      function observeProperty (event) {\n        // call f whenever path changes\n        if (event.name === propertyName) {\n          // call this also for delete events!\n          f(self.get(propertyName))\n        }\n      }\n\n      if (path.length < 1) {\n        f(this)\n        return function () {}\n      } else if (path.length === 1) {\n        propertyName = path[0]\n        f(self.get(propertyName))\n        this.observe(observeProperty)\n        return function () {\n          self.unobserve(f)\n        }\n      } else {\n        var deleteChildObservers\n        var resetObserverPath = function () {\n          var map = self.get(path[0])\n          if (!(map instanceof YMap)) {\n            // its either not defined or a primitive value / not a map\n            map = self.set(path[0], Y.Map)\n          }\n          deleteChildObservers = map.observePath(path.slice(1), f)\n        }\n        var observer = function (event) {\n          if (event.name === path[0]) {\n            if (deleteChildObservers != null) {\n              deleteChildObservers()\n            }\n            if (event.type === 'add' || event.type === 'update') {\n              resetObserverPath()\n            }\n            // TODO: what about the delete events?\n          }\n        }\n        self.observe(observer)\n        resetObserverPath()\n        // returns a function that deletes all the child observers\n        // and how to unobserve the observe from this object\n        return function () {\n          if (deleteChildObservers != null) {\n            deleteChildObservers()\n          }\n          self.unobserve(observer)\n        }\n      }\n    }\n    * _changed (transaction, op) {\n      if (op.struct === 'Delete') {\n        if (op.key == null) {\n          var target = yield* transaction.getOperation(op.target)\n          op.key = target.parentSub\n        }\n      } else if (op.opContent != null) {\n        yield* transaction.store.initType.call(transaction, op.opContent)\n      }\n      this.eventHandler.receivedOp(op)\n    }\n  }\n  Y.extend('Map', new Y.utils.CustomTypeDefinition({\n    name: 'Map',\n    class: YMap,\n    struct: 'Map',\n    initType: function * YMapInitializer (os, model) {\n      var contents = {}\n      var opContents = {}\n      var map = model.map\n      for (var name in map) {\n        var op = yield* this.getOperation(map[name])\n        if (op.deleted) continue\n        if (op.opContent != null) {\n          opContents[name] = op.opContent\n          var type = yield* this.store.initType.call(this, op.opContent)\n          type._parent = model.id\n        } else {\n          contents[name] = op.content[0]\n        }\n      }\n      return new YMap(os, model, contents, opContents)\n    },\n    createType: function YMapCreator (os, model) {\n      return new YMap(os, model, {}, {})\n    }\n  }))\n}\n\nmodule.exports = extend\nif (typeof Y !== 'undefined') {\n  extend(Y)\n}\n"]}