[
  {
    "__docId__": 0,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/attributes/attribute-boolean.js",
    "memberof": null,
    "longname": "lib/attributes/attribute-boolean.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import Attribute from './attribute';\n\n/**\nThe value of this attribute is always a boolean. Null values are coerced to false.\n\nString attributes can be queries using `equal` and `not`. Matching on\n`greaterThan` and `lessThan` is not supported.\n*/\nexport default class AttributeBoolean extends Attribute {\n  toJSON(val) {\n    return val;\n  }\n  fromJSON(val) {\n    return ((val === 'true') || (val === true)) || false;\n  }\n  columnSQL() {\n    return `${this.jsonKey} INTEGER`;\n  }\n}\n"
  },
  {
    "__docId__": 1,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "AttributeBoolean",
    "memberof": "lib/attributes/attribute-boolean.js",
    "longname": "lib/attributes/attribute-boolean.js~AttributeBoolean",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/attributes/attribute-boolean.js",
    "importStyle": "AttributeBoolean",
    "description": "The value of this attribute is always a boolean. Null values are coerced to false.\n\nString attributes can be queries using `equal` and `not`. Matching on\n`greaterThan` and `lessThan` is not supported.",
    "lineNumber": 9,
    "interface": false,
    "extends": [
      "lib/attributes/attribute.js~Attribute"
    ]
  },
  {
    "__docId__": 2,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "toJSON",
    "memberof": "lib/attributes/attribute-boolean.js~AttributeBoolean",
    "longname": "lib/attributes/attribute-boolean.js~AttributeBoolean#toJSON",
    "access": null,
    "description": null,
    "lineNumber": 10,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 3,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "fromJSON",
    "memberof": "lib/attributes/attribute-boolean.js~AttributeBoolean",
    "longname": "lib/attributes/attribute-boolean.js~AttributeBoolean#fromJSON",
    "access": null,
    "description": null,
    "lineNumber": 13,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 4,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "columnSQL",
    "memberof": "lib/attributes/attribute-boolean.js~AttributeBoolean",
    "longname": "lib/attributes/attribute-boolean.js~AttributeBoolean#columnSQL",
    "access": null,
    "description": null,
    "lineNumber": 16,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 5,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/attributes/attribute-collection.js",
    "memberof": null,
    "longname": "lib/attributes/attribute-collection.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import Attribute from './attribute';\nimport Matcher from './matcher';\n\n/**\nCollection attributes provide basic support for one-to-many relationships.\nFor example, Threads in N1 have a collection of Labels or Folders.\n\nWhen Collection attributes are marked as `queryable`, the RxDatabase\nautomatically creates a join table and maintains it as you create, save,\nand delete models. When you call `persistModel`, entries are added to the\njoin table associating the ID of the model with the IDs of models in the collection.\n\nCollection attributes have an additional clause builder, `contains`:\n\n```coffee\ndb.findAll(Thread).where([Thread.attributes.categories.contains('inbox')])\n```\n\nThis is equivalent to writing the following SQL:\n\n```sql\nSELECT `Thread`.`data` FROM `Thread`\nINNER JOIN `ThreadLabel` AS `M1` ON `M1`.`id` = `Thread`.`id`\nWHERE `M1`.`value` = 'inbox'\nORDER BY `Thread`.`last_message_received_timestamp` DESC\n```\n\nThe value of this attribute is always an array of other model objects.\n\nSection: Database\n*/\nexport default class AttributeCollection extends Attribute {\n  constructor({modelKey, jsonKey, itemClass, joinOnField, joinQueryableBy, queryable}) {\n    super({modelKey, jsonKey, queryable});\n    this.ItemClass = this.itemClass = itemClass;\n    this.joinOnField = joinOnField;\n    this.joinQueryableBy = joinQueryableBy || [];\n  }\n\n  toJSON(vals) {\n    if (!vals) {\n      return [];\n    }\n\n    if (!(vals instanceof Array)) {\n      throw new Error(`AttributeCollection::toJSON: ${this.modelKey} is not an array.`);\n    }\n\n    const json = []\n    for (const val of vals) {\n      if (!(val instanceof this.ItemClass)) {\n        throw new Error(`AttributeCollection::toJSON: Value \\`${val}\\` in ${this.modelKey} is not an ${this.ItemClass.name}`);\n      }\n      if (val.toJSON !== undefined) {\n        json.push(val.toJSON());\n      } else {\n        json.push(val);\n      }\n    }\n    return json;\n  }\n\n  fromJSON(json) {\n    if (!json || !(json instanceof Array)) {\n      return [];\n    }\n    const objs = [];\n\n    for (const objJSON of json) {\n      // Note: It's possible for a malformed API request to return an array\n      // of null values. N1 is tolerant to this type of error, but shouldn't\n      // happen on the API end.\n      if (!objJSON) {\n        continue;\n      }\n\n      if (this.ItemClass.prototype.fromJSON) {\n        const obj = new this.ItemClass();\n        // Important: if no ids are in the JSON, don't make them up\n        // randomly.  This causes an object to be \"different\" each time it's\n        // de-serialized even if it's actually the same, makes React\n        // components re-render!\n        obj.id = undefined;\n        obj.fromJSON(objJSON);\n        objs.push(obj);\n      } else {\n        const obj = new this.ItemClass(objJSON);\n        obj.id = undefined;\n        objs.push(obj);\n      }\n    }\n    return objs;\n  }\n\n  /**\n  @returns {Matcher} - Matcher for objects containing the provided value.\n  */\n  contains(val) {\n    this._assertPresentAndQueryable('contains', val);\n    return new Matcher(this, 'contains', val);\n  }\n\n  containsAny(vals) {\n    this._assertPresentAndQueryable('contains', vals);\n    return new Matcher(this, 'containsAny', vals);\n  }\n}\n"
  },
  {
    "__docId__": 6,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "AttributeCollection",
    "memberof": "lib/attributes/attribute-collection.js",
    "longname": "lib/attributes/attribute-collection.js~AttributeCollection",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/attributes/attribute-collection.js",
    "importStyle": "AttributeCollection",
    "description": "Collection attributes provide basic support for one-to-many relationships.\nFor example, Threads in N1 have a collection of Labels or Folders.\n\nWhen Collection attributes are marked as `queryable`, the RxDatabase\nautomatically creates a join table and maintains it as you create, save,\nand delete models. When you call `persistModel`, entries are added to the\njoin table associating the ID of the model with the IDs of models in the collection.\n\nCollection attributes have an additional clause builder, `contains`:\n\n```coffee\ndb.findAll(Thread).where([Thread.attributes.categories.contains('inbox')])\n```\n\nThis is equivalent to writing the following SQL:\n\n```sql\nSELECT `Thread`.`data` FROM `Thread`\nINNER JOIN `ThreadLabel` AS `M1` ON `M1`.`id` = `Thread`.`id`\nWHERE `M1`.`value` = 'inbox'\nORDER BY `Thread`.`last_message_received_timestamp` DESC\n```\n\nThe value of this attribute is always an array of other model objects.\n\nSection: Database",
    "lineNumber": 32,
    "interface": false,
    "extends": [
      "lib/attributes/attribute.js~Attribute"
    ]
  },
  {
    "__docId__": 7,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/attributes/attribute-collection.js~AttributeCollection",
    "longname": "lib/attributes/attribute-collection.js~AttributeCollection#constructor",
    "access": null,
    "description": null,
    "lineNumber": 33,
    "undocument": true,
    "params": [
      {
        "name": "objectPattern",
        "types": [
          "{\"modelKey\": *, \"jsonKey\": *, \"itemClass\": *, \"joinOnField\": *, \"joinQueryableBy\": *, \"queryable\": *}"
        ],
        "defaultRaw": {
          "modelKey": null,
          "jsonKey": null,
          "itemClass": null,
          "joinOnField": null,
          "joinQueryableBy": null,
          "queryable": null
        },
        "defaultValue": "{\"modelKey\":null,\"jsonKey\":null,\"itemClass\":null,\"joinOnField\":null,\"joinQueryableBy\":null,\"queryable\":null}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 8,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "ItemClass",
    "memberof": "lib/attributes/attribute-collection.js~AttributeCollection",
    "longname": "lib/attributes/attribute-collection.js~AttributeCollection#ItemClass",
    "access": null,
    "description": null,
    "lineNumber": 35,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 9,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "joinOnField",
    "memberof": "lib/attributes/attribute-collection.js~AttributeCollection",
    "longname": "lib/attributes/attribute-collection.js~AttributeCollection#joinOnField",
    "access": null,
    "description": null,
    "lineNumber": 36,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 10,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "joinQueryableBy",
    "memberof": "lib/attributes/attribute-collection.js~AttributeCollection",
    "longname": "lib/attributes/attribute-collection.js~AttributeCollection#joinQueryableBy",
    "access": null,
    "description": null,
    "lineNumber": 37,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 11,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "toJSON",
    "memberof": "lib/attributes/attribute-collection.js~AttributeCollection",
    "longname": "lib/attributes/attribute-collection.js~AttributeCollection#toJSON",
    "access": null,
    "description": null,
    "lineNumber": 40,
    "undocument": true,
    "params": [
      {
        "name": "vals",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 12,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "fromJSON",
    "memberof": "lib/attributes/attribute-collection.js~AttributeCollection",
    "longname": "lib/attributes/attribute-collection.js~AttributeCollection#fromJSON",
    "access": null,
    "description": null,
    "lineNumber": 63,
    "undocument": true,
    "params": [
      {
        "name": "json",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 13,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "contains",
    "memberof": "lib/attributes/attribute-collection.js~AttributeCollection",
    "longname": "lib/attributes/attribute-collection.js~AttributeCollection#contains",
    "access": null,
    "description": "",
    "lineNumber": 98,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Matcher} - Matcher for objects containing the provided value."
      }
    ],
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Matcher"
      ],
      "spread": false,
      "description": "Matcher for objects containing the provided value."
    },
    "generator": false
  },
  {
    "__docId__": 14,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "containsAny",
    "memberof": "lib/attributes/attribute-collection.js~AttributeCollection",
    "longname": "lib/attributes/attribute-collection.js~AttributeCollection#containsAny",
    "access": null,
    "description": null,
    "lineNumber": 103,
    "undocument": true,
    "params": [
      {
        "name": "vals",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 15,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/attributes/attribute-datetime.js",
    "memberof": null,
    "longname": "lib/attributes/attribute-datetime.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import Attribute from './attribute';\nimport Matcher from './matcher';\n\n/**\nThe value of this attribute is always a Javascript `Date`, or `null`.\n*/\nexport default class AttributeDateTime extends Attribute {\n  toJSON(val) {\n    if (!val) {\n      return null;\n    }\n    if (!(val instanceof Date)) {\n      throw new Error(`Attempting to toJSON AttributeDateTime which is not a date: ${this.modelKey} = ${val}`);\n    }\n    return val.getTime() / 1000.0;\n  }\n\n  fromJSON(val) {\n    return val ? new Date(val * 1000) : null;\n  }\n\n  columnSQL() {\n    return `${this.jsonKey} INTEGER`;\n  }\n\n  /**\n  @returns {Matcher} - Matcher for objects greater than the provided value.\n  */\n  greaterThan(val) {\n    this._assertPresentAndQueryable('greaterThan', val);\n    return new Matcher(this, '>', val)\n  }\n\n  /**\n  @returns {Matcher} - Matcher for objects less than the provided value.\n  */\n  lessThan(val) {\n    this._assertPresentAndQueryable('lessThan', val);\n    return new Matcher(this, '<', val);\n  }\n\n  /**\n  @returns {Matcher} - Matcher for objects greater than or equal to the provided value.\n  */\n  greaterThanOrEqualTo(val) {\n    this._assertPresentAndQueryable('greaterThanOrEqualTo', val);\n    return new Matcher(this, '>=', val);\n  }\n\n  /**\n  @returns {Matcher} - Matcher for objects less than or equal to the provided value.\n  */\n  lessThanOrEqualTo(val) {\n    this._assertPresentAndQueryable('lessThanOrEqualTo', val);\n    return new Matcher(this, '<=', val);\n  }\n\n  gt = AttributeDateTime.greaterThan;\n  lt = AttributeDateTime.lessThan;\n  gte = AttributeDateTime.greaterThanOrEqualTo;\n  lte = AttributeDateTime.lessThanOrEqualTo;\n}\n"
  },
  {
    "__docId__": 16,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "AttributeDateTime",
    "memberof": "lib/attributes/attribute-datetime.js",
    "longname": "lib/attributes/attribute-datetime.js~AttributeDateTime",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/attributes/attribute-datetime.js",
    "importStyle": "AttributeDateTime",
    "description": "The value of this attribute is always a Javascript `Date`, or `null`.",
    "lineNumber": 7,
    "interface": false,
    "extends": [
      "lib/attributes/attribute.js~Attribute"
    ]
  },
  {
    "__docId__": 17,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "toJSON",
    "memberof": "lib/attributes/attribute-datetime.js~AttributeDateTime",
    "longname": "lib/attributes/attribute-datetime.js~AttributeDateTime#toJSON",
    "access": null,
    "description": null,
    "lineNumber": 8,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 18,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "fromJSON",
    "memberof": "lib/attributes/attribute-datetime.js~AttributeDateTime",
    "longname": "lib/attributes/attribute-datetime.js~AttributeDateTime#fromJSON",
    "access": null,
    "description": null,
    "lineNumber": 18,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 19,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "columnSQL",
    "memberof": "lib/attributes/attribute-datetime.js~AttributeDateTime",
    "longname": "lib/attributes/attribute-datetime.js~AttributeDateTime#columnSQL",
    "access": null,
    "description": null,
    "lineNumber": 22,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 20,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "greaterThan",
    "memberof": "lib/attributes/attribute-datetime.js~AttributeDateTime",
    "longname": "lib/attributes/attribute-datetime.js~AttributeDateTime#greaterThan",
    "access": null,
    "description": "",
    "lineNumber": 29,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Matcher} - Matcher for objects greater than the provided value."
      }
    ],
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Matcher"
      ],
      "spread": false,
      "description": "Matcher for objects greater than the provided value."
    },
    "generator": false
  },
  {
    "__docId__": 21,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "lessThan",
    "memberof": "lib/attributes/attribute-datetime.js~AttributeDateTime",
    "longname": "lib/attributes/attribute-datetime.js~AttributeDateTime#lessThan",
    "access": null,
    "description": "",
    "lineNumber": 37,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Matcher} - Matcher for objects less than the provided value."
      }
    ],
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Matcher"
      ],
      "spread": false,
      "description": "Matcher for objects less than the provided value."
    },
    "generator": false
  },
  {
    "__docId__": 22,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "greaterThanOrEqualTo",
    "memberof": "lib/attributes/attribute-datetime.js~AttributeDateTime",
    "longname": "lib/attributes/attribute-datetime.js~AttributeDateTime#greaterThanOrEqualTo",
    "access": null,
    "description": "",
    "lineNumber": 45,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Matcher} - Matcher for objects greater than or equal to the provided value."
      }
    ],
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Matcher"
      ],
      "spread": false,
      "description": "Matcher for objects greater than or equal to the provided value."
    },
    "generator": false
  },
  {
    "__docId__": 23,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "lessThanOrEqualTo",
    "memberof": "lib/attributes/attribute-datetime.js~AttributeDateTime",
    "longname": "lib/attributes/attribute-datetime.js~AttributeDateTime#lessThanOrEqualTo",
    "access": null,
    "description": "",
    "lineNumber": 53,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Matcher} - Matcher for objects less than or equal to the provided value."
      }
    ],
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Matcher"
      ],
      "spread": false,
      "description": "Matcher for objects less than or equal to the provided value."
    },
    "generator": false
  },
  {
    "__docId__": 24,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/attributes/attribute-joined-data.js",
    "memberof": null,
    "longname": "lib/attributes/attribute-joined-data.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import Attribute from './attribute';\n\nconst NullPlaceholder = \"!NULLVALUE!\";\n\n/**\nJoined Data attributes allow you to store certain attributes of an\nobject in a separate table in the database. We use this attribute\ntype for Message bodies. Storing message bodies, which can be very\nlarge, in a separate table allows us to make queries on message\nmetadata extremely fast, and inflate Message objects without their\nbodies to build the thread list.\n\nWhen building a query on a model with a JoinedData attribute, you need\nto call `include` to explicitly load the joined data attribute.\nThe query builder will automatically perform a `LEFT OUTER JOIN` with\nthe secondary table to retrieve the attribute:\n\n```coffee\ndb.find(Message, '123').then (message) ->\n  // message.body is undefined\n\ndb.find(Message, '123').include(Message.attributes.body).then (message) ->\n  // message.body is defined\n```\n\nWhen you call `persistModel`, JoinedData attributes are automatically\nwritten to the secondary table.\n\nJoinedData attributes cannot be `queryable`.\n\nSection: Database\n*/\nexport default class AttributeJoinedData extends Attribute {\n  static NullPlaceholder = NullPlaceholder;\n\n  constructor({modelKey, jsonKey, modelTable, queryable}) {\n    super({modelKey, jsonKey, queryable});\n    this.modelTable = modelTable;\n  }\n\n  toJSON(val) {\n    return val;\n  }\n\n  fromJSON(val) {\n    return (val === null || val === undefined || val === false) ? null : `${val}`;\n  }\n\n  selectSQL() {\n    // NullPlaceholder is necessary because if the LEFT JOIN returns nothing, it leaves the field\n    // blank, and it comes through in the result row as \"\" rather than NULL\n    return `IFNULL(\\`${this.modelTable}\\`.\\`value\\`, '${NullPlaceholder}') AS \\`${this.modelKey}\\``;\n  }\n\n  includeSQL(klass) {\n    return `LEFT OUTER JOIN \\`${this.modelTable}\\` ON \\`${this.modelTable}\\`.\\`id\\` = \\`${klass.name}\\`.\\`id\\``;\n  }\n}\n"
  },
  {
    "__docId__": 25,
    "kind": "variable",
    "static": true,
    "variation": null,
    "name": "NullPlaceholder",
    "memberof": "lib/attributes/attribute-joined-data.js",
    "longname": "lib/attributes/attribute-joined-data.js~NullPlaceholder",
    "access": null,
    "export": false,
    "importPath": "electron-coresqlite/lib/attributes/attribute-joined-data.js",
    "importStyle": null,
    "description": null,
    "lineNumber": 3,
    "undocument": true,
    "type": {
      "types": [
        "string"
      ]
    }
  },
  {
    "__docId__": 26,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "AttributeJoinedData",
    "memberof": "lib/attributes/attribute-joined-data.js",
    "longname": "lib/attributes/attribute-joined-data.js~AttributeJoinedData",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/attributes/attribute-joined-data.js",
    "importStyle": "AttributeJoinedData",
    "description": "Joined Data attributes allow you to store certain attributes of an\nobject in a separate table in the database. We use this attribute\ntype for Message bodies. Storing message bodies, which can be very\nlarge, in a separate table allows us to make queries on message\nmetadata extremely fast, and inflate Message objects without their\nbodies to build the thread list.\n\nWhen building a query on a model with a JoinedData attribute, you need\nto call `include` to explicitly load the joined data attribute.\nThe query builder will automatically perform a `LEFT OUTER JOIN` with\nthe secondary table to retrieve the attribute:\n\n```coffee\ndb.find(Message, '123').then (message) ->\n// message.body is undefined\n\ndb.find(Message, '123').include(Message.attributes.body).then (message) ->\n// message.body is defined\n```\n\nWhen you call `persistModel`, JoinedData attributes are automatically\nwritten to the secondary table.\n\nJoinedData attributes cannot be `queryable`.\n\nSection: Database",
    "lineNumber": 33,
    "interface": false,
    "extends": [
      "lib/attributes/attribute.js~Attribute"
    ]
  },
  {
    "__docId__": 27,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/attributes/attribute-joined-data.js~AttributeJoinedData",
    "longname": "lib/attributes/attribute-joined-data.js~AttributeJoinedData#constructor",
    "access": null,
    "description": null,
    "lineNumber": 36,
    "undocument": true,
    "params": [
      {
        "name": "objectPattern",
        "types": [
          "{\"modelKey\": *, \"jsonKey\": *, \"modelTable\": *, \"queryable\": *}"
        ],
        "defaultRaw": {
          "modelKey": null,
          "jsonKey": null,
          "modelTable": null,
          "queryable": null
        },
        "defaultValue": "{\"modelKey\":null,\"jsonKey\":null,\"modelTable\":null,\"queryable\":null}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 28,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "modelTable",
    "memberof": "lib/attributes/attribute-joined-data.js~AttributeJoinedData",
    "longname": "lib/attributes/attribute-joined-data.js~AttributeJoinedData#modelTable",
    "access": null,
    "description": null,
    "lineNumber": 38,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 29,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "toJSON",
    "memberof": "lib/attributes/attribute-joined-data.js~AttributeJoinedData",
    "longname": "lib/attributes/attribute-joined-data.js~AttributeJoinedData#toJSON",
    "access": null,
    "description": null,
    "lineNumber": 41,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 30,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "fromJSON",
    "memberof": "lib/attributes/attribute-joined-data.js~AttributeJoinedData",
    "longname": "lib/attributes/attribute-joined-data.js~AttributeJoinedData#fromJSON",
    "access": null,
    "description": null,
    "lineNumber": 45,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 31,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "selectSQL",
    "memberof": "lib/attributes/attribute-joined-data.js~AttributeJoinedData",
    "longname": "lib/attributes/attribute-joined-data.js~AttributeJoinedData#selectSQL",
    "access": null,
    "description": null,
    "lineNumber": 49,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 32,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "includeSQL",
    "memberof": "lib/attributes/attribute-joined-data.js~AttributeJoinedData",
    "longname": "lib/attributes/attribute-joined-data.js~AttributeJoinedData#includeSQL",
    "access": null,
    "description": null,
    "lineNumber": 55,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 33,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/attributes/attribute-number.js",
    "memberof": null,
    "longname": "lib/attributes/attribute-number.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import Attribute from './attribute';\nimport Matcher from './matcher';\n\n/**\nThe value of this attribute is always a number, or null.\n*/\nexport default class AttributeNumber extends Attribute {\n  toJSON(val) {\n    return val;\n  }\n\n  fromJSON(val) {\n    return isNaN(val) ? null : Number(val);\n  }\n\n  columnSQL() {\n    return `${this.jsonKey} INTEGER`;\n  }\n\n  // Public: Returns a {Matcher} for objects greater than the provided value.\n  greaterThan(val) {\n    this._assertPresentAndQueryable('greaterThan', val);\n    return new Matcher(this, '>', val);\n  }\n\n  // Public: Returns a {Matcher} for objects less than the provided value.\n  lessThan(val) {\n    this._assertPresentAndQueryable('lessThan', val);\n    return new Matcher(this, '<', val);\n  }\n\n  // Public: Returns a {Matcher} for objects greater than the provided value.\n  greaterThanOrEqualTo(val) {\n    this._assertPresentAndQueryable('greaterThanOrEqualTo', val);\n    return new Matcher(this, '>=', val);\n  }\n\n  // Public: Returns a {Matcher} for objects less than the provided value.\n  lessThanOrEqualTo(val) {\n    this._assertPresentAndQueryable('lessThanOrEqualTo', val);\n    return new Matcher(this, '<=', val);\n  }\n\n  gt = AttributeNumber.prototype.greaterThan;\n  lt = AttributeNumber.prototype.lessThan;\n  gte = AttributeNumber.prototype.greaterThanOrEqualTo;\n  lte = AttributeNumber.prototype.lessThanOrEqualTo;\n}\n"
  },
  {
    "__docId__": 34,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "AttributeNumber",
    "memberof": "lib/attributes/attribute-number.js",
    "longname": "lib/attributes/attribute-number.js~AttributeNumber",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/attributes/attribute-number.js",
    "importStyle": "AttributeNumber",
    "description": "The value of this attribute is always a number, or null.",
    "lineNumber": 7,
    "interface": false,
    "extends": [
      "lib/attributes/attribute.js~Attribute"
    ]
  },
  {
    "__docId__": 35,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "toJSON",
    "memberof": "lib/attributes/attribute-number.js~AttributeNumber",
    "longname": "lib/attributes/attribute-number.js~AttributeNumber#toJSON",
    "access": null,
    "description": null,
    "lineNumber": 8,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 36,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "fromJSON",
    "memberof": "lib/attributes/attribute-number.js~AttributeNumber",
    "longname": "lib/attributes/attribute-number.js~AttributeNumber#fromJSON",
    "access": null,
    "description": null,
    "lineNumber": 12,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 37,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "columnSQL",
    "memberof": "lib/attributes/attribute-number.js~AttributeNumber",
    "longname": "lib/attributes/attribute-number.js~AttributeNumber#columnSQL",
    "access": null,
    "description": null,
    "lineNumber": 16,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 38,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "greaterThan",
    "memberof": "lib/attributes/attribute-number.js~AttributeNumber",
    "longname": "lib/attributes/attribute-number.js~AttributeNumber#greaterThan",
    "access": null,
    "description": null,
    "lineNumber": 21,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 39,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "lessThan",
    "memberof": "lib/attributes/attribute-number.js~AttributeNumber",
    "longname": "lib/attributes/attribute-number.js~AttributeNumber#lessThan",
    "access": null,
    "description": null,
    "lineNumber": 27,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 40,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "greaterThanOrEqualTo",
    "memberof": "lib/attributes/attribute-number.js~AttributeNumber",
    "longname": "lib/attributes/attribute-number.js~AttributeNumber#greaterThanOrEqualTo",
    "access": null,
    "description": null,
    "lineNumber": 33,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 41,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "lessThanOrEqualTo",
    "memberof": "lib/attributes/attribute-number.js~AttributeNumber",
    "longname": "lib/attributes/attribute-number.js~AttributeNumber#lessThanOrEqualTo",
    "access": null,
    "description": null,
    "lineNumber": 39,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 42,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/attributes/attribute-object.js",
    "memberof": null,
    "longname": "lib/attributes/attribute-object.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import Attribute from './attribute';\n\n/**\nThe value of this attribute is always an object that can be cast to `itemClass`\n*/\nexport default class AttributeObject extends Attribute {\n  constructor({modelKey, jsonKey, itemClass, queryable}) {\n    super({modelKey, jsonKey, queryable});\n    this.ItemClass = itemClass;\n  }\n\n  toJSON(val) {\n    return (val && val.toJSON) ? val.toJSON() : val;\n  }\n\n  fromJSON(val) {\n    if (!this.ItemClass) {\n      return val || \"\";\n    }\n    const obj = new this.ItemClass(val);\n\n    // Important: if no ids are in the JSON, don't make them up randomly.\n    // This causes an object to be \"different\" each time it's de-serialized\n    // even if it's actually the same, makes React components re-render!\n    obj.id = undefined;\n\n    // Warning: typeof(null) is object\n    if (obj.fromJSON && !!val && (typeof val === 'object')) {\n      obj.fromJSON(val);\n    }\n\n    return obj;\n  }\n}\n"
  },
  {
    "__docId__": 43,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "AttributeObject",
    "memberof": "lib/attributes/attribute-object.js",
    "longname": "lib/attributes/attribute-object.js~AttributeObject",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/attributes/attribute-object.js",
    "importStyle": "AttributeObject",
    "description": "The value of this attribute is always an object that can be cast to `itemClass`",
    "lineNumber": 6,
    "interface": false,
    "extends": [
      "lib/attributes/attribute.js~Attribute"
    ]
  },
  {
    "__docId__": 44,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/attributes/attribute-object.js~AttributeObject",
    "longname": "lib/attributes/attribute-object.js~AttributeObject#constructor",
    "access": null,
    "description": null,
    "lineNumber": 7,
    "undocument": true,
    "params": [
      {
        "name": "objectPattern",
        "types": [
          "{\"modelKey\": *, \"jsonKey\": *, \"itemClass\": *, \"queryable\": *}"
        ],
        "defaultRaw": {
          "modelKey": null,
          "jsonKey": null,
          "itemClass": null,
          "queryable": null
        },
        "defaultValue": "{\"modelKey\":null,\"jsonKey\":null,\"itemClass\":null,\"queryable\":null}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 45,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "ItemClass",
    "memberof": "lib/attributes/attribute-object.js~AttributeObject",
    "longname": "lib/attributes/attribute-object.js~AttributeObject#ItemClass",
    "access": null,
    "description": null,
    "lineNumber": 9,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 46,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "toJSON",
    "memberof": "lib/attributes/attribute-object.js~AttributeObject",
    "longname": "lib/attributes/attribute-object.js~AttributeObject#toJSON",
    "access": null,
    "description": null,
    "lineNumber": 12,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 47,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "fromJSON",
    "memberof": "lib/attributes/attribute-object.js~AttributeObject",
    "longname": "lib/attributes/attribute-object.js~AttributeObject#fromJSON",
    "access": null,
    "description": null,
    "lineNumber": 16,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 48,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/attributes/attribute-string.js",
    "memberof": null,
    "longname": "lib/attributes/attribute-string.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import Attribute from './attribute';\nimport Matcher from './matcher';\n\n/**\nThe value of this attribute is always a string or `null`.\n\nString attributes can be queries using `equal`, `not`, and `startsWith`.\nMatching on `greaterThan` and `lessThan` is not supported.\n*/\nexport default class AttributeString extends Attribute {\n  toJSON(val) {\n    return val;\n  }\n\n  fromJSON(val) {\n    return (val === null || val === undefined || val === false) ? null : `${val}`;\n  }\n\n  // Public: Returns a {Matcher} for objects starting with the provided value.\n  startsWith(val) {\n    return new Matcher(this, 'startsWith', val);\n  }\n\n  columnSQL() {\n    return `${this.jsonKey} TEXT`;\n  }\n\n  like(val) {\n    this._assertPresentAndQueryable('like', val);\n    return new Matcher(this, 'like', val);\n  }\n}\n"
  },
  {
    "__docId__": 49,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "AttributeString",
    "memberof": "lib/attributes/attribute-string.js",
    "longname": "lib/attributes/attribute-string.js~AttributeString",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/attributes/attribute-string.js",
    "importStyle": "AttributeString",
    "description": "The value of this attribute is always a string or `null`.\n\nString attributes can be queries using `equal`, `not`, and `startsWith`.\nMatching on `greaterThan` and `lessThan` is not supported.",
    "lineNumber": 10,
    "interface": false,
    "extends": [
      "lib/attributes/attribute.js~Attribute"
    ]
  },
  {
    "__docId__": 50,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "toJSON",
    "memberof": "lib/attributes/attribute-string.js~AttributeString",
    "longname": "lib/attributes/attribute-string.js~AttributeString#toJSON",
    "access": null,
    "description": null,
    "lineNumber": 11,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 51,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "fromJSON",
    "memberof": "lib/attributes/attribute-string.js~AttributeString",
    "longname": "lib/attributes/attribute-string.js~AttributeString#fromJSON",
    "access": null,
    "description": null,
    "lineNumber": 15,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 52,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "startsWith",
    "memberof": "lib/attributes/attribute-string.js~AttributeString",
    "longname": "lib/attributes/attribute-string.js~AttributeString#startsWith",
    "access": null,
    "description": null,
    "lineNumber": 20,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 53,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "columnSQL",
    "memberof": "lib/attributes/attribute-string.js~AttributeString",
    "longname": "lib/attributes/attribute-string.js~AttributeString#columnSQL",
    "access": null,
    "description": null,
    "lineNumber": 24,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 54,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "like",
    "memberof": "lib/attributes/attribute-string.js~AttributeString",
    "longname": "lib/attributes/attribute-string.js~AttributeString#like",
    "access": null,
    "description": null,
    "lineNumber": 28,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 55,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/attributes/attribute.js",
    "memberof": null,
    "longname": "lib/attributes/attribute.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import Matcher from './matcher';\nimport SortOrder from './sort-order';\n\n/**\nThe Attribute class represents a single model attribute, like 'account_id'.\nSubclasses of {Attribute} like {AttributeDateTime} know how to covert between\nthe JSON representation of that type and the javascript representation.\nThe Attribute class also exposes convenience methods for generating {Matcher} objects.\n*/\nexport default class Attribute {\n  constructor({modelKey, queryable, jsonKey}) {\n    this.modelKey = modelKey;\n    this.jsonKey = jsonKey || modelKey;\n    this.queryable = queryable;\n  }\n\n  _assertPresentAndQueryable(fnName, val) {\n    if (val === undefined) {\n      throw new Error(`Attribute::${fnName} (${this.modelKey}) - you must provide a value`);\n    }\n    if (!this.queryable) {\n      throw new Error(`Attribute::${fnName} (${this.modelKey}) - this field cannot be queried against`);\n    }\n  }\n\n  /**\n  @param val - The attribute value\n  @returns {Matcher} - Matcher for objects `=` to the provided value.\n  */\n  equal(val) {\n    this._assertPresentAndQueryable('equal', val);\n    return new Matcher(this, '=', val);\n  }\n\n  /**\n  @param {Array} val - An array of values\n  @returns {Matcher} - Matcher for objects in the provided array.\n  */\n  in(val) {\n    this._assertPresentAndQueryable('in', val);\n\n    if (!(val instanceof Array)) {\n      throw new Error(`Attribute.in: you must pass an array of values.`);\n    }\n    if (val.length === 0) {\n      console.warn(`Attribute::in (${this.modelKey}) called with an empty set. You should avoid this useless query!`);\n    }\n    return (val.length === 1) ? new Matcher(this, '=', val[0]) : new Matcher(this, 'in', val);\n  }\n\n  /**\n  @param val - The attribute value\n  @returns {Matcher} - A matcher for objects `!=` to the provided value.\n  */\n  not(val) {\n    this._assertPresentAndQueryable('not', val);\n    return new Matcher(this, '!=', val);\n  }\n\n  /**\n  @returns {SortOrder} - Returns a descending sort order for this attribute\n  */\n  descending() {\n    return new SortOrder(this, 'DESC');\n  }\n\n  /**\n  @returns {SortOrder} - Returns an ascending sort order for this attribute\n  */\n  ascending() {\n    return new SortOrder(this, 'ASC');\n  }\n\n  toJSON(val) {\n    return val;\n  }\n\n  fromJSON(val) {\n    return val || null;\n  }\n}\n"
  },
  {
    "__docId__": 56,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "Attribute",
    "memberof": "lib/attributes/attribute.js",
    "longname": "lib/attributes/attribute.js~Attribute",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/attributes/attribute.js",
    "importStyle": "Attribute",
    "description": "The Attribute class represents a single model attribute, like 'account_id'.\nSubclasses of {Attribute} like {AttributeDateTime} know how to covert between\nthe JSON representation of that type and the javascript representation.\nThe Attribute class also exposes convenience methods for generating {Matcher} objects.",
    "lineNumber": 10,
    "interface": false
  },
  {
    "__docId__": 57,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/attributes/attribute.js~Attribute",
    "longname": "lib/attributes/attribute.js~Attribute#constructor",
    "access": null,
    "description": null,
    "lineNumber": 11,
    "undocument": true,
    "params": [
      {
        "name": "objectPattern",
        "types": [
          "{\"modelKey\": *, \"queryable\": *, \"jsonKey\": *}"
        ],
        "defaultRaw": {
          "modelKey": null,
          "queryable": null,
          "jsonKey": null
        },
        "defaultValue": "{\"modelKey\":null,\"queryable\":null,\"jsonKey\":null}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 58,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "modelKey",
    "memberof": "lib/attributes/attribute.js~Attribute",
    "longname": "lib/attributes/attribute.js~Attribute#modelKey",
    "access": null,
    "description": null,
    "lineNumber": 12,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 59,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "jsonKey",
    "memberof": "lib/attributes/attribute.js~Attribute",
    "longname": "lib/attributes/attribute.js~Attribute#jsonKey",
    "access": null,
    "description": null,
    "lineNumber": 13,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 60,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "queryable",
    "memberof": "lib/attributes/attribute.js~Attribute",
    "longname": "lib/attributes/attribute.js~Attribute#queryable",
    "access": null,
    "description": null,
    "lineNumber": 14,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 61,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_assertPresentAndQueryable",
    "memberof": "lib/attributes/attribute.js~Attribute",
    "longname": "lib/attributes/attribute.js~Attribute#_assertPresentAndQueryable",
    "access": null,
    "description": null,
    "lineNumber": 17,
    "undocument": true,
    "params": [
      {
        "name": "fnName",
        "types": [
          "*"
        ]
      },
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 62,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "equal",
    "memberof": "lib/attributes/attribute.js~Attribute",
    "longname": "lib/attributes/attribute.js~Attribute#equal",
    "access": null,
    "description": "",
    "lineNumber": 30,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Matcher} - Matcher for objects `=` to the provided value."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "*"
        ],
        "spread": false,
        "optional": false,
        "name": "val",
        "description": "The attribute value"
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Matcher"
      ],
      "spread": false,
      "description": "Matcher for objects `=` to the provided value."
    },
    "generator": false
  },
  {
    "__docId__": 63,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "in",
    "memberof": "lib/attributes/attribute.js~Attribute",
    "longname": "lib/attributes/attribute.js~Attribute#in",
    "access": null,
    "description": "",
    "lineNumber": 39,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Matcher} - Matcher for objects in the provided array."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Array"
        ],
        "spread": false,
        "optional": false,
        "name": "val",
        "description": "An array of values"
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Matcher"
      ],
      "spread": false,
      "description": "Matcher for objects in the provided array."
    },
    "generator": false
  },
  {
    "__docId__": 64,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "not",
    "memberof": "lib/attributes/attribute.js~Attribute",
    "longname": "lib/attributes/attribute.js~Attribute#not",
    "access": null,
    "description": "",
    "lineNumber": 55,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Matcher} - A matcher for objects `!=` to the provided value."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "*"
        ],
        "spread": false,
        "optional": false,
        "name": "val",
        "description": "The attribute value"
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Matcher"
      ],
      "spread": false,
      "description": "A matcher for objects `!=` to the provided value."
    },
    "generator": false
  },
  {
    "__docId__": 65,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "descending",
    "memberof": "lib/attributes/attribute.js~Attribute",
    "longname": "lib/attributes/attribute.js~Attribute#descending",
    "access": null,
    "description": "",
    "lineNumber": 63,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{SortOrder} - Returns a descending sort order for this attribute"
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "SortOrder"
      ],
      "spread": false,
      "description": "Returns a descending sort order for this attribute"
    },
    "generator": false
  },
  {
    "__docId__": 66,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "ascending",
    "memberof": "lib/attributes/attribute.js~Attribute",
    "longname": "lib/attributes/attribute.js~Attribute#ascending",
    "access": null,
    "description": "",
    "lineNumber": 70,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{SortOrder} - Returns an ascending sort order for this attribute"
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "SortOrder"
      ],
      "spread": false,
      "description": "Returns an ascending sort order for this attribute"
    },
    "generator": false
  },
  {
    "__docId__": 67,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "toJSON",
    "memberof": "lib/attributes/attribute.js~Attribute",
    "longname": "lib/attributes/attribute.js~Attribute#toJSON",
    "access": null,
    "description": null,
    "lineNumber": 74,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 68,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "fromJSON",
    "memberof": "lib/attributes/attribute.js~Attribute",
    "longname": "lib/attributes/attribute.js~Attribute#fromJSON",
    "access": null,
    "description": null,
    "lineNumber": 78,
    "undocument": true,
    "params": [
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 69,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/attributes/matcher.js",
    "memberof": null,
    "longname": "lib/attributes/matcher.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import {tableNameForJoin} from '../utils';\n\n// https://www.sqlite.org/faq.html#q14\n// That's right. Two single quotes in a row…\nconst singleQuoteEscapeSequence = \"''\";\n\n// https://www.sqlite.org/fts5.html#section_3\nconst doubleQuoteEscapeSequence = '\"\"';\n\n\n/**\nThe Matcher class encapsulates a particular comparison clause on an {@link Attribute}.\nMatchers can evaluate whether or not an object matches them, and also compose\nSQL clauses for the {@link RxDatabase}. Each matcher has a reference to a model\nattribute, a comparator and a value. This class is heavily inspired by\nNSPredicate on Mac OS X / CoreData.\n\n```js\n\n// Retrieving Matchers\n\nconst isUnread = Thread.attributes.unread.equal(true);\n\nconst hasLabel = Thread.attributes.categories.contains('label-id-123');\n\n// Using Matchers in Database Queries\n\nconst db.findAll(Thread).where(isUnread)...\n\n// Using Matchers to test Models\n\nconst threadA = new Thread({unread: true})\nconst threadB = new Thread({unread: false})\n\nisUnread.evaluate(threadA)\n// => true\n\nisUnread.evaluate(threadB)\n// => false\n\n```\n*/\nclass Matcher {\n  constructor(attr, comparator, val) {\n    this.attr = attr;\n    this.comparator = comparator;\n    this.val = val;\n\n    this.muid = Matcher.muid;\n    Matcher.muid = (Matcher.muid + 1) % 50;\n  }\n\n  attribute() {\n    return this.attr;\n  }\n\n  value() {\n    return this.val;\n  }\n\n  evaluate(model) {\n    let modelValue = model[this.attr.modelKey];\n    if (modelValue instanceof Function) {\n      modelValue = modelValue()\n    }\n    const matcherValue = this.val;\n\n    // Given an array of strings or models, and a string or model search value,\n    // will find if a match exists.\n    const modelArrayContainsValue = (array, searchItem) => {\n      const asId = (v) => ((v && v.id) ? v.id : v);\n      const search = asId(searchItem)\n      for (const item of array) {\n        if (asId(item) === search) {\n          return true;\n        }\n      }\n      return false;\n    }\n\n    switch (this.comparator) {\n      case '=':\n        return modelValue === matcherValue\n      case '<':\n        return modelValue < matcherValue\n      case '>':\n        return modelValue > matcherValue\n      case '<=':\n        return modelValue <= matcherValue\n      case '>=':\n        return modelValue >= matcherValue\n      case 'in':\n        return matcherValue.includes(modelValue)\n      case 'contains':\n        return modelArrayContainsValue(modelValue, matcherValue)\n      case 'containsAny':\n        return !!matcherValue.find((submatcherValue) => modelArrayContainsValue(modelValue, submatcherValue))\n      case 'startsWith':\n        return modelValue.startsWith(matcherValue)\n      case 'like':\n        return modelValue.search(new RegExp(`.*${matcherValue}.*`, \"gi\")) >= 0\n      default:\n        throw new Error(`Matcher.evaulate() not sure how to evaluate ${this.attr.modelKey} with comparator ${this.comparator}`)\n    }\n  }\n\n  joinTableRef() {\n    return `M${this.muid}`;\n  }\n\n  joinSQL(klass) {\n    switch (this.comparator) {\n      case 'contains':\n      case 'containsAny': {\n        const joinTable = tableNameForJoin(klass, this.attr.itemClass);\n        const joinTableRef = this.joinTableRef();\n        return `INNER JOIN \\`${joinTable}\\` AS \\`${joinTableRef}\\` ON \\`${joinTableRef}\\`.\\`id\\` = \\`${klass.name}\\`.\\`id\\``;\n      }\n      default:\n        return false;\n    }\n  }\n\n  whereSQL(klass) {\n    const val = (this.comparator === \"like\") ? `%${this.val}%` : this.val;\n    let escaped = null;\n\n    if (typeof val === 'string') {\n      escaped = `'${val.replace(/'/g, singleQuoteEscapeSequence)}'`;\n    } else if (val === true) {\n      escaped = 1\n    } else if (val === false) {\n      escaped = 0\n    } else if (val instanceof Date) {\n      escaped = val.getTime() / 1000\n    } else if (val instanceof Array) {\n      const escapedVals = []\n      for (const v of val) {\n        if (typeof v !== 'string') {\n          throw new Error(`${this.attr.jsonKey} value ${v} must be a string.`);\n        }\n        escapedVals.push(`'${v.replace(/'/g, singleQuoteEscapeSequence)}'`);\n      }\n      escaped = `(${escapedVals.join(',')})`;\n    } else {\n      escaped = val;\n    }\n\n    switch (this.comparator) {\n      case 'startsWith':\n        return \" RAISE `TODO`; \";\n      case 'contains':\n        return `\\`${this.joinTableRef()}\\`.\\`value\\` = ${escaped}`;\n      case 'containsAny':\n        return `\\`${this.joinTableRef()}\\`.\\`value\\` IN ${escaped}`;\n      default:\n        return `\\`${klass.name}\\`.\\`${this.attr.jsonKey}\\` ${this.comparator} ${escaped}`;\n    }\n  }\n}\n\nMatcher.muid = 0\n\n/**\nThis subclass is publicly exposed as Matcher.Or.\n@private\n*/\nclass OrCompositeMatcher extends Matcher {\n  constructor(children) {\n    super();\n    this.children = children;\n  }\n\n  attribute() {\n    return null;\n  }\n\n  value() {\n    return null;\n  }\n\n  evaluate(model) {\n    return this.children.some((matcher) => matcher.evaluate(model));\n  }\n\n  joinSQL(klass) {\n    const joins = []\n    for (const matcher of this.children) {\n      const join = matcher.joinSQL(klass);\n      if (join) {\n        joins.push(join);\n      }\n    }\n    return (joins.length) ? joins.join(\" \") : false;\n  }\n\n  whereSQL(klass) {\n    const wheres = this.children.map((matcher) => matcher.whereSQL(klass));\n    return `(${wheres.join(\" OR \")})`;\n  }\n}\n\n/**\nThis subclass is publicly exposed as Matcher.And.\n@private\n*/\nclass AndCompositeMatcher extends Matcher {\n  constructor(children) {\n    super();\n    this.children = children;\n  }\n\n  attribute() {\n    return null;\n  }\n\n  value() {\n    return null;\n  }\n\n  evaluate(model) {\n    return this.children.every((m) => m.evaluate(model));\n  }\n\n  joinSQL(klass) {\n    const joins = []\n    for (const matcher of this.children) {\n      const join = matcher.joinSQL(klass);\n      if (join) {\n        joins.push(join);\n      }\n    }\n    return joins;\n  }\n\n  whereSQL(klass) {\n    const wheres = this.children.map((m) => m.whereSQL(klass));\n    return `(${wheres.join(\" AND \")})`;\n  }\n}\n\n/**\nThis subclass is publicly exposed as Matcher.Not.\n@private\n*/\nclass NotCompositeMatcher extends AndCompositeMatcher {\n  whereSQL(klass) {\n    return `NOT (${super.whereSQL(klass)})`;\n  }\n}\n\nclass SearchMatcher extends Matcher {\n  constructor(searchQuery) {\n    super(null, null, null);\n    this.searchQuery = (\n      searchQuery.trim()\n      .replace(/^['\"]/, \"\")\n      .replace(/['\"]$/, \"\")\n      .replace(/'/g, singleQuoteEscapeSequence)\n      .replace(/\"/g, doubleQuoteEscapeSequence)\n    )\n  }\n\n  attribute() {\n    return null;\n  }\n\n  value() {\n    return null\n  }\n\n  // The only way to truly check if a model matches this matcher is to run the query\n  // again and check if the model is in the results. This is too expensive, so we\n  // will always return true so models aren't excluded from the\n  // SearchQuerySubscription result set\n  evaluate() {\n    return true;\n  }\n\n  joinSQL(klass) {\n    const searchTable = `${klass.name}Search`\n    const joinTableRef = this.joinTableRef()\n    return `INNER JOIN \\`${searchTable}\\` AS \\`${joinTableRef}\\` ON \\`${joinTableRef}\\`.\\`content_id\\` = \\`${klass.name}\\`.\\`id\\``;\n  }\n\n  whereSQL(klass) {\n    const searchTable = `${klass.name}Search`\n    return `\\`${searchTable}\\` MATCH '\"${this.searchQuery}\"*'`;\n  }\n}\n\nMatcher.Or = OrCompositeMatcher\nMatcher.And = AndCompositeMatcher\nMatcher.Not = NotCompositeMatcher\nMatcher.Search = SearchMatcher\n\nexport default Matcher;\n"
  },
  {
    "__docId__": 70,
    "kind": "variable",
    "static": true,
    "variation": null,
    "name": "singleQuoteEscapeSequence",
    "memberof": "lib/attributes/matcher.js",
    "longname": "lib/attributes/matcher.js~singleQuoteEscapeSequence",
    "access": null,
    "export": false,
    "importPath": "electron-coresqlite/lib/attributes/matcher.js",
    "importStyle": null,
    "description": null,
    "lineNumber": 5,
    "undocument": true,
    "type": {
      "types": [
        "string"
      ]
    }
  },
  {
    "__docId__": 71,
    "kind": "variable",
    "static": true,
    "variation": null,
    "name": "doubleQuoteEscapeSequence",
    "memberof": "lib/attributes/matcher.js",
    "longname": "lib/attributes/matcher.js~doubleQuoteEscapeSequence",
    "access": null,
    "export": false,
    "importPath": "electron-coresqlite/lib/attributes/matcher.js",
    "importStyle": null,
    "description": null,
    "lineNumber": 8,
    "undocument": true,
    "type": {
      "types": [
        "string"
      ]
    }
  },
  {
    "__docId__": 72,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "OrCompositeMatcher",
    "memberof": "lib/attributes/matcher.js",
    "longname": "lib/attributes/matcher.js~OrCompositeMatcher",
    "access": "private",
    "export": false,
    "importPath": "electron-coresqlite/lib/attributes/matcher.js",
    "importStyle": null,
    "description": "This subclass is publicly exposed as Matcher.Or.",
    "lineNumber": 168,
    "interface": false,
    "extends": [
      "Matcher"
    ]
  },
  {
    "__docId__": 73,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/attributes/matcher.js~OrCompositeMatcher",
    "longname": "lib/attributes/matcher.js~OrCompositeMatcher#constructor",
    "access": null,
    "description": null,
    "lineNumber": 169,
    "undocument": true,
    "params": [
      {
        "name": "children",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 74,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "children",
    "memberof": "lib/attributes/matcher.js~OrCompositeMatcher",
    "longname": "lib/attributes/matcher.js~OrCompositeMatcher#children",
    "access": null,
    "description": null,
    "lineNumber": 171,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 75,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "attribute",
    "memberof": "lib/attributes/matcher.js~OrCompositeMatcher",
    "longname": "lib/attributes/matcher.js~OrCompositeMatcher#attribute",
    "access": null,
    "description": null,
    "lineNumber": 174,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 76,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "value",
    "memberof": "lib/attributes/matcher.js~OrCompositeMatcher",
    "longname": "lib/attributes/matcher.js~OrCompositeMatcher#value",
    "access": null,
    "description": null,
    "lineNumber": 178,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 77,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "evaluate",
    "memberof": "lib/attributes/matcher.js~OrCompositeMatcher",
    "longname": "lib/attributes/matcher.js~OrCompositeMatcher#evaluate",
    "access": null,
    "description": null,
    "lineNumber": 182,
    "undocument": true,
    "params": [
      {
        "name": "model",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 78,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "joinSQL",
    "memberof": "lib/attributes/matcher.js~OrCompositeMatcher",
    "longname": "lib/attributes/matcher.js~OrCompositeMatcher#joinSQL",
    "access": null,
    "description": null,
    "lineNumber": 186,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 79,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "whereSQL",
    "memberof": "lib/attributes/matcher.js~OrCompositeMatcher",
    "longname": "lib/attributes/matcher.js~OrCompositeMatcher#whereSQL",
    "access": null,
    "description": null,
    "lineNumber": 197,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 80,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "AndCompositeMatcher",
    "memberof": "lib/attributes/matcher.js",
    "longname": "lib/attributes/matcher.js~AndCompositeMatcher",
    "access": "private",
    "export": false,
    "importPath": "electron-coresqlite/lib/attributes/matcher.js",
    "importStyle": null,
    "description": "This subclass is publicly exposed as Matcher.And.",
    "lineNumber": 207,
    "interface": false,
    "extends": [
      "Matcher"
    ]
  },
  {
    "__docId__": 81,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/attributes/matcher.js~AndCompositeMatcher",
    "longname": "lib/attributes/matcher.js~AndCompositeMatcher#constructor",
    "access": null,
    "description": null,
    "lineNumber": 208,
    "undocument": true,
    "params": [
      {
        "name": "children",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 82,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "children",
    "memberof": "lib/attributes/matcher.js~AndCompositeMatcher",
    "longname": "lib/attributes/matcher.js~AndCompositeMatcher#children",
    "access": null,
    "description": null,
    "lineNumber": 210,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 83,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "attribute",
    "memberof": "lib/attributes/matcher.js~AndCompositeMatcher",
    "longname": "lib/attributes/matcher.js~AndCompositeMatcher#attribute",
    "access": null,
    "description": null,
    "lineNumber": 213,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 84,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "value",
    "memberof": "lib/attributes/matcher.js~AndCompositeMatcher",
    "longname": "lib/attributes/matcher.js~AndCompositeMatcher#value",
    "access": null,
    "description": null,
    "lineNumber": 217,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 85,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "evaluate",
    "memberof": "lib/attributes/matcher.js~AndCompositeMatcher",
    "longname": "lib/attributes/matcher.js~AndCompositeMatcher#evaluate",
    "access": null,
    "description": null,
    "lineNumber": 221,
    "undocument": true,
    "params": [
      {
        "name": "model",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 86,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "joinSQL",
    "memberof": "lib/attributes/matcher.js~AndCompositeMatcher",
    "longname": "lib/attributes/matcher.js~AndCompositeMatcher#joinSQL",
    "access": null,
    "description": null,
    "lineNumber": 225,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 87,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "whereSQL",
    "memberof": "lib/attributes/matcher.js~AndCompositeMatcher",
    "longname": "lib/attributes/matcher.js~AndCompositeMatcher#whereSQL",
    "access": null,
    "description": null,
    "lineNumber": 236,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 88,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "NotCompositeMatcher",
    "memberof": "lib/attributes/matcher.js",
    "longname": "lib/attributes/matcher.js~NotCompositeMatcher",
    "access": "private",
    "export": false,
    "importPath": "electron-coresqlite/lib/attributes/matcher.js",
    "importStyle": null,
    "description": "This subclass is publicly exposed as Matcher.Not.",
    "lineNumber": 246,
    "interface": false,
    "extends": [
      "AndCompositeMatcher"
    ]
  },
  {
    "__docId__": 89,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "whereSQL",
    "memberof": "lib/attributes/matcher.js~NotCompositeMatcher",
    "longname": "lib/attributes/matcher.js~NotCompositeMatcher#whereSQL",
    "access": null,
    "description": null,
    "lineNumber": 247,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 90,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "SearchMatcher",
    "memberof": "lib/attributes/matcher.js",
    "longname": "lib/attributes/matcher.js~SearchMatcher",
    "access": null,
    "export": false,
    "importPath": "electron-coresqlite/lib/attributes/matcher.js",
    "importStyle": null,
    "description": null,
    "lineNumber": 252,
    "undocument": true,
    "interface": false,
    "extends": [
      "Matcher"
    ]
  },
  {
    "__docId__": 91,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/attributes/matcher.js~SearchMatcher",
    "longname": "lib/attributes/matcher.js~SearchMatcher#constructor",
    "access": null,
    "description": null,
    "lineNumber": 253,
    "undocument": true,
    "params": [
      {
        "name": "searchQuery",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 92,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "searchQuery",
    "memberof": "lib/attributes/matcher.js~SearchMatcher",
    "longname": "lib/attributes/matcher.js~SearchMatcher#searchQuery",
    "access": null,
    "description": null,
    "lineNumber": 255,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 93,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "attribute",
    "memberof": "lib/attributes/matcher.js~SearchMatcher",
    "longname": "lib/attributes/matcher.js~SearchMatcher#attribute",
    "access": null,
    "description": null,
    "lineNumber": 264,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 94,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "value",
    "memberof": "lib/attributes/matcher.js~SearchMatcher",
    "longname": "lib/attributes/matcher.js~SearchMatcher#value",
    "access": null,
    "description": null,
    "lineNumber": 268,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 95,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "evaluate",
    "memberof": "lib/attributes/matcher.js~SearchMatcher",
    "longname": "lib/attributes/matcher.js~SearchMatcher#evaluate",
    "access": null,
    "description": null,
    "lineNumber": 276,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "boolean"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 96,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "joinSQL",
    "memberof": "lib/attributes/matcher.js~SearchMatcher",
    "longname": "lib/attributes/matcher.js~SearchMatcher#joinSQL",
    "access": null,
    "description": null,
    "lineNumber": 280,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 97,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "whereSQL",
    "memberof": "lib/attributes/matcher.js~SearchMatcher",
    "longname": "lib/attributes/matcher.js~SearchMatcher#whereSQL",
    "access": null,
    "description": null,
    "lineNumber": 286,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 98,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "Matcher",
    "memberof": "lib/attributes/matcher.js",
    "longname": "lib/attributes/matcher.js~Matcher",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/attributes/matcher.js",
    "importStyle": "Matcher",
    "description": "The Matcher class encapsulates a particular comparison clause on an {@link Attribute}.\nMatchers can evaluate whether or not an object matches them, and also compose\nSQL clauses for the {@link RxDatabase}. Each matcher has a reference to a model\nattribute, a comparator and a value. This class is heavily inspired by\nNSPredicate on Mac OS X / CoreData.\n\n```js\n\n// Retrieving Matchers\n\nconst isUnread = Thread.attributes.unread.equal(true);\n\nconst hasLabel = Thread.attributes.categories.contains('label-id-123');\n\n// Using Matchers in Database Queries\n\nconst db.findAll(Thread).where(isUnread)...\n\n// Using Matchers to test Models\n\nconst threadA = new Thread({unread: true})\nconst threadB = new Thread({unread: false})\n\nisUnread.evaluate(threadA)\n// => true\n\nisUnread.evaluate(threadB)\n// => false\n\n```",
    "lineNumber": 43,
    "interface": false
  },
  {
    "__docId__": 99,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/attributes/matcher.js~Matcher",
    "longname": "lib/attributes/matcher.js~Matcher#constructor",
    "access": null,
    "description": null,
    "lineNumber": 44,
    "undocument": true,
    "params": [
      {
        "name": "attr",
        "types": [
          "*"
        ]
      },
      {
        "name": "comparator",
        "types": [
          "*"
        ]
      },
      {
        "name": "val",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 100,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "attr",
    "memberof": "lib/attributes/matcher.js~Matcher",
    "longname": "lib/attributes/matcher.js~Matcher#attr",
    "access": null,
    "description": null,
    "lineNumber": 45,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 101,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "comparator",
    "memberof": "lib/attributes/matcher.js~Matcher",
    "longname": "lib/attributes/matcher.js~Matcher#comparator",
    "access": null,
    "description": null,
    "lineNumber": 46,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 102,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "val",
    "memberof": "lib/attributes/matcher.js~Matcher",
    "longname": "lib/attributes/matcher.js~Matcher#val",
    "access": null,
    "description": null,
    "lineNumber": 47,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 103,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "muid",
    "memberof": "lib/attributes/matcher.js~Matcher",
    "longname": "lib/attributes/matcher.js~Matcher#muid",
    "access": null,
    "description": null,
    "lineNumber": 49,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 104,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "attribute",
    "memberof": "lib/attributes/matcher.js~Matcher",
    "longname": "lib/attributes/matcher.js~Matcher#attribute",
    "access": null,
    "description": null,
    "lineNumber": 53,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 105,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "value",
    "memberof": "lib/attributes/matcher.js~Matcher",
    "longname": "lib/attributes/matcher.js~Matcher#value",
    "access": null,
    "description": null,
    "lineNumber": 57,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 106,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "evaluate",
    "memberof": "lib/attributes/matcher.js~Matcher",
    "longname": "lib/attributes/matcher.js~Matcher#evaluate",
    "access": null,
    "description": null,
    "lineNumber": 61,
    "undocument": true,
    "params": [
      {
        "name": "model",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 107,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "joinTableRef",
    "memberof": "lib/attributes/matcher.js~Matcher",
    "longname": "lib/attributes/matcher.js~Matcher#joinTableRef",
    "access": null,
    "description": null,
    "lineNumber": 107,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 108,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "joinSQL",
    "memberof": "lib/attributes/matcher.js~Matcher",
    "longname": "lib/attributes/matcher.js~Matcher#joinSQL",
    "access": null,
    "description": null,
    "lineNumber": 111,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "boolean"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 109,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "whereSQL",
    "memberof": "lib/attributes/matcher.js~Matcher",
    "longname": "lib/attributes/matcher.js~Matcher#whereSQL",
    "access": null,
    "description": null,
    "lineNumber": 124,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 110,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/attributes/sort-order.js",
    "memberof": null,
    "longname": "lib/attributes/sort-order.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/**\nRepresents a particular sort direction on a particular column. You should not\ninstantiate SortOrders manually. Instead, call {@link Attribute.ascending} or\n{@link Attribute.descending} to obtain a sort order instance:\n\n```js\ndb.findBy(Message)\n  .where({threadId: threadId, draft: false})\n  .order(Message.attributes.date.descending()).then((messages) {\n\n});\n```\n\nSection: Database\n*/\nexport default class SortOrder {\n  constructor(attr, direction = 'DESC') {\n    this.attr = attr;\n    this.direction = direction;\n  }\n\n  orderBySQL(klass) {\n    return `\\`${klass.name}\\`.\\`${this.attr.jsonKey}\\` ${this.direction}`;\n  }\n\n  attribute() {\n    return this.attr;\n  }\n}\n"
  },
  {
    "__docId__": 111,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "SortOrder",
    "memberof": "lib/attributes/sort-order.js",
    "longname": "lib/attributes/sort-order.js~SortOrder",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/attributes/sort-order.js",
    "importStyle": "SortOrder",
    "description": "Represents a particular sort direction on a particular column. You should not\ninstantiate SortOrders manually. Instead, call {@link Attribute.ascending} or\n{@link Attribute.descending} to obtain a sort order instance:\n\n```js\ndb.findBy(Message)\n.where({threadId: threadId, draft: false})\n.order(Message.attributes.date.descending()).then((messages) {\n\n});\n```\n\nSection: Database",
    "lineNumber": 16,
    "interface": false
  },
  {
    "__docId__": 112,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/attributes/sort-order.js~SortOrder",
    "longname": "lib/attributes/sort-order.js~SortOrder#constructor",
    "access": null,
    "description": null,
    "lineNumber": 17,
    "undocument": true,
    "params": [
      {
        "name": "attr",
        "types": [
          "*"
        ]
      },
      {
        "name": "direction",
        "optional": true,
        "types": [
          "string"
        ],
        "defaultRaw": "DESC",
        "defaultValue": "DESC"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 113,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "attr",
    "memberof": "lib/attributes/sort-order.js~SortOrder",
    "longname": "lib/attributes/sort-order.js~SortOrder#attr",
    "access": null,
    "description": null,
    "lineNumber": 18,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 114,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "direction",
    "memberof": "lib/attributes/sort-order.js~SortOrder",
    "longname": "lib/attributes/sort-order.js~SortOrder#direction",
    "access": null,
    "description": null,
    "lineNumber": 19,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 115,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "orderBySQL",
    "memberof": "lib/attributes/sort-order.js~SortOrder",
    "longname": "lib/attributes/sort-order.js~SortOrder#orderBySQL",
    "access": null,
    "description": null,
    "lineNumber": 22,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 116,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "attribute",
    "memberof": "lib/attributes/sort-order.js~SortOrder",
    "longname": "lib/attributes/sort-order.js~SortOrder#attribute",
    "access": null,
    "description": null,
    "lineNumber": 26,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 117,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/attributes.js",
    "memberof": null,
    "longname": "lib/attributes.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import Matcher from './attributes/matcher'\nimport SortOrder from './attributes/sort-order'\nimport AttributeNumber from './attributes/attribute-number'\nimport AttributeString from './attributes/attribute-string'\nimport AttributeObject from './attributes/attribute-object'\nimport AttributeBoolean from './attributes/attribute-boolean'\nimport AttributeDateTime from './attributes/attribute-datetime'\nimport AttributeCollection from './attributes/attribute-collection'\nimport AttributeJoinedData from './attributes/attribute-joined-data'\n\nmodule.exports = {\n  Matcher: Matcher,\n  SortOrder: SortOrder,\n\n  Number: (...args) => new AttributeNumber(...args),\n  String: (...args) => new AttributeString(...args),\n  Object: (...args) => new AttributeObject(...args),\n  Boolean: (...args) => new AttributeBoolean(...args),\n  DateTime: (...args) => new AttributeDateTime(...args),\n  Collection: (...args) => new AttributeCollection(...args),\n  JoinedData: (...args) => new AttributeJoinedData(...args),\n\n  AttributeNumber: AttributeNumber,\n  AttributeString: AttributeString,\n  AttributeObject: AttributeObject,\n  AttributeBoolean: AttributeBoolean,\n  AttributeDateTime: AttributeDateTime,\n  AttributeCollection: AttributeCollection,\n  AttributeJoinedData: AttributeJoinedData,\n};\n"
  },
  {
    "__docId__": 118,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/browser/coordinator.js",
    "memberof": null,
    "longname": "lib/browser/coordinator.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import {BrowserWindow, ipcMain} from 'electron';\nimport fs from 'fs';\n\n/**\nTo use RxDB, you need to attach the coordinator in your Electron browser process.\nIt handles message dispatch across windows and manages the state of database\nfiles when they need to be created before use. Just import it and instantiate one:\n\n```js\nimport {Coordinator} from 'electron-rxdb';\nglobal._coordinator = new Coordinator();\n```\n*/\nexport default class Coordinator {\n  constructor() {\n    this._phase = 'setup';\n\n    ipcMain.on('rxdb-get-phase', (event) => {\n      event.returnValue = this._phase;\n    });\n\n    ipcMain.on('rxdb-set-phase', (event, phase) => {\n      console.log(phase);\n      this.setPhase(phase);\n    });\n\n    ipcMain.on('rxdb-handle-setup-error', () => {\n      this.recoverFromFatalDatabaseError();\n    });\n\n    ipcMain.on('rxdb-trigger', (event, ...args) => {\n      const sender = BrowserWindow.fromWebContents(event.sender);\n      BrowserWindow.getAllWindows().forEach((win) => {\n        if (win !== sender) {\n          win.webContents.send('rxdb-trigger', ...args);\n        }\n      });\n    });\n  }\n\n  setPhase(phase) {\n    this._phase = phase;\n    BrowserWindow.getAllWindows().forEach((win) => {\n      win.webContents.send('rxdb-phase-changed');\n    });\n  }\n\n  recoverFromFatalDatabaseError(databasePath) {\n    setTimeout(() => {\n      if (this._databasePhase === 'close') {\n        return;\n      }\n      this.setPhase('close');\n      BrowserWindow.getAllWindows().forEach((win) => {\n        win.hide();\n      });\n      this.deleteDatabase(databasePath, () => {\n        this.setPhase('setup');\n        BrowserWindow.getAllWindows().forEach((win) => {\n          win.reload();\n          win.once('ready-to-show', () => {\n            win.show();\n          });\n        });\n      });\n    }, 0);\n  }\n\n  deleteDatabase(databasePath, callback) {\n    this.deleteFileWithRetry(`${databasePath}-wal`);\n    this.deleteFileWithRetry(`${databasePath}-shm`);\n    this.deleteFileWithRetry(databasePath, callback);\n  }\n\n  // On Windows, removing a file can fail if a process still has it open. When\n  // we close windows and log out, we need to wait for these processes to completely\n  // exit and then delete the file. It's hard to tell when this happens, so we just\n  // retry the deletion a few times.\n  deleteFileWithRetry(filePath, callback = () => {}, retries = 5) {\n    const callbackWithRetry = (err) => {\n      if (err && (err.message.indexOf('no such file') === -1)) {\n        console.log(`File Error: ${err.message} - retrying in 150msec`);\n        setTimeout(() => {\n          this.deleteFileWithRetry(filePath, callback, retries - 1);\n        }, 150);\n      } else {\n        callback(null);\n      }\n    }\n\n    if (!fs.existsSync(filePath)) {\n      callback(null);\n      return\n    }\n\n    if (retries > 0) {\n      fs.unlink(filePath, callbackWithRetry);\n    } else {\n      fs.unlink(filePath, callback);\n    }\n  }\n}\n"
  },
  {
    "__docId__": 119,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "Coordinator",
    "memberof": "lib/browser/coordinator.js",
    "longname": "lib/browser/coordinator.js~Coordinator",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/browser/coordinator.js",
    "importStyle": "Coordinator",
    "description": "To use RxDB, you need to attach the coordinator in your Electron browser process.\nIt handles message dispatch across windows and manages the state of database\nfiles when they need to be created before use. Just import it and instantiate one:\n\n```js\nimport {Coordinator} from 'electron-rxdb';\nglobal._coordinator = new Coordinator();\n```",
    "lineNumber": 14,
    "interface": false
  },
  {
    "__docId__": 120,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/browser/coordinator.js~Coordinator",
    "longname": "lib/browser/coordinator.js~Coordinator#constructor",
    "access": null,
    "description": null,
    "lineNumber": 15,
    "undocument": true,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 121,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_phase",
    "memberof": "lib/browser/coordinator.js~Coordinator",
    "longname": "lib/browser/coordinator.js~Coordinator#_phase",
    "access": null,
    "description": null,
    "lineNumber": 16,
    "undocument": true,
    "type": {
      "types": [
        "string"
      ]
    }
  },
  {
    "__docId__": 122,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "setPhase",
    "memberof": "lib/browser/coordinator.js~Coordinator",
    "longname": "lib/browser/coordinator.js~Coordinator#setPhase",
    "access": null,
    "description": null,
    "lineNumber": 41,
    "undocument": true,
    "params": [
      {
        "name": "phase",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 123,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_phase",
    "memberof": "lib/browser/coordinator.js~Coordinator",
    "longname": "lib/browser/coordinator.js~Coordinator#_phase",
    "access": null,
    "description": null,
    "lineNumber": 42,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 124,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "recoverFromFatalDatabaseError",
    "memberof": "lib/browser/coordinator.js~Coordinator",
    "longname": "lib/browser/coordinator.js~Coordinator#recoverFromFatalDatabaseError",
    "access": null,
    "description": null,
    "lineNumber": 48,
    "undocument": true,
    "params": [
      {
        "name": "databasePath",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 125,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "deleteDatabase",
    "memberof": "lib/browser/coordinator.js~Coordinator",
    "longname": "lib/browser/coordinator.js~Coordinator#deleteDatabase",
    "access": null,
    "description": null,
    "lineNumber": 69,
    "undocument": true,
    "params": [
      {
        "name": "databasePath",
        "types": [
          "*"
        ]
      },
      {
        "name": "callback",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 126,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "deleteFileWithRetry",
    "memberof": "lib/browser/coordinator.js~Coordinator",
    "longname": "lib/browser/coordinator.js~Coordinator#deleteFileWithRetry",
    "access": null,
    "description": null,
    "lineNumber": 79,
    "undocument": true,
    "params": [
      {
        "name": "filePath",
        "types": [
          "*"
        ]
      },
      {
        "name": "callback",
        "optional": true,
        "types": [
          "*"
        ]
      },
      {
        "name": "retries",
        "optional": true,
        "types": [
          "number"
        ],
        "defaultRaw": 5,
        "defaultValue": "5"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 127,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/console-utils.js",
    "memberof": null,
    "longname": "lib/console-utils.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint import/prefer-default-export: 0 */\nexport function logSQLString(qa) {\n  let q = qa.replace(/%/g, '%%');\n  q = `color:black |||%c ${q}`;\n  q = q.replace(/`(\\w+)`/g, \"||| color:purple |||%c$&||| color:black |||%c\");\n\n  const colorRules = {\n    'color:green': ['SELECT', 'INSERT INTO', 'VALUES', 'WHERE', 'FROM', 'JOIN', 'ORDER BY', 'DESC', 'ASC', 'INNER', 'OUTER', 'LIMIT', 'OFFSET', 'IN'],\n    'color:red; background-color:#ffdddd;': ['SCAN TABLE'],\n  };\n\n  for (const style of Object.keys(colorRules)) {\n    for (const keyword of colorRules[style]) {\n      q = q.replace(new RegExp(`\\\\b${keyword}\\\\b`, 'g'), `||| ${style} |||%c${keyword}||| color:black |||%c`);\n    }\n  }\n\n  q = q.split('|||');\n  const colors = [];\n  const msg = [];\n  for (let i = 0; i < q.length; i++) {\n    if (i % 2 === 0) {\n      colors.push(q[i]);\n    } else {\n      msg.push(q[i]);\n    }\n  }\n\n  console.log(msg.join(''), ...colors);\n}\n"
  },
  {
    "__docId__": 128,
    "kind": "function",
    "static": true,
    "variation": null,
    "name": "logSQLString",
    "memberof": "lib/console-utils.js",
    "longname": "lib/console-utils.js~logSQLString",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/console-utils.js",
    "importStyle": "{logSQLString}",
    "description": null,
    "lineNumber": 2,
    "undocument": true,
    "params": [
      {
        "name": "qa",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 129,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/database-change-record-debouncer.js",
    "memberof": null,
    "longname": "lib/database-change-record-debouncer.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/**\nDatabaseChangeRecordDebouncer.accumulate is a guarded version of trigger that can accumulate changes.\nThis means that even if you're a bad person and call `persistModel` 100 times\nfrom 100 task objects queued at the same time, it will only create one\n`trigger` event. This is important since the database triggering impacts\nthe entire application.\n\n@private\n*/\nexport default class DatabaseChangeRecordDebouncer {\n  constructor({onTrigger, maxTriggerDelay}) {\n    this._options = {onTrigger, maxTriggerDelay};\n    this._record = null;\n  }\n\n  _flushAfterDelay() {\n    this._cancelFlush();\n    this._flushTimer = setTimeout(() => this._flush(), this._options.maxTriggerDelay);\n  }\n\n  _cancelFlush() {\n    if (this._flushTimer) {\n      clearTimeout(this._flushTimer);\n      this._flushTimer = null;\n    }\n  }\n\n  _flush() {\n    if (!this._record) {\n      return;\n    }\n\n    this._cancelFlush();\n    this._options.onTrigger(this._record);\n    this._record = null;\n\n    if (this._promiseResolve) {\n      this._promiseResolve();\n      this._promiseResolve = null;\n      this._promise = null;\n    }\n  }\n\n  accumulate(change) {\n    this._promise = this._promise || new Promise((resolve) => {\n      this._promiseResolve = resolve;\n    });\n\n    if (this._record && this._record.canAppend(change)) {\n      this._record.append(change);\n    } else {\n      this._flush();\n      this._record = change;\n      this._flushAfterDelay();\n    }\n\n    return this._promise;\n  }\n}\n"
  },
  {
    "__docId__": 130,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "DatabaseChangeRecordDebouncer",
    "memberof": "lib/database-change-record-debouncer.js",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "access": "private",
    "export": true,
    "importPath": "electron-coresqlite/lib/database-change-record-debouncer.js",
    "importStyle": "DatabaseChangeRecordDebouncer",
    "description": "DatabaseChangeRecordDebouncer.accumulate is a guarded version of trigger that can accumulate changes.\nThis means that even if you're a bad person and call `persistModel` 100 times\nfrom 100 task objects queued at the same time, it will only create one\n`trigger` event. This is important since the database triggering impacts\nthe entire application.",
    "lineNumber": 10,
    "interface": false
  },
  {
    "__docId__": 131,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#constructor",
    "access": null,
    "description": null,
    "lineNumber": 11,
    "undocument": true,
    "params": [
      {
        "name": "objectPattern",
        "types": [
          "{\"onTrigger\": *, \"maxTriggerDelay\": *}"
        ],
        "defaultRaw": {
          "onTrigger": null,
          "maxTriggerDelay": null
        },
        "defaultValue": "{\"onTrigger\":null,\"maxTriggerDelay\":null}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 132,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_options",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_options",
    "access": null,
    "description": null,
    "lineNumber": 12,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 133,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_record",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_record",
    "access": null,
    "description": null,
    "lineNumber": 13,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 134,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_flushAfterDelay",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_flushAfterDelay",
    "access": null,
    "description": null,
    "lineNumber": 16,
    "undocument": true,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 135,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_flushTimer",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_flushTimer",
    "access": null,
    "description": null,
    "lineNumber": 18,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 136,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_cancelFlush",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_cancelFlush",
    "access": null,
    "description": null,
    "lineNumber": 21,
    "undocument": true,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 137,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_flushTimer",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_flushTimer",
    "access": null,
    "description": null,
    "lineNumber": 24,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 138,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_flush",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_flush",
    "access": null,
    "description": null,
    "lineNumber": 28,
    "undocument": true,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 139,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_record",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_record",
    "access": null,
    "description": null,
    "lineNumber": 35,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 140,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_promiseResolve",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_promiseResolve",
    "access": null,
    "description": null,
    "lineNumber": 39,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 141,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_promise",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_promise",
    "access": null,
    "description": null,
    "lineNumber": 40,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 142,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "accumulate",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#accumulate",
    "access": null,
    "description": null,
    "lineNumber": 44,
    "undocument": true,
    "params": [
      {
        "name": "change",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 143,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_promise",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_promise",
    "access": null,
    "description": null,
    "lineNumber": 45,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 144,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_promiseResolve",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_promiseResolve",
    "access": null,
    "description": null,
    "lineNumber": 46,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 145,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_record",
    "memberof": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer",
    "longname": "lib/database-change-record-debouncer.js~DatabaseChangeRecordDebouncer#_record",
    "access": null,
    "description": null,
    "lineNumber": 53,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 146,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/database-change-record.js",
    "memberof": null,
    "longname": "lib/database-change-record.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/**\nAn RxDB database emits DatabaseChangeRecord objects once a transaction has completed.\nThe change record contains a copy of the model(s) that were modified, the type of\nmodification (persist / destroy) and the model class.\n\nDatabaseChangeRecords can be serialized to JSON and RxDB transparently bridges\nthem between windows of Electron applications. Change records of the same type\nand model class can also be merged.\n*/\nexport default class DatabaseChangeRecord {\n\n  constructor(database, options) {\n    this._database = database;\n    this._options = options;\n\n    // When DatabaseChangeRecords are sent over IPC to other windows, their object\n    // payload is sub-serialized into a JSON string. This means that we can wait\n    // to deserialize models until someone in the window asks for `change.objects`\n    this._objects = options.objects;\n    this._objectsString = options.objectsString;\n\n    Object.defineProperty(this, 'type', {\n      get: () => options.type,\n    })\n    Object.defineProperty(this, 'objectClass', {\n      get: () => options.objectClass,\n    })\n    Object.defineProperty(this, 'objects', {\n      get: () => {\n        this._objects = this._objects || JSON.parse(this._objectsString, this._database.models.JSONReviver);\n        return this._objects;\n      },\n    })\n  }\n\n  canAppend(other) {\n    return (this.objectClass === other.objectClass) && (this.type === other.type);\n  }\n\n  append(other) {\n    if (!this._indexLookup) {\n      this._indexLookup = {};\n      this.objects.forEach((obj, idx) => {\n        this._indexLookup[obj.id] = idx;\n      });\n    }\n\n    // When we join new models into our set, replace existing ones so the same\n    // model cannot exist in the change record set multiple times.\n    for (const obj of other.objects) {\n      const idx = this._indexLookup[obj.id]\n      if (idx) {\n        this.objects[idx] = obj;\n      } else {\n        this._indexLookup[obj.id] = this.objects.length\n        this.objects.push(obj);\n      }\n    }\n  }\n\n  toJSON() {\n    this._objectsString = this._objectsString || JSON.stringify(this._objects, this._database.models.JSONReplacer);\n    return {\n      type: this.type,\n      objectClass: this.objectClass,\n      objectsString: this._objectsString,\n    };\n  }\n}\n"
  },
  {
    "__docId__": 147,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "DatabaseChangeRecord",
    "memberof": "lib/database-change-record.js",
    "longname": "lib/database-change-record.js~DatabaseChangeRecord",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/database-change-record.js",
    "importStyle": "DatabaseChangeRecord",
    "description": "An RxDB database emits DatabaseChangeRecord objects once a transaction has completed.\nThe change record contains a copy of the model(s) that were modified, the type of\nmodification (persist / destroy) and the model class.\n\nDatabaseChangeRecords can be serialized to JSON and RxDB transparently bridges\nthem between windows of Electron applications. Change records of the same type\nand model class can also be merged.",
    "lineNumber": 10,
    "interface": false
  },
  {
    "__docId__": 148,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/database-change-record.js~DatabaseChangeRecord",
    "longname": "lib/database-change-record.js~DatabaseChangeRecord#constructor",
    "access": null,
    "description": null,
    "lineNumber": 12,
    "undocument": true,
    "params": [
      {
        "name": "database",
        "types": [
          "*"
        ]
      },
      {
        "name": "options",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 149,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_database",
    "memberof": "lib/database-change-record.js~DatabaseChangeRecord",
    "longname": "lib/database-change-record.js~DatabaseChangeRecord#_database",
    "access": null,
    "description": null,
    "lineNumber": 13,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 150,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_options",
    "memberof": "lib/database-change-record.js~DatabaseChangeRecord",
    "longname": "lib/database-change-record.js~DatabaseChangeRecord#_options",
    "access": null,
    "description": null,
    "lineNumber": 14,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 151,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_objects",
    "memberof": "lib/database-change-record.js~DatabaseChangeRecord",
    "longname": "lib/database-change-record.js~DatabaseChangeRecord#_objects",
    "access": null,
    "description": null,
    "lineNumber": 19,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 152,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_objectsString",
    "memberof": "lib/database-change-record.js~DatabaseChangeRecord",
    "longname": "lib/database-change-record.js~DatabaseChangeRecord#_objectsString",
    "access": null,
    "description": null,
    "lineNumber": 20,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 153,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_objects",
    "memberof": "lib/database-change-record.js~DatabaseChangeRecord",
    "longname": "lib/database-change-record.js~DatabaseChangeRecord#_objects",
    "access": null,
    "description": null,
    "lineNumber": 30,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 154,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "canAppend",
    "memberof": "lib/database-change-record.js~DatabaseChangeRecord",
    "longname": "lib/database-change-record.js~DatabaseChangeRecord#canAppend",
    "access": null,
    "description": null,
    "lineNumber": 36,
    "undocument": true,
    "params": [
      {
        "name": "other",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 155,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "append",
    "memberof": "lib/database-change-record.js~DatabaseChangeRecord",
    "longname": "lib/database-change-record.js~DatabaseChangeRecord#append",
    "access": null,
    "description": null,
    "lineNumber": 40,
    "undocument": true,
    "params": [
      {
        "name": "other",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 156,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_indexLookup",
    "memberof": "lib/database-change-record.js~DatabaseChangeRecord",
    "longname": "lib/database-change-record.js~DatabaseChangeRecord#_indexLookup",
    "access": null,
    "description": null,
    "lineNumber": 42,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 157,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "toJSON",
    "memberof": "lib/database-change-record.js~DatabaseChangeRecord",
    "longname": "lib/database-change-record.js~DatabaseChangeRecord#toJSON",
    "access": null,
    "description": null,
    "lineNumber": 61,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 158,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_objectsString",
    "memberof": "lib/database-change-record.js~DatabaseChangeRecord",
    "longname": "lib/database-change-record.js~DatabaseChangeRecord#_objectsString",
    "access": null,
    "description": null,
    "lineNumber": 62,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 159,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/database-setup-query-builder.js",
    "memberof": null,
    "longname": "lib/database-setup-query-builder.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint global-require:0 */\nimport ModelRegistry from './model-registry';\nimport {tableNameForJoin} from './utils';\nimport Attributes from './attributes';\n\nconst {AttributeCollection, AttributeJoinedData} = Attributes;\n\n/**\nThe factory methods in this class assemble SQL queries that build Model\ntables based on their attribute schema.\n\n@private\n*/\nexport default class DatabaseSetupQueryBuilder {\n\n  setupQueries() {\n    let queries = []\n    for (const klass of ModelRegistry.getAllConstructors()) {\n      queries = queries.concat(this.setupQueriesForTable(klass));\n    }\n    return queries;\n  }\n\n  analyzeQueries() {\n    const queries = [];\n\n    for (const klass of ModelRegistry.getAllConstructors()) {\n      const attributes = Object.keys(klass.attributes).map(k => klass.attributes[k]);\n      const collectionAttributes = attributes.filter((attr) =>\n        attr.queryable && attr instanceof AttributeCollection\n      )\n\n      queries.push(`ANALYZE \\`${klass.name}\\``);\n      collectionAttributes.forEach((attribute) => {\n        queries.push(`ANALYZE \\`${tableNameForJoin(klass, attribute.itemClass)}\\``)\n      });\n    }\n    return queries;\n  }\n\n  setupQueriesForTable(klass) {\n    const attributes = Object.keys(klass.attributes).map(k => klass.attributes[k]);\n    let queries = [];\n\n    // Identify attributes of this class that can be matched against. These\n    // attributes need their own columns in the table\n    const columnAttributes = attributes.filter(attr =>\n      attr.queryable && attr.columnSQL && attr.jsonKey !== 'id'\n    );\n\n    const columns = ['id TEXT PRIMARY KEY', 'data BLOB']\n    columnAttributes.forEach(attr => columns.push(attr.columnSQL()));\n\n    const columnsSQL = columns.join(',');\n    queries.unshift(`CREATE TABLE IF NOT EXISTS \\`${klass.name}\\` (${columnsSQL})`);\n    queries.push(`CREATE UNIQUE INDEX IF NOT EXISTS \\`${klass.name}_id\\` ON \\`${klass.name}\\` (\\`id\\`)`);\n\n    // Identify collection attributes that can be matched against. These require\n    // JOIN tables. (Right now the only one of these is Thread.folders or\n    // Thread.categories)\n    const collectionAttributes = attributes.filter(attr =>\n      attr.queryable && attr instanceof AttributeCollection\n    );\n    collectionAttributes.forEach((attribute) => {\n      const joinTable = tableNameForJoin(klass, attribute.itemClass);\n      const joinColumns = attribute.joinQueryableBy.map((name) =>\n        klass.attributes[name].columnSQL()\n      );\n      joinColumns.unshift('id TEXT KEY', '`value` TEXT');\n\n      queries.push(`CREATE TABLE IF NOT EXISTS \\`${joinTable}\\` (${joinColumns.join(',')})`);\n      queries.push(`CREATE INDEX IF NOT EXISTS \\`${joinTable.replace('-', '_')}_id\\` ON \\`${joinTable}\\` (\\`id\\` ASC)`);\n      queries.push(`CREATE UNIQUE INDEX IF NOT EXISTS \\`${joinTable.replace('-', '_')}_val_id\\` ON \\`${joinTable}\\` (\\`value\\` ASC, \\`id\\` ASC)`);\n    });\n\n    const joinedDataAttributes = attributes.filter(attr =>\n      attr instanceof AttributeJoinedData\n    )\n\n    joinedDataAttributes.forEach((attribute) => {\n      queries.push(`CREATE TABLE IF NOT EXISTS \\`${attribute.modelTable}\\` (id TEXT PRIMARY KEY, \\`value\\` TEXT)`);\n    });\n\n    if (klass.additionalSQLiteConfig && klass.additionalSQLiteConfig.setup) {\n      queries = queries.concat(klass.additionalSQLiteConfig.setup());\n    }\n\n    if (klass.searchable === true) {\n      queries.push(this.createSearchIndexSql(klass));\n    }\n\n    return queries;\n  }\n\n  createSearchIndexSql(klass) {\n    if (!klass) {\n      throw new Error(`RxDatabase::createSearchIndex - You must provide a class`);\n    }\n    if (!klass.searchFields) {\n      throw new Error(`RxDatabase::createSearchIndex - ${klass.name} must expose an array of \\`searchFields\\``);\n    }\n    const searchTableName = `${klass.name}Search`;\n    const searchFields = klass.searchFields;\n    return (\n      `CREATE VIRTUAL TABLE IF NOT EXISTS \\`${searchTableName}\\` ` +\n      `USING fts5(\n        tokenize='porter unicode61',\n        content_id UNINDEXED,\n        ${searchFields.join(', ')}\n      )`\n    );\n  }\n}\n"
  },
  {
    "__docId__": 160,
    "kind": "variable",
    "static": true,
    "variation": null,
    "name": "AttributeCollection",
    "memberof": "lib/database-setup-query-builder.js",
    "longname": "lib/database-setup-query-builder.js~AttributeCollection",
    "access": null,
    "export": false,
    "importPath": "electron-coresqlite/lib/database-setup-query-builder.js",
    "importStyle": null,
    "description": null,
    "lineNumber": 6,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 161,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "DatabaseSetupQueryBuilder",
    "memberof": "lib/database-setup-query-builder.js",
    "longname": "lib/database-setup-query-builder.js~DatabaseSetupQueryBuilder",
    "access": "private",
    "export": true,
    "importPath": "electron-coresqlite/lib/database-setup-query-builder.js",
    "importStyle": "DatabaseSetupQueryBuilder",
    "description": "The factory methods in this class assemble SQL queries that build Model\ntables based on their attribute schema.",
    "lineNumber": 14,
    "interface": false
  },
  {
    "__docId__": 162,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "setupQueries",
    "memberof": "lib/database-setup-query-builder.js~DatabaseSetupQueryBuilder",
    "longname": "lib/database-setup-query-builder.js~DatabaseSetupQueryBuilder#setupQueries",
    "access": null,
    "description": null,
    "lineNumber": 16,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 163,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "analyzeQueries",
    "memberof": "lib/database-setup-query-builder.js~DatabaseSetupQueryBuilder",
    "longname": "lib/database-setup-query-builder.js~DatabaseSetupQueryBuilder#analyzeQueries",
    "access": null,
    "description": null,
    "lineNumber": 24,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 164,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "setupQueriesForTable",
    "memberof": "lib/database-setup-query-builder.js~DatabaseSetupQueryBuilder",
    "longname": "lib/database-setup-query-builder.js~DatabaseSetupQueryBuilder#setupQueriesForTable",
    "access": null,
    "description": null,
    "lineNumber": 41,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 165,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "createSearchIndexSql",
    "memberof": "lib/database-setup-query-builder.js~DatabaseSetupQueryBuilder",
    "longname": "lib/database-setup-query-builder.js~DatabaseSetupQueryBuilder#createSearchIndexSql",
    "access": null,
    "description": null,
    "lineNumber": 95,
    "undocument": true,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 166,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/database-transaction.js",
    "memberof": null,
    "longname": "lib/database-transaction.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint global-require:0 */\n/* eslint import/newline-after-import:0 */\nimport Model from './model';\nimport {tableNameForJoin} from './utils';\n\nimport Attributes from './attributes';\nimport DatabaseChangeRecord from './database-change-record';\n\nrequire('promise.prototype.finally').shim();\nrequire('promise.try').shim()\n\nconst {AttributeCollection, AttributeJoinedData} = Attributes;\n\n/**\nDatabaseTransaction exposes a convenient API for querying and modifying an RxDB\nwithin a SQLite transaction.\n\nYou shouldn't need to instantiate this class directly. Instead, use\nRxDatabase#inTransaction.\n*/\nexport default class DatabaseTransaction {\n  constructor(database) {\n    this.database = database;\n    this._changeRecords = [];\n    this._opened = false;\n  }\n\n  /**\n  @borrows RxDatabase#find\n  */\n  find(...args) { return this.database.find(...args) }\n  findBy(...args) { return this.database.findBy(...args) }\n  findAll(...args) { return this.database.findAll(...args) }\n  modelify(...args) { return this.database.modelify(...args) }\n  count(...args) { return this.database.count(...args) }\n  findJSONBlob(...args) { return this.database.findJSONBlob(...args) }\n\n  execute(fn) {\n    if (this._opened) {\n      throw new Error(\"DatabaseTransaction:execute was already called\");\n    }\n\n    return this._query(\"BEGIN IMMEDIATE TRANSACTION\").then(() => {\n      this._opened = true;\n      return fn(this);\n    }).finally(() => {\n      if (!this._opened) {\n        return null;\n      }\n      this._opened = false;\n      return this._query(\"COMMIT\").then(() => {\n        this.database.transactionDidCommitChanges(this._changeRecords);\n      });\n    });\n  }\n\n  // Mutating the Database\n\n  persistJSONBlob(id, json) {\n    const JSONBlob = require('./json-blob').default;\n    return this.persistModel(new JSONBlob({id, json}));\n  }\n\n  /**\n  Asynchronously writes `model` to the cache and triggers a change event.\n\n  @param {Model} model - A {Model} to write to the database.\n\n  @returns {Promise} - A promise that:\n    - resolves after the database queries are complete and any listening\n      database callbacks have finished\n    - rejects if any databse query fails or one of the triggering\n      callbacks failed\n  */\n  persistModel(model) {\n    if (!model || !(model instanceof Model)) {\n      throw new Error(\"DatabaseTransaction::persistModel - You must pass an instance of the Model class.\");\n    }\n    return this.persistModels([model]);\n  }\n\n  /**\n  Asynchronously writes `models` to the cache and triggers a single change\n  event. Note: Models must be of the same class to be persisted in a batch operation.\n\n  @param {Array} models - An {Array} of {Model} objects to write to the database.\n\n  @returns {Promise} - A promise that:\n    - resolves after the database queries are complete and any listening\n      database callbacks have finished\n    - rejects if any databse query fails or one of the triggering\n      callbacks failed\n  */\n  persistModels(models = []) {\n    if (models.length === 0) {\n      return Promise.resolve();\n    }\n\n    const klass = models[0].constructor;\n    const clones = [];\n    const ids = {};\n\n    if (!(models[0] instanceof Model)) {\n      throw new Error(`DatabaseTransaction::persistModels - You must pass an array of items which descend from the Model class.`);\n    }\n\n    for (const model of models) {\n      if (!model || (model.constructor !== klass)) {\n        throw new Error(`DatabaseTransaction::persistModels - When you batch persist objects, they must be of the same type`);\n      }\n      if (ids[model.id]) {\n        throw new Error(`DatabaseTransaction::persistModels - You must pass an array of models with different ids. ID ${model.id} is in the set multiple times.`)\n      }\n      clones.push(model.clone());\n      ids[model.id] = true;\n    }\n\n    // Note: It's important that we clone the objects since other code could mutate\n    // them during the save process. We want to guaruntee that the models you send to\n    // persistModels are saved exactly as they were sent.\n    const metadata = {\n      objectClass: clones[0].constructor.name,\n      objectIds: Object.keys(ids),\n      objects: clones,\n      type: 'persist',\n    };\n\n    return this._runMutationHooks('beforeDatabaseChange', metadata).then((data) => {\n      return this._writeModels(clones).then(() => {\n        this._runMutationHooks('afterDatabaseChange', metadata, data);\n        return this._changeRecords.push(new DatabaseChangeRecord(this.database, metadata));\n      });\n    });\n  }\n\n  /**\n  Asynchronously removes `model` from the cache and triggers a change event.\n\n  @param {Model} model - A {Model} to write to the database.\n\n  @returns {Promise} - A promise that\n    - resolves after the database queries are complete and any listening\n      database callbacks have finished\n    - rejects if any databse query fails or one of the triggering\n      callbacks failed\n  */\n  unpersistModel(model) {\n    const clone = model.clone();\n    const metadata = {\n      objectClass: clone.constructor.name,\n      objectIds: [clone.id],\n      objects: [clone],\n      type: 'unpersist',\n    }\n\n    return this._runMutationHooks('beforeDatabaseChange', metadata).then((data) => {\n      return this._deleteModel(clone).then(() => {\n        this._runMutationHooks('afterDatabaseChange', metadata, data);\n        return this._changeRecords.push(new DatabaseChangeRecord(this.database, metadata));\n      });\n    });\n  }\n\n  // PRIVATE METHODS ////////////////////////////////////////////////////////\n\n  _query = (...args) => {\n    return this.database._query(...args);\n  }\n\n  _runMutationHooks(selectorName, metadata, data = []) {\n    const beforePromises = this.database.mutationHooks().map((hook, idx) =>\n      Promise.try(() => hook[selectorName](this._query, metadata, data[idx]))\n    );\n\n    return Promise.all(beforePromises).catch((e) => {\n      if (!process.env.CI) {\n        console.warn(`DatabaseTransaction Hook: ${selectorName} failed`, e);\n      }\n      return Promise.resolve([]);\n    });\n  }\n\n  // Fires the queries required to write models to the DB\n  //\n  // Returns a promise that:\n  //   - resolves when all write queries are complete\n  //   - rejects if any query fails\n  _writeModels(models) {\n    const promises = [];\n\n    // IMPORTANT: This method assumes that all the models you\n    // provide are of the same class, and have different ids!\n\n    // Avoid trying to write too many objects a time - sqlite can only handle\n    // value sets `(?,?)...` of less than SQLITE_MAX_COMPOUND_SELECT (500),\n    // and we don't know ahead of time whether we'll hit that or not.\n    if (models.length > 50) {\n      return Promise.all([\n        this._writeModels(models.slice(0, 50)),\n        this._writeModels(models.slice(50)),\n      ]);\n    }\n\n    const klass = models[0].constructor;\n    const attributes = Object.keys(klass.attributes).map(key => klass.attributes[key])\n\n    const columnAttributes = attributes.filter((attr) =>\n      attr.queryable && attr.columnSQL && attr.jsonKey !== 'id'\n    );\n\n    // Compute the columns in the model table and a question mark string\n    const columns = ['id', 'data'];\n    const columnMarks = ['?', '?'];\n    columnAttributes.forEach((attr) => {\n      columns.push(attr.jsonKey);\n      columnMarks.push('?');\n    });\n    const columnsSQL = columns.join(',');\n    const marksSet = `(${columnMarks.join(',')})`;\n\n    // Prepare a batch insert VALUES (?,?,?), (?,?,?)... by assembling\n    // an array of the values and a corresponding question mark set\n    const values = [];\n    const marks = [];\n    const ids = [];\n    const modelsJSONs = [];\n    for (const model of models) {\n      const json = model.toJSON({joined: false});\n      modelsJSONs.push(json);\n      ids.push(model.id);\n      values.push(model.id, JSON.stringify(json, this.database.models.JSONReplacer));\n      columnAttributes.forEach((attr) => {\n        values.push(json[attr.jsonKey]);\n      });\n      marks.push(marksSet);\n    }\n\n    const marksSQL = marks.join(',');\n\n    promises.push(this._query(`REPLACE INTO \\`${klass.name}\\` (${columnsSQL}) VALUES ${marksSQL}`, values));\n\n    // For each join table property, find all the items in the join table for this\n    // model and delete them. Insert each new value back into the table.\n    const collectionAttributes = attributes.filter((attr) =>\n      attr.queryable && attr instanceof AttributeCollection\n    )\n\n    collectionAttributes.forEach((attr) => {\n      const joinTable = tableNameForJoin(klass, attr.itemClass);\n\n      promises.push(this._query(`DELETE FROM \\`${joinTable}\\` WHERE \\`id\\` IN ('${ids.join(\"','\")}')`));\n\n      const joinMarks = [];\n      const joinedValues = [];\n      const joinMarkUnit = `(${[\"?\", \"?\"].concat(attr.joinQueryableBy.map(() => '?')).join(',')})`;\n      const joinQueryableByJSONKeys = attr.joinQueryableBy.map(joinedModelKey =>\n        klass.attributes[joinedModelKey].jsonKey\n      );\n      const joinColumns = ['id', 'value'].concat(joinQueryableByJSONKeys);\n\n      // https://www.sqlite.org/limits.html: SQLITE_MAX_VARIABLE_NUMBER\n      const valuesPerRow = joinColumns.length;\n      const rowsPerInsert = Math.floor(600 / valuesPerRow);\n      const valuesPerInsert = rowsPerInsert * valuesPerRow;\n\n      models.forEach((model, idx) => {\n        const joinedModels = model[attr.modelKey] || [];\n        for (const joined of joinedModels) {\n          if (!attr.joinOnField) {\n            throw new Error(`Queryable collection attribute ${attr.modelKey} must specify a joinOnField`);\n          }\n          const joinValue = joined[attr.joinOnField];\n          joinMarks.push(joinMarkUnit);\n          joinedValues.push(model.id, joinValue);\n          for (const joinedJsonKey of joinQueryableByJSONKeys) {\n            joinedValues.push(modelsJSONs[idx][joinedJsonKey]);\n          }\n        }\n      });\n\n      if (joinedValues.length !== 0) {\n        // Write no more than 200 items (400 values) at once to avoid sqlite limits\n        // 399 values: slices:[0..0]\n        // 400 values: slices:[0..0]\n        // 401 values: slices:[0..1]\n        const slicePageCount = Math.ceil(joinMarks.length / rowsPerInsert) - 1;\n        for (let slice = 0; slice <= slicePageCount; slice++) {\n          const [ms, me] = [slice * rowsPerInsert, slice * rowsPerInsert + rowsPerInsert];\n          const [vs, ve] = [slice * valuesPerInsert, slice * valuesPerInsert + valuesPerInsert];\n          promises.push(this._query(`INSERT OR IGNORE INTO \\`${joinTable}\\` (\\`${joinColumns.join('`,`')}\\`) VALUES ${joinMarks.slice(ms, me).join(',')}`, joinedValues.slice(vs, ve)));\n        }\n      }\n    });\n\n    // For each joined data property stored in another table...\n    const joinedDataAttributes = attributes.filter(attr =>\n      attr instanceof AttributeJoinedData\n    )\n\n    joinedDataAttributes.forEach((attr) => {\n      for (const model of models) {\n        if (model[attr.modelKey] !== undefined) {\n          promises.push(this._query(`REPLACE INTO \\`${attr.modelTable}\\` (\\`id\\`, \\`value\\`) VALUES (?, ?)`, [model.id, model[attr.modelKey]]));\n        }\n      }\n    });\n\n    return Promise.all(promises);\n  }\n\n  // Fires the queries required to delete models to the DB\n  //\n  // Returns a promise that:\n  //   - resolves when all deltion queries are complete\n  //   - rejects if any query fails\n  _deleteModel(model) {\n    const promises = []\n\n    const klass = model.constructor;\n    const attributes = Object.keys(klass.attributes).map(key => klass.attributes[key]);\n\n    // Delete the primary record\n    promises.push(this._query(`DELETE FROM \\`${klass.name}\\` WHERE \\`id\\` = ?`, [model.id]))\n\n    // For each join table property, find all the items in the join table for this\n    // model and delte them. Insert each new value back into the table.\n    const collectionAttributes = attributes.filter(attr =>\n      attr.queryable && attr instanceof AttributeCollection\n    );\n\n    collectionAttributes.forEach((attr) => {\n      const joinTable = tableNameForJoin(klass, attr.itemClass);\n      promises.push(this._query(`DELETE FROM \\`${joinTable}\\` WHERE \\`id\\` = ?`, [model.id]))\n    });\n\n    const joinedDataAttributes = attributes.filter(attr =>\n      attr instanceof AttributeJoinedData\n    );\n\n    joinedDataAttributes.forEach((attr) => {\n      promises.push(this._query(`DELETE FROM \\`${attr.modelTable}\\` WHERE \\`id\\` = ?`, [model.id]));\n    });\n\n    return Promise.all(promises);\n  }\n}\n"
  },
  {
    "__docId__": 167,
    "kind": "variable",
    "static": true,
    "variation": null,
    "name": "AttributeCollection",
    "memberof": "lib/database-transaction.js",
    "longname": "lib/database-transaction.js~AttributeCollection",
    "access": null,
    "export": false,
    "importPath": "electron-coresqlite/lib/database-transaction.js",
    "importStyle": null,
    "description": null,
    "lineNumber": 12,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 168,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "DatabaseTransaction",
    "memberof": "lib/database-transaction.js",
    "longname": "lib/database-transaction.js~DatabaseTransaction",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/database-transaction.js",
    "importStyle": "DatabaseTransaction",
    "description": "DatabaseTransaction exposes a convenient API for querying and modifying an RxDB\nwithin a SQLite transaction.\n\nYou shouldn't need to instantiate this class directly. Instead, use\nRxDatabase#inTransaction.",
    "lineNumber": 21,
    "interface": false
  },
  {
    "__docId__": 169,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#constructor",
    "access": null,
    "description": null,
    "lineNumber": 22,
    "undocument": true,
    "params": [
      {
        "name": "database",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 170,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "database",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#database",
    "access": null,
    "description": null,
    "lineNumber": 23,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 171,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_changeRecords",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#_changeRecords",
    "access": null,
    "description": null,
    "lineNumber": 24,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 172,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_opened",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#_opened",
    "access": null,
    "description": null,
    "lineNumber": 25,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 173,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "find",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#find",
    "access": null,
    "description": "",
    "lineNumber": 31,
    "unknown": [
      {
        "tagName": "@borrows",
        "tagValue": "RxDatabase#find"
      }
    ],
    "params": [
      {
        "name": "args",
        "types": [
          "...*"
        ],
        "spread": true
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 174,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "findBy",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#findBy",
    "access": null,
    "description": null,
    "lineNumber": 32,
    "undocument": true,
    "params": [
      {
        "name": "args",
        "types": [
          "...*"
        ],
        "spread": true
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 175,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "findAll",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#findAll",
    "access": null,
    "description": null,
    "lineNumber": 33,
    "undocument": true,
    "params": [
      {
        "name": "args",
        "types": [
          "...*"
        ],
        "spread": true
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 176,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "modelify",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#modelify",
    "access": null,
    "description": null,
    "lineNumber": 34,
    "undocument": true,
    "params": [
      {
        "name": "args",
        "types": [
          "...*"
        ],
        "spread": true
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 177,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "count",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#count",
    "access": null,
    "description": null,
    "lineNumber": 35,
    "undocument": true,
    "params": [
      {
        "name": "args",
        "types": [
          "...*"
        ],
        "spread": true
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 178,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "findJSONBlob",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#findJSONBlob",
    "access": null,
    "description": null,
    "lineNumber": 36,
    "undocument": true,
    "params": [
      {
        "name": "args",
        "types": [
          "...*"
        ],
        "spread": true
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 179,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "execute",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#execute",
    "access": null,
    "description": null,
    "lineNumber": 38,
    "undocument": true,
    "params": [
      {
        "name": "fn",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 180,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_opened",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#_opened",
    "access": null,
    "description": null,
    "lineNumber": 44,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 181,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_opened",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#_opened",
    "access": null,
    "description": null,
    "lineNumber": 50,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 182,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "persistJSONBlob",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#persistJSONBlob",
    "access": null,
    "description": null,
    "lineNumber": 59,
    "undocument": true,
    "params": [
      {
        "name": "id",
        "types": [
          "*"
        ]
      },
      {
        "name": "json",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 183,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "persistModel",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#persistModel",
    "access": null,
    "description": "Asynchronously writes `model` to the cache and triggers a change event.",
    "lineNumber": 75,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Promise} - A promise that:\n- resolves after the database queries are complete and any listening\ndatabase callbacks have finished\n- rejects if any databse query fails or one of the triggering\ncallbacks failed"
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Model"
        ],
        "spread": false,
        "optional": false,
        "name": "model",
        "description": "A {Model} to write to the database."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Promise"
      ],
      "spread": false,
      "description": "A promise that:\n- resolves after the database queries are complete and any listening\ndatabase callbacks have finished\n- rejects if any databse query fails or one of the triggering\ncallbacks failed"
    },
    "generator": false
  },
  {
    "__docId__": 184,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "persistModels",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#persistModels",
    "access": null,
    "description": "Asynchronously writes `models` to the cache and triggers a single change\nevent. Note: Models must be of the same class to be persisted in a batch operation.",
    "lineNumber": 94,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Promise} - A promise that:\n- resolves after the database queries are complete and any listening\ndatabase callbacks have finished\n- rejects if any databse query fails or one of the triggering\ncallbacks failed"
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Array"
        ],
        "spread": false,
        "optional": false,
        "name": "models",
        "description": "An {Array} of {Model} objects to write to the database."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Promise"
      ],
      "spread": false,
      "description": "A promise that:\n- resolves after the database queries are complete and any listening\ndatabase callbacks have finished\n- rejects if any databse query fails or one of the triggering\ncallbacks failed"
    },
    "generator": false
  },
  {
    "__docId__": 185,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "unpersistModel",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#unpersistModel",
    "access": null,
    "description": "Asynchronously removes `model` from the cache and triggers a change event.",
    "lineNumber": 147,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Promise} - A promise that\n- resolves after the database queries are complete and any listening\ndatabase callbacks have finished\n- rejects if any databse query fails or one of the triggering\ncallbacks failed"
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Model"
        ],
        "spread": false,
        "optional": false,
        "name": "model",
        "description": "A {Model} to write to the database."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Promise"
      ],
      "spread": false,
      "description": "A promise that\n- resolves after the database queries are complete and any listening\ndatabase callbacks have finished\n- rejects if any databse query fails or one of the triggering\ncallbacks failed"
    },
    "generator": false
  },
  {
    "__docId__": 186,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_runMutationHooks",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#_runMutationHooks",
    "access": null,
    "description": null,
    "lineNumber": 170,
    "undocument": true,
    "params": [
      {
        "name": "selectorName",
        "types": [
          "*"
        ]
      },
      {
        "name": "metadata",
        "types": [
          "*"
        ]
      },
      {
        "name": "data",
        "optional": true,
        "types": [
          "*[]"
        ],
        "defaultRaw": [],
        "defaultValue": "[]"
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 187,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_writeModels",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#_writeModels",
    "access": null,
    "description": null,
    "lineNumber": 188,
    "undocument": true,
    "params": [
      {
        "name": "models",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 188,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_deleteModel",
    "memberof": "lib/database-transaction.js~DatabaseTransaction",
    "longname": "lib/database-transaction.js~DatabaseTransaction#_deleteModel",
    "access": null,
    "description": null,
    "lineNumber": 316,
    "undocument": true,
    "params": [
      {
        "name": "model",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 189,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/json-blob.js",
    "memberof": null,
    "longname": "lib/json-blob.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import Model from './model';\nimport Query from './query';\nimport Attributes from './attributes';\n\nclass JSONBlobQuery extends Query {\n  formatResult(objects) {\n    return objects[0] ? objects[0].json : null;\n  }\n}\n\nexport default class JSONBlob extends Model {\n  static Query = JSONBlobQuery;\n\n  static attributes = {\n    id: Attributes.String({\n      queryable: true,\n      modelKey: 'id',\n    }),\n\n    json: Attributes.Object({\n      modelKey: 'json',\n      jsonKey: 'json',\n    }),\n  };\n\n  get key() {\n    return this.id;\n  }\n\n  set key(val) {\n    this.id = val;\n  }\n}\n"
  },
  {
    "__docId__": 190,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "JSONBlobQuery",
    "memberof": "lib/json-blob.js",
    "longname": "lib/json-blob.js~JSONBlobQuery",
    "access": null,
    "export": false,
    "importPath": "electron-coresqlite/lib/json-blob.js",
    "importStyle": null,
    "description": null,
    "lineNumber": 5,
    "undocument": true,
    "interface": false,
    "extends": [
      "lib/query.js~Query"
    ]
  },
  {
    "__docId__": 191,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "formatResult",
    "memberof": "lib/json-blob.js~JSONBlobQuery",
    "longname": "lib/json-blob.js~JSONBlobQuery#formatResult",
    "access": null,
    "description": null,
    "lineNumber": 6,
    "undocument": true,
    "params": [
      {
        "name": "objects",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 192,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "JSONBlob",
    "memberof": "lib/json-blob.js",
    "longname": "lib/json-blob.js~JSONBlob",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/json-blob.js",
    "importStyle": "JSONBlob",
    "description": null,
    "lineNumber": 11,
    "undocument": true,
    "interface": false,
    "extends": [
      "lib/model.js~Model"
    ]
  },
  {
    "__docId__": 193,
    "kind": "get",
    "static": false,
    "variation": null,
    "name": "key",
    "memberof": "lib/json-blob.js~JSONBlob",
    "longname": "lib/json-blob.js~JSONBlob#key",
    "access": null,
    "description": null,
    "lineNumber": 26,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 194,
    "kind": "set",
    "static": false,
    "variation": null,
    "name": "key",
    "memberof": "lib/json-blob.js~JSONBlob",
    "longname": "lib/json-blob.js~JSONBlob#key",
    "access": null,
    "description": null,
    "lineNumber": 30,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 195,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "id",
    "memberof": "lib/json-blob.js~JSONBlob",
    "longname": "lib/json-blob.js~JSONBlob#id",
    "access": null,
    "description": null,
    "lineNumber": 31,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 196,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/model-registry.js",
    "memberof": null,
    "longname": "lib/model-registry.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import Model from './model';\n\n/**\nThis keeps track of constructors so we know how to inflate\nserialized objects.\n\nWe map constructor string names with factory functions that will return\nthe actual constructor itself.\n\nThe reason we have an extra function call to return a constructor is so\nwe don't need to `require` all constructors at once on load. We are\nwasting a very large amount of time on bootup requiring files that may\nnever be used or only used way down the line.\n\nIf 3rd party packages want to register new inflatable models, they can\nuse `register` and pass the constructor generator along with the name.\n\nNote that there is one registry per window.\n\n@private\n*/\nexport default class ModelRegistry {\n  constructor() {\n    this._classMap = {};\n\n    const registry = this;\n\n    this.JSONReviver = function JSONReviver(k, v) {\n      const type = v ? v.__constructorName : null;\n      if (!type) {\n        return v;\n      }\n\n      if (registry.has(type)) {\n        return registry.deserialize(type, v);\n      }\n\n      return v;\n    }\n\n    this.JSONReplacer = function JSONReplacer(k, v) {\n      if (v instanceof Object) {\n        const type = this[k].constructor.name;\n        if (registry.has(type)) {\n          v.__constructorName = type;\n        }\n      }\n      return v;\n    }\n  }\n\n  /**\n  @param {String} name - The name of the class\n  @returns {Model} - The Model subclass with the given name.\n  */\n  get(name) {\n    return this._classMap[name].call(null);\n  }\n\n  getAllConstructors() {\n    return Object.keys(this._classMap).map((name) => this.get(name))\n  }\n\n  /**\n  @param {String} name - The name of the class.\n  @returns {Boolean} - True if a class with the given name has been registered.\n  */\n  has(name) {\n    return !!this._classMap[name];\n  }\n\n  /**\n  Add a Model class so that it can be used with an RxDB database.\n\n  @param {Model} klass - The subclass of Model to register\n  */\n  register(klass) {\n    this.registerDeferred({\n      name: klass.constructor.name,\n      resolver: () => klass,\n    })\n  }\n\n  /**\n  Add a Model class without requiring it immediately. Provide the name of\n  the class and a resolver function that returns it upon request.\n\n  The resolver will not be invoked until an instance of the class is needed\n  for the first time, which can improve load time.\n\n  @param {String} name - The class name\n  @param {Function} resolver - A function that will return the class. Generally,\n    this function calls `require`.\n  */\n  registerDeferred({name, resolver}) {\n    this._classMap[name] = resolver;\n  }\n\n  /**\n  Remove a Model class.\n  */\n  unregister(name) {\n    delete this._classMap[name];\n  }\n\n  /**\n  @private\n  */\n  deserialize(name, dataJSON) {\n    let data = dataJSON;\n    if (typeof data === \"string\") {\n      data = JSON.parse(dataJSON);\n    }\n\n    const constructor = this.get(name);\n\n    if (typeof constructor !== \"function\") {\n      throw new Error(`ModelRegistry: Unsure of how to inflate ${JSON.stringify(data)}. Your constructor factory must return a class constructor.`);\n    }\n\n    const object = new constructor();\n    if (!(object instanceof Model)) {\n      throw new Error(`ModelRegistry: ${name} is not a subclass of RxDB.Model.`);\n    }\n    object.fromJSON(data);\n\n    return object;\n  }\n}\n"
  },
  {
    "__docId__": 197,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "ModelRegistry",
    "memberof": "lib/model-registry.js",
    "longname": "lib/model-registry.js~ModelRegistry",
    "access": "private",
    "export": true,
    "importPath": "electron-coresqlite/lib/model-registry.js",
    "importStyle": "ModelRegistry",
    "description": "This keeps track of constructors so we know how to inflate\nserialized objects.\n\nWe map constructor string names with factory functions that will return\nthe actual constructor itself.\n\nThe reason we have an extra function call to return a constructor is so\nwe don't need to `require` all constructors at once on load. We are\nwasting a very large amount of time on bootup requiring files that may\nnever be used or only used way down the line.\n\nIf 3rd party packages want to register new inflatable models, they can\nuse `register` and pass the constructor generator along with the name.\n\nNote that there is one registry per window.",
    "lineNumber": 22,
    "interface": false
  },
  {
    "__docId__": 198,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/model-registry.js~ModelRegistry",
    "longname": "lib/model-registry.js~ModelRegistry#constructor",
    "access": null,
    "description": null,
    "lineNumber": 23,
    "undocument": true,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 199,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_classMap",
    "memberof": "lib/model-registry.js~ModelRegistry",
    "longname": "lib/model-registry.js~ModelRegistry#_classMap",
    "access": null,
    "description": null,
    "lineNumber": 24,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 200,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "get",
    "memberof": "lib/model-registry.js~ModelRegistry",
    "longname": "lib/model-registry.js~ModelRegistry#get",
    "access": null,
    "description": "",
    "lineNumber": 56,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Model} - The Model subclass with the given name."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "String"
        ],
        "spread": false,
        "optional": false,
        "name": "name",
        "description": "The name of the class"
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Model"
      ],
      "spread": false,
      "description": "The Model subclass with the given name."
    },
    "generator": false
  },
  {
    "__docId__": 201,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "getAllConstructors",
    "memberof": "lib/model-registry.js~ModelRegistry",
    "longname": "lib/model-registry.js~ModelRegistry#getAllConstructors",
    "access": null,
    "description": null,
    "lineNumber": 60,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 202,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "has",
    "memberof": "lib/model-registry.js~ModelRegistry",
    "longname": "lib/model-registry.js~ModelRegistry#has",
    "access": null,
    "description": "",
    "lineNumber": 68,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Boolean} - True if a class with the given name has been registered."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "String"
        ],
        "spread": false,
        "optional": false,
        "name": "name",
        "description": "The name of the class."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Boolean"
      ],
      "spread": false,
      "description": "True if a class with the given name has been registered."
    },
    "generator": false
  },
  {
    "__docId__": 203,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "register",
    "memberof": "lib/model-registry.js~ModelRegistry",
    "longname": "lib/model-registry.js~ModelRegistry#register",
    "access": null,
    "description": "Add a Model class so that it can be used with an RxDB database.",
    "lineNumber": 77,
    "params": [
      {
        "nullable": null,
        "types": [
          "Model"
        ],
        "spread": false,
        "optional": false,
        "name": "klass",
        "description": "The subclass of Model to register"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 204,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "registerDeferred",
    "memberof": "lib/model-registry.js~ModelRegistry",
    "longname": "lib/model-registry.js~ModelRegistry#registerDeferred",
    "access": null,
    "description": "Add a Model class without requiring it immediately. Provide the name of\nthe class and a resolver function that returns it upon request.\n\nThe resolver will not be invoked until an instance of the class is needed\nfor the first time, which can improve load time.",
    "lineNumber": 95,
    "params": [
      {
        "nullable": null,
        "types": [
          "String"
        ],
        "spread": false,
        "optional": false,
        "name": "name",
        "description": "The class name"
      },
      {
        "nullable": null,
        "types": [
          "Function"
        ],
        "spread": false,
        "optional": false,
        "name": "resolver",
        "description": "A function that will return the class. Generally,\nthis function calls `require`."
      }
    ],
    "generator": false
  },
  {
    "__docId__": 205,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "unregister",
    "memberof": "lib/model-registry.js~ModelRegistry",
    "longname": "lib/model-registry.js~ModelRegistry#unregister",
    "access": null,
    "description": "Remove a Model class.",
    "lineNumber": 102,
    "params": [
      {
        "name": "name",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 206,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "deserialize",
    "memberof": "lib/model-registry.js~ModelRegistry",
    "longname": "lib/model-registry.js~ModelRegistry#deserialize",
    "access": "private",
    "description": "",
    "lineNumber": 109,
    "params": [
      {
        "name": "name",
        "types": [
          "*"
        ]
      },
      {
        "name": "dataJSON",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 207,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/model.js",
    "memberof": null,
    "longname": "lib/model.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import Attributes from './attributes';\n\nfunction generateTempId() {\n  const s4 = () => Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);\n  return `local-${s4()}${s4()}-${s4()}`;\n}\n/**\nA base class for RxDB models that provides abstract support for JSON\nserialization and deserialization, and attribute-based matching.\n\nYour RxDB data classes should extend Model and extend it's attributes:\n\n- {AttributeString} id: The resolved canonical ID of the model used in the\ndatabase and generally throughout the app.\n\n*/\nexport default class Model {\n\n  static attributes = {\n    id: Attributes.String({\n      queryable: true,\n      modelKey: 'id',\n    }),\n  }\n\n  static naturalSortOrder() {\n    return null;\n  }\n\n  constructor(values = {}) {\n    for (const key of Object.keys(this.constructor.attributes)) {\n      this[key] = values[key];\n    }\n    this.id = this.id || generateTempId();\n  }\n\n  clone() {\n    return (new this.constructor()).fromJSON(this.toJSON())\n  }\n\n  // Public: Returns an {Array} of {Attribute} objects defined on the Model's constructor\n  //\n  attributes() {\n    return Object.assign({}, this.constructor.attributes)\n  }\n\n  // Public: Inflates the model object from JSON, using the defined attributes to\n  // guide type coercision.\n  //\n  // - `json` A plain Javascript {Object} with the JSON representation of the model.\n  //\n  // This method is chainable.\n  //\n  fromJSON(json) {\n    // Note: The loop in this function has been optimized for the V8 'fast case'\n    // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers\n    //\n    for (const key of Object.keys(this.constructor.attributes)) {\n      const attr = this.constructor.attributes[key];\n      const attrValue = json[attr.jsonKey];\n      if (attrValue !== undefined) {\n        this[key] = attr.fromJSON(attrValue);\n      }\n    }\n    return this;\n  }\n\n  // Public: Deflates the model to a plain JSON object. Only attributes defined\n  // on the model are included in the JSON.\n  //\n  // - `options` (optional) An {Object} with additional options. To skip joined\n  //    data attributes in the toJSON representation, pass the `joined:false`\n  //\n  // Returns an {Object} with the JSON representation of the model.\n  //\n  toJSON(options = {}) {\n    const json = {}\n    for (const key of Object.keys(this.constructor.attributes)) {\n      const attr = this.constructor.attributes[key];\n      const attrValue = this[key];\n\n      if (attrValue === undefined) {\n        continue;\n      }\n      if (attr instanceof Attributes.AttributeJoinedData && (options.joined === false)) {\n        continue;\n      }\n      json[attr.jsonKey] = attr.toJSON(attrValue);\n    }\n    return json;\n  }\n\n  toString() {\n    return JSON.stringify(this.toJSON());\n  }\n\n  // Public: Evaluates the model against one or more {Matcher} objects.\n  //\n  // - `criteria` An {Array} of {Matcher}s to run on the model.\n  //\n  // Returns true if the model matches the criteria.\n  //\n  matches(criteria) {\n    if (!(criteria instanceof Array)) {\n      return false;\n    }\n    for (const matcher of criteria) {\n      if (!matcher.evaluate(this)) {\n        return false;\n      }\n    }\n    return true;\n  }\n}\n"
  },
  {
    "__docId__": 208,
    "kind": "function",
    "static": true,
    "variation": null,
    "name": "generateTempId",
    "memberof": "lib/model.js",
    "longname": "lib/model.js~generateTempId",
    "access": null,
    "export": false,
    "importPath": "electron-coresqlite/lib/model.js",
    "importStyle": null,
    "description": null,
    "lineNumber": 3,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 209,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "Model",
    "memberof": "lib/model.js",
    "longname": "lib/model.js~Model",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/model.js",
    "importStyle": "Model",
    "description": "A base class for RxDB models that provides abstract support for JSON\nserialization and deserialization, and attribute-based matching.\n\nYour RxDB data classes should extend Model and extend it's attributes:\n\n- {AttributeString} id: The resolved canonical ID of the model used in the\ndatabase and generally throughout the app.",
    "lineNumber": 17,
    "interface": false
  },
  {
    "__docId__": 210,
    "kind": "method",
    "static": true,
    "variation": null,
    "name": "naturalSortOrder",
    "memberof": "lib/model.js~Model",
    "longname": "lib/model.js~Model.naturalSortOrder",
    "access": null,
    "description": null,
    "lineNumber": 26,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 211,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/model.js~Model",
    "longname": "lib/model.js~Model#constructor",
    "access": null,
    "description": null,
    "lineNumber": 30,
    "undocument": true,
    "params": [
      {
        "name": "values",
        "optional": true,
        "types": [
          "{}"
        ],
        "defaultRaw": {},
        "defaultValue": "{}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 212,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "id",
    "memberof": "lib/model.js~Model",
    "longname": "lib/model.js~Model#id",
    "access": null,
    "description": null,
    "lineNumber": 34,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 213,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "clone",
    "memberof": "lib/model.js~Model",
    "longname": "lib/model.js~Model#clone",
    "access": null,
    "description": null,
    "lineNumber": 37,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 214,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "attributes",
    "memberof": "lib/model.js~Model",
    "longname": "lib/model.js~Model#attributes",
    "access": null,
    "description": null,
    "lineNumber": 43,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 215,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "fromJSON",
    "memberof": "lib/model.js~Model",
    "longname": "lib/model.js~Model#fromJSON",
    "access": null,
    "description": null,
    "lineNumber": 54,
    "undocument": true,
    "params": [
      {
        "name": "json",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 216,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "toJSON",
    "memberof": "lib/model.js~Model",
    "longname": "lib/model.js~Model#toJSON",
    "access": null,
    "description": null,
    "lineNumber": 76,
    "undocument": true,
    "params": [
      {
        "name": "options",
        "optional": true,
        "types": [
          "{}"
        ],
        "defaultRaw": {},
        "defaultValue": "{}"
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 217,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "toString",
    "memberof": "lib/model.js~Model",
    "longname": "lib/model.js~Model#toString",
    "access": null,
    "description": null,
    "lineNumber": 93,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 218,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "matches",
    "memberof": "lib/model.js~Model",
    "longname": "lib/model.js~Model#matches",
    "access": null,
    "description": null,
    "lineNumber": 103,
    "undocument": true,
    "params": [
      {
        "name": "criteria",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "boolean"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 219,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/mutable-query-result-set.js",
    "memberof": null,
    "longname": "lib/mutable-query-result-set.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import QueryResultSet from './query-result-set';\nimport AttributeJoinedData from './attributes/attribute-joined-data';\n\n// TODO: Make mutator methods QueryResultSet.join(), QueryResultSet.clip...\nexport default class MutableQueryResultSet extends QueryResultSet {\n\n  immutableClone() {\n    const set = new QueryResultSet({\n      _ids: [].concat(this._ids),\n      _modelsHash: Object.assign({}, this._modelsHash),\n      _query: this._query,\n      _offset: this._offset,\n    });\n    Object.freeze(set._ids);\n    Object.freeze(set._modelsHash);\n    return set;\n  }\n\n  clipToRange(range) {\n    if (range.isInfinite()) {\n      return;\n    }\n    if (range.offset > this._offset) {\n      this._ids = this._ids.slice(range.offset - this._offset);\n      this._offset = range.offset;\n    }\n\n    const rangeEnd = range.offset + range.limit;\n    const selfEnd = this._offset + this._ids.length;\n    if (rangeEnd < selfEnd) {\n      this._ids.length = Math.max(0, rangeEnd - this._offset);\n    }\n\n    const models = this.models();\n    this._modelsHash = {};\n    this._idToIndexHash = null;\n    models.forEach((m) => this.updateModel(m));\n  }\n\n  addModelsInRange(rangeModels, range) {\n    this.addIdsInRange(rangeModels.map(m => m.id), range);\n    rangeModels.forEach((m) => this.updateModel(m));\n  }\n\n  addIdsInRange(rangeIds, range) {\n    if ((this._offset === null) || range.isInfinite()) {\n      this._ids = rangeIds;\n      this._idToIndexHash = null;\n      this._offset = range.offset;\n    } else {\n      const currentEnd = this._offset + this._ids.length;\n      const rangeIdsEnd = range.offset + rangeIds.length;\n\n      if (rangeIdsEnd < this._offset) {\n        throw new Error(`addIdsInRange: You can only add adjacent values (${rangeIdsEnd} < ${this._offset})`)\n      }\n      if (range.offset > currentEnd) {\n        throw new Error(`addIdsInRange: You can only add adjacent values (${range.offset} > ${currentEnd})`);\n      }\n\n      let existingBefore = []\n      if (range.offset > this._offset) {\n        existingBefore = this._ids.slice(0, range.offset - this._offset);\n      }\n\n      let existingAfter = []\n      if ((rangeIds.length === range.limit) && (currentEnd > rangeIdsEnd)) {\n        existingAfter = this._ids.slice(rangeIdsEnd - this._offset);\n      }\n\n      this._ids = [].concat(existingBefore, rangeIds, existingAfter);\n      this._idToIndexHash = null;\n      this._offset = Math.min(this._offset, range.offset);\n    }\n  }\n\n  updateModel(item) {\n    if (!item) {\n      return;\n    }\n\n    // Sometimes the new copy of `item` doesn't contain the joined data present\n    // in the old one, since it's not provided by default and may not have changed.\n    // Make sure we never drop joined data by pulling it over.\n    const existing = this._modelsHash[item.id];\n    if (existing) {\n      const attrs = existing.constructor.attributes\n      for (const key of Object.keys(attrs)) {\n        const attr = attrs[key];\n        if ((attr instanceof AttributeJoinedData) && (item[attr.modelKey] === undefined)) {\n          item[attr.modelKey] = existing[attr.modelKey];\n        }\n      }\n    }\n    this._modelsHash[item.id] = item;\n    this._idToIndexHash = null;\n  }\n\n  removeModelAtOffset(item, offset) {\n    const idx = offset - this._offset;\n    delete this._modelsHash[item.id];\n    this._ids.splice(idx, 1);\n    this._idToIndexHash = null;\n  }\n\n  setQuery(query) {\n    this._query = query.clone();\n    this._query.finalize();\n  }\n}\n"
  },
  {
    "__docId__": 220,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "MutableQueryResultSet",
    "memberof": "lib/mutable-query-result-set.js",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/mutable-query-result-set.js",
    "importStyle": "MutableQueryResultSet",
    "description": null,
    "lineNumber": 5,
    "undocument": true,
    "interface": false,
    "extends": [
      "lib/query-result-set.js~QueryResultSet"
    ]
  },
  {
    "__docId__": 221,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "immutableClone",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#immutableClone",
    "access": null,
    "description": null,
    "lineNumber": 7,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 222,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "clipToRange",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#clipToRange",
    "access": null,
    "description": null,
    "lineNumber": 19,
    "undocument": true,
    "params": [
      {
        "name": "range",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 223,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_ids",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_ids",
    "access": null,
    "description": null,
    "lineNumber": 24,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 224,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_offset",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_offset",
    "access": null,
    "description": null,
    "lineNumber": 25,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 225,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_modelsHash",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_modelsHash",
    "access": null,
    "description": null,
    "lineNumber": 35,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 226,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_idToIndexHash",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_idToIndexHash",
    "access": null,
    "description": null,
    "lineNumber": 36,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 227,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "addModelsInRange",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#addModelsInRange",
    "access": null,
    "description": null,
    "lineNumber": 40,
    "undocument": true,
    "params": [
      {
        "name": "rangeModels",
        "types": [
          "*"
        ]
      },
      {
        "name": "range",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 228,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "addIdsInRange",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#addIdsInRange",
    "access": null,
    "description": null,
    "lineNumber": 45,
    "undocument": true,
    "params": [
      {
        "name": "rangeIds",
        "types": [
          "*"
        ]
      },
      {
        "name": "range",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 229,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_ids",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_ids",
    "access": null,
    "description": null,
    "lineNumber": 47,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 230,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_idToIndexHash",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_idToIndexHash",
    "access": null,
    "description": null,
    "lineNumber": 48,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 231,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_offset",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_offset",
    "access": null,
    "description": null,
    "lineNumber": 49,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 232,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_ids",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_ids",
    "access": null,
    "description": null,
    "lineNumber": 71,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 233,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_idToIndexHash",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_idToIndexHash",
    "access": null,
    "description": null,
    "lineNumber": 72,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 234,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_offset",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_offset",
    "access": null,
    "description": null,
    "lineNumber": 73,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 235,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "updateModel",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#updateModel",
    "access": null,
    "description": null,
    "lineNumber": 77,
    "undocument": true,
    "params": [
      {
        "name": "item",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 236,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_idToIndexHash",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_idToIndexHash",
    "access": null,
    "description": null,
    "lineNumber": 96,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 237,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "removeModelAtOffset",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#removeModelAtOffset",
    "access": null,
    "description": null,
    "lineNumber": 99,
    "undocument": true,
    "params": [
      {
        "name": "item",
        "types": [
          "*"
        ]
      },
      {
        "name": "offset",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 238,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_idToIndexHash",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_idToIndexHash",
    "access": null,
    "description": null,
    "lineNumber": 103,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 239,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "setQuery",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#setQuery",
    "access": null,
    "description": null,
    "lineNumber": 106,
    "undocument": true,
    "params": [
      {
        "name": "query",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 240,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_query",
    "memberof": "lib/mutable-query-result-set.js~MutableQueryResultSet",
    "longname": "lib/mutable-query-result-set.js~MutableQueryResultSet#_query",
    "access": null,
    "description": null,
    "lineNumber": 107,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 241,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/mutable-query-subscription.js",
    "memberof": null,
    "longname": "lib/mutable-query-subscription.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import QuerySubscription from './query-subscription'\n\nclass MutableQuerySubscription extends QuerySubscription {\n\n  replaceQuery(nextQuery) {\n    if (this._query && this._query.sql() === nextQuery.sql()) {\n      return\n    }\n\n    let rangeIsOnlyChange = false;\n    if (this._query) {\n      rangeIsOnlyChange = this._query.clone().offset(0).limit(0).sql() === nextQuery.clone().offset(0).limit(0).sql()\n    }\n\n    this.cancelPendingUpdate()\n\n    nextQuery.finalize()\n    this._query = nextQuery\n    if (!(this._set && rangeIsOnlyChange)) {\n      this._set = null\n    }\n    this.update()\n  }\n\n  replaceRange = ({start, end}) => {\n    if (!this._query) {\n      return\n    }\n\n    const next = this._query.clone().page(start, end);\n    if (!next.range().isEqual(this._query.range())) {\n      this.replaceQuery(next);\n    }\n  }\n}\n\nexport default MutableQuerySubscription\n"
  },
  {
    "__docId__": 242,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "MutableQuerySubscription",
    "memberof": "lib/mutable-query-subscription.js",
    "longname": "lib/mutable-query-subscription.js~MutableQuerySubscription",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/mutable-query-subscription.js",
    "importStyle": "MutableQuerySubscription",
    "description": null,
    "lineNumber": 3,
    "undocument": true,
    "interface": false,
    "extends": [
      "lib/query-subscription.js~QuerySubscription"
    ]
  },
  {
    "__docId__": 243,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "replaceQuery",
    "memberof": "lib/mutable-query-subscription.js~MutableQuerySubscription",
    "longname": "lib/mutable-query-subscription.js~MutableQuerySubscription#replaceQuery",
    "access": null,
    "description": null,
    "lineNumber": 5,
    "undocument": true,
    "params": [
      {
        "name": "nextQuery",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 244,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_query",
    "memberof": "lib/mutable-query-subscription.js~MutableQuerySubscription",
    "longname": "lib/mutable-query-subscription.js~MutableQuerySubscription#_query",
    "access": null,
    "description": null,
    "lineNumber": 18,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 245,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_set",
    "memberof": "lib/mutable-query-subscription.js~MutableQuerySubscription",
    "longname": "lib/mutable-query-subscription.js~MutableQuerySubscription#_set",
    "access": null,
    "description": null,
    "lineNumber": 20,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 246,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/query-range.js",
    "memberof": null,
    "longname": "lib/query-range.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/**\nQueryRange represents a LIMIT + OFFSET pair and provides high-level methods\nfor comparing, copying and  joining ranges. It also provides syntax sugar\naround infinity (the absence of a defined LIMIT or OFFSET).\n*/\nexport default class QueryRange {\n  static infinite() {\n    return new QueryRange({limit: null, offset: null});\n  }\n\n  static rangeWithUnion(a, b) {\n    if (a.isInfinite() || b.isInfinite()) {\n      return QueryRange.infinite();\n    }\n    if (!a.isContiguousWith(b)) {\n      throw new Error('You cannot union ranges which do not touch or intersect.');\n    }\n\n    return new QueryRange({\n      start: Math.min(a.start, b.start),\n      end: Math.max(a.end, b.end),\n    });\n  }\n\n  static rangesBySubtracting(a, b) {\n    if (!b) {\n      return [];\n    }\n\n    if (a.isInfinite() || b.isInfinite()) {\n      throw new Error(\"You cannot subtract infinite ranges.\");\n    }\n\n    const uncovered = []\n    if (b.start > a.start) {\n      uncovered.push(new QueryRange({start: a.start, end: Math.min(a.end, b.start)}))\n    }\n    if (b.end < a.end) {\n      uncovered.push(new QueryRange({start: Math.max(a.start, b.end), end: a.end}));\n    }\n    return uncovered;\n  }\n\n  get start() {\n    return this.offset;\n  }\n\n  get end() {\n    return this.offset + this.limit;\n  }\n\n  constructor({limit, offset, start, end} = {}) {\n    this.limit = limit;\n    this.offset = offset;\n\n    if ((start !== undefined) && (offset === undefined)) {\n      this.offset = start;\n    }\n    if ((end !== undefined) && (limit === undefined)) {\n      this.limit = end - this.offset;\n    }\n\n    if (this.limit === undefined) {\n      throw new Error(\"You must specify a limit\");\n    }\n    if (this.offset === undefined) {\n      throw new Error(\"You must specify an offset\");\n    }\n  }\n\n  clone() {\n    const {limit, offset} = this;\n    return new QueryRange({limit, offset});\n  }\n\n  isInfinite() {\n    return (this.limit === null) && (this.offset === null);\n  }\n\n  isEqual(b) {\n    return (this.start === b.start) && (this.end === b.end);\n  }\n\n  // Returns true if joining the two ranges would not result in empty space.\n  // ie: they intersect or touch\n  isContiguousWith(b) {\n    if (this.isInfinite() || b.isInfinite()) {\n      return true;\n    }\n    return ((this.start <= b.start) && (b.start <= this.end)) || ((this.start <= b.end) && (b.end <= this.end));\n  }\n\n  toString() {\n    return `QueryRange{${this.start} - ${this.end}}`;\n  }\n}\n"
  },
  {
    "__docId__": 247,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "QueryRange",
    "memberof": "lib/query-range.js",
    "longname": "lib/query-range.js~QueryRange",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/query-range.js",
    "importStyle": "QueryRange",
    "description": "QueryRange represents a LIMIT + OFFSET pair and provides high-level methods\nfor comparing, copying and  joining ranges. It also provides syntax sugar\naround infinity (the absence of a defined LIMIT or OFFSET).",
    "lineNumber": 6,
    "interface": false
  },
  {
    "__docId__": 248,
    "kind": "method",
    "static": true,
    "variation": null,
    "name": "infinite",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange.infinite",
    "access": null,
    "description": null,
    "lineNumber": 7,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 249,
    "kind": "method",
    "static": true,
    "variation": null,
    "name": "rangeWithUnion",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange.rangeWithUnion",
    "access": null,
    "description": null,
    "lineNumber": 11,
    "undocument": true,
    "params": [
      {
        "name": "a",
        "types": [
          "*"
        ]
      },
      {
        "name": "b",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 250,
    "kind": "method",
    "static": true,
    "variation": null,
    "name": "rangesBySubtracting",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange.rangesBySubtracting",
    "access": null,
    "description": null,
    "lineNumber": 25,
    "undocument": true,
    "params": [
      {
        "name": "a",
        "types": [
          "*"
        ]
      },
      {
        "name": "b",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 251,
    "kind": "get",
    "static": false,
    "variation": null,
    "name": "start",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange#start",
    "access": null,
    "description": null,
    "lineNumber": 44,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 252,
    "kind": "get",
    "static": false,
    "variation": null,
    "name": "end",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange#end",
    "access": null,
    "description": null,
    "lineNumber": 48,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 253,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange#constructor",
    "access": null,
    "description": null,
    "lineNumber": 52,
    "undocument": true,
    "params": [
      {
        "name": "objectPattern",
        "optional": true,
        "types": [
          "{\"limit\": *, \"offset\": *, \"start\": *, \"end\": *}"
        ],
        "defaultRaw": {},
        "defaultValue": "{}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 254,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "limit",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange#limit",
    "access": null,
    "description": null,
    "lineNumber": 53,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 255,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "offset",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange#offset",
    "access": null,
    "description": null,
    "lineNumber": 54,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 256,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "offset",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange#offset",
    "access": null,
    "description": null,
    "lineNumber": 57,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 257,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "limit",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange#limit",
    "access": null,
    "description": null,
    "lineNumber": 60,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 258,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "clone",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange#clone",
    "access": null,
    "description": null,
    "lineNumber": 71,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 259,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "isInfinite",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange#isInfinite",
    "access": null,
    "description": null,
    "lineNumber": 76,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 260,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "isEqual",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange#isEqual",
    "access": null,
    "description": null,
    "lineNumber": 80,
    "undocument": true,
    "params": [
      {
        "name": "b",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 261,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "isContiguousWith",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange#isContiguousWith",
    "access": null,
    "description": null,
    "lineNumber": 86,
    "undocument": true,
    "params": [
      {
        "name": "b",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 262,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "toString",
    "memberof": "lib/query-range.js~QueryRange",
    "longname": "lib/query-range.js~QueryRange#toString",
    "access": null,
    "description": null,
    "lineNumber": 93,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 263,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/query-result-set.js",
    "memberof": null,
    "longname": "lib/query-result-set.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import QueryRange from './query-range';\n\n/**\nInstances of QueryResultSet hold a set of models retrieved from the database\nfor a given query and offset.\n\nComplete vs Incomplete:\n\nQueryResultSet keeps an array of item ids and a lookup table of models.\nThe lookup table may be incomplete if the QuerySubscription isn't finished\npreparing results. You can use `isComplete` to determine whether the set\nhas every model.\n\nOffset vs Index:\n\nTo avoid confusion, \"index\" (used within the implementation) refers to an item's\nposition in an array, and \"offset\" refers to it's position in the query\nresult set. For example, an item might be at index 20 in the _ids array, but\nat offset 120 in the result.\n*/\nexport default class QueryResultSet {\n\n  static setByApplyingModels(set, models) {\n    if (models instanceof Array) {\n      throw new Error(\"setByApplyingModels: A hash of models is required.\");\n    }\n    const out = set.clone();\n    out._modelsHash = models;\n    out._idToIndexHash = null;\n    return out;\n  }\n\n  constructor(other = {}) {\n    this._offset = (other._offset !== undefined) ? other._offset : null;\n    this._query = (other._query !== undefined) ? other._query : null;\n    this._idToIndexHash = (other._idToIndexHash !== undefined) ? other._idToIndexHash : null;\n    // Clone, since the others may be frozen\n    this._modelsHash = Object.assign({}, other._modelsHash || {})\n    this._ids = [].concat(other._ids || []);\n  }\n\n  clone() {\n    return new this.constructor({\n      _ids: [].concat(this._ids),\n      _modelsHash: Object.assign({}, this._modelsHash),\n      _idToIndexHash: Object.assign({}, this._idToIndexHash),\n      _query: this._query,\n      _offset: this._offset,\n    });\n  }\n\n  /**\n  @returns {Boolean} - True if every model in the result set is available, false\n    if part of the set is still being loaded. (Usually following range changes.)\n  */\n  isComplete() {\n    return this._ids.every((id) => this._modelsHash[id]);\n  }\n\n  /**\n  @returns {QueryRange} - The represented range.\n  */\n  range() {\n    return new QueryRange({offset: this._offset, limit: this._ids.length});\n  }\n\n  /**\n  @returns {Query} - The represented query.\n  */\n  query() {\n    return this._query;\n  }\n\n  /**\n  @returns {QueryRange} - The number of items in the represented range. Note\n  that a range (`LIMIT 10 OFFSET 0`) may return fewer than the maximum number\n  of items if none match the query.\n  */\n  count() {\n    return this._ids.length;\n  }\n\n  /**\n  @returns {Boolean} - True if the result set is empty, false otherwise.\n  */\n  empty() {\n    return this.count() === 0;\n  }\n\n  /**\n  @returns {Array} - the model IDs in the represented result.\n  */\n  ids() {\n    return this._ids;\n  }\n\n  /**\n  @param {Number} offset - The desired offset.\n  @returns {Array} - the model ID available at the requested offset, or undefined.\n  */\n  idAtOffset(offset) {\n    return this._ids[offset - this._offset];\n  }\n\n  /**\n  @returns {Array} - An array of model objects. If the result is not yet complete,\n  this array may contain `undefined` values.\n  */\n  models() {\n    return this._ids.map((id) => this._modelsHash[id]);\n  }\n\n  /**\n  @protected\n  */\n  modelCacheCount() {\n    return Object.keys(this._modelsHash).length;\n  }\n\n  /**\n  @param {Number} offset - The desired offset.\n  @returns {Model} - the model at the requested offset.\n  */\n  modelAtOffset(offset) {\n    if (!Number.isInteger(offset)) {\n      throw new Error(\"QueryResultSet.modelAtOffset() takes a numeric index. Maybe you meant modelWithId()?\");\n    }\n    return this._modelsHash[this._ids[offset - this._offset]];\n  }\n\n  /**\n  @param {String} id - The desired ID.\n  @returns {Model} - the model with the requested ID, or undefined.\n  */\n  modelWithId(id) {\n    return this._modelsHash[id];\n  }\n\n  _buildIdToIndexHash() {\n    this._idToIndexHash = {}\n    this._ids.forEach((id, idx) => {\n      this._idToIndexHash[id] = idx;\n      const model = this._modelsHash[id];\n      if (model) {\n        this._idToIndexHash[model.id] = idx;\n      }\n    });\n  }\n\n  /**\n  @param {String} id - The desired ID.\n  @returns {Number} - the offset of `ID`, relative to all of the query results.\n  */\n  offsetOfId(id) {\n    if (this._idToIndexHash === null) {\n      this._buildIdToIndexHash();\n    }\n\n    if (this._idToIndexHash[id] === undefined) {\n      return -1;\n    }\n    return this._idToIndexHash[id] + this._offset\n  }\n}\n"
  },
  {
    "__docId__": 264,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "QueryResultSet",
    "memberof": "lib/query-result-set.js",
    "longname": "lib/query-result-set.js~QueryResultSet",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/query-result-set.js",
    "importStyle": "QueryResultSet",
    "description": "Instances of QueryResultSet hold a set of models retrieved from the database\nfor a given query and offset.\n\nComplete vs Incomplete:\n\nQueryResultSet keeps an array of item ids and a lookup table of models.\nThe lookup table may be incomplete if the QuerySubscription isn't finished\npreparing results. You can use `isComplete` to determine whether the set\nhas every model.\n\nOffset vs Index:\n\nTo avoid confusion, \"index\" (used within the implementation) refers to an item's\nposition in an array, and \"offset\" refers to it's position in the query\nresult set. For example, an item might be at index 20 in the _ids array, but\nat offset 120 in the result.",
    "lineNumber": 21,
    "interface": false
  },
  {
    "__docId__": 265,
    "kind": "method",
    "static": true,
    "variation": null,
    "name": "setByApplyingModels",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet.setByApplyingModels",
    "access": null,
    "description": null,
    "lineNumber": 23,
    "undocument": true,
    "params": [
      {
        "name": "set",
        "types": [
          "*"
        ]
      },
      {
        "name": "models",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 266,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#constructor",
    "access": null,
    "description": null,
    "lineNumber": 33,
    "undocument": true,
    "params": [
      {
        "name": "other",
        "optional": true,
        "types": [
          "{}"
        ],
        "defaultRaw": {},
        "defaultValue": "{}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 267,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_offset",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#_offset",
    "access": null,
    "description": null,
    "lineNumber": 34,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 268,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_query",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#_query",
    "access": null,
    "description": null,
    "lineNumber": 35,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 269,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_idToIndexHash",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#_idToIndexHash",
    "access": null,
    "description": null,
    "lineNumber": 36,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 270,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_modelsHash",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#_modelsHash",
    "access": null,
    "description": null,
    "lineNumber": 38,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 271,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_ids",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#_ids",
    "access": null,
    "description": null,
    "lineNumber": 39,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 272,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "clone",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#clone",
    "access": null,
    "description": null,
    "lineNumber": 42,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 273,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "isComplete",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#isComplete",
    "access": null,
    "description": "",
    "lineNumber": 56,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Boolean} - True if every model in the result set is available, false\nif part of the set is still being loaded. (Usually following range changes.)"
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "Boolean"
      ],
      "spread": false,
      "description": "True if every model in the result set is available, false\nif part of the set is still being loaded. (Usually following range changes.)"
    },
    "generator": false
  },
  {
    "__docId__": 274,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "range",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#range",
    "access": null,
    "description": "",
    "lineNumber": 63,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{QueryRange} - The represented range."
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "QueryRange"
      ],
      "spread": false,
      "description": "The represented range."
    },
    "generator": false
  },
  {
    "__docId__": 275,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "query",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#query",
    "access": null,
    "description": "",
    "lineNumber": 70,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Query} - The represented query."
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "Query"
      ],
      "spread": false,
      "description": "The represented query."
    },
    "generator": false
  },
  {
    "__docId__": 276,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "count",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#count",
    "access": null,
    "description": "",
    "lineNumber": 79,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{QueryRange} - The number of items in the represented range. Note\nthat a range (`LIMIT 10 OFFSET 0`) may return fewer than the maximum number\nof items if none match the query."
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "QueryRange"
      ],
      "spread": false,
      "description": "The number of items in the represented range. Note\nthat a range (`LIMIT 10 OFFSET 0`) may return fewer than the maximum number\nof items if none match the query."
    },
    "generator": false
  },
  {
    "__docId__": 277,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "empty",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#empty",
    "access": null,
    "description": "",
    "lineNumber": 86,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Boolean} - True if the result set is empty, false otherwise."
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "Boolean"
      ],
      "spread": false,
      "description": "True if the result set is empty, false otherwise."
    },
    "generator": false
  },
  {
    "__docId__": 278,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "ids",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#ids",
    "access": null,
    "description": "",
    "lineNumber": 93,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Array} - the model IDs in the represented result."
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "Array"
      ],
      "spread": false,
      "description": "the model IDs in the represented result."
    },
    "generator": false
  },
  {
    "__docId__": 279,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "idAtOffset",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#idAtOffset",
    "access": null,
    "description": "",
    "lineNumber": 101,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Array} - the model ID available at the requested offset, or undefined."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Number"
        ],
        "spread": false,
        "optional": false,
        "name": "offset",
        "description": "The desired offset."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Array"
      ],
      "spread": false,
      "description": "the model ID available at the requested offset, or undefined."
    },
    "generator": false
  },
  {
    "__docId__": 280,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "models",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#models",
    "access": null,
    "description": "",
    "lineNumber": 109,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Array} - An array of model objects. If the result is not yet complete,\nthis array may contain `undefined` values."
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "Array"
      ],
      "spread": false,
      "description": "An array of model objects. If the result is not yet complete,\nthis array may contain `undefined` values."
    },
    "generator": false
  },
  {
    "__docId__": 281,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "modelCacheCount",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#modelCacheCount",
    "access": "protected",
    "description": "",
    "lineNumber": 116,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 282,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "modelAtOffset",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#modelAtOffset",
    "access": null,
    "description": "",
    "lineNumber": 124,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Model} - the model at the requested offset."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Number"
        ],
        "spread": false,
        "optional": false,
        "name": "offset",
        "description": "The desired offset."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Model"
      ],
      "spread": false,
      "description": "the model at the requested offset."
    },
    "generator": false
  },
  {
    "__docId__": 283,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "modelWithId",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#modelWithId",
    "access": null,
    "description": "",
    "lineNumber": 135,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Model} - the model with the requested ID, or undefined."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "String"
        ],
        "spread": false,
        "optional": false,
        "name": "id",
        "description": "The desired ID."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Model"
      ],
      "spread": false,
      "description": "the model with the requested ID, or undefined."
    },
    "generator": false
  },
  {
    "__docId__": 284,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_buildIdToIndexHash",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#_buildIdToIndexHash",
    "access": null,
    "description": null,
    "lineNumber": 139,
    "undocument": true,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 285,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_idToIndexHash",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#_idToIndexHash",
    "access": null,
    "description": null,
    "lineNumber": 140,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 286,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "offsetOfId",
    "memberof": "lib/query-result-set.js~QueryResultSet",
    "longname": "lib/query-result-set.js~QueryResultSet#offsetOfId",
    "access": null,
    "description": "",
    "lineNumber": 154,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Number} - the offset of `ID`, relative to all of the query results."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "String"
        ],
        "spread": false,
        "optional": false,
        "name": "id",
        "description": "The desired ID."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Number"
      ],
      "spread": false,
      "description": "the offset of `ID`, relative to all of the query results."
    },
    "generator": false
  },
  {
    "__docId__": 287,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/query-subscription-pool.js",
    "memberof": null,
    "longname": "lib/query-subscription-pool.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint global-require: 0 */\nimport QuerySubscription from './query-subscription';\n\n/**\nThe QuerySubscriptionPool maintains a list of all of the query\nsubscriptions in the app. In the future, this class will monitor performance,\nmerge equivalent subscriptions, etc.\n\n@private\n*/\nexport default class QuerySubscriptionPool {\n  constructor(database) {\n    this._database = database;\n    this._subscriptions = {};\n    this._cleanupChecks = [];\n    this._setup();\n  }\n\n  add(query, callback) {\n    // TODO\n    // if (NylasEnv.inDevMode()) {\n    //   callback._registrationPoint = this._formatRegistrationPoint((new Error).stack);\n    // }\n\n    const key = this._keyForQuery(query);\n    let subscription = this._subscriptions[key];\n    if (!subscription) {\n      subscription = new QuerySubscription(query);\n      this._subscriptions[key] = subscription;\n    }\n\n    subscription.addCallback(callback);\n    return () => {\n      subscription.removeCallback(callback);\n      this._scheduleCleanupCheckForSubscription(key);\n    };\n  }\n\n  addPrivateSubscription(key, subscription, callback) {\n    this._subscriptions[key] = subscription;\n    subscription.addCallback(callback);\n    return () => {\n      subscription.removeCallback(callback);\n      this._scheduleCleanupCheckForSubscription(key);\n    };\n  }\n\n  printSubscriptions() {\n    // TODO\n    // if (!NylasEnv.inDevMode()) {\n    //   console.log(\"printSubscriptions is only available in developer mode.\");\n    //   return;\n    // }\n\n    for (const key of Object.keys(this._subscriptions)) {\n      const subscription = this._subscriptions[key];\n      console.log(key);\n      console.group();\n      for (const callback of subscription._callbacks) {\n        console.log(`${callback._registrationPoint}`);\n      }\n      console.groupEnd();\n    }\n  }\n\n  _scheduleCleanupCheckForSubscription(key) {\n    // We unlisten / relisten to lots of subscriptions and setTimeout is actually\n    // /not/ that fast. Create one timeout for all checks, not one for each.\n    if (this._cleanupChecks.length === 0) {\n      setTimeout(() => this._runCleanupChecks(), 1);\n    }\n    this._cleanupChecks.push(key);\n  }\n\n  _runCleanupChecks() {\n    for (const key of this._cleanupChecks) {\n      const subscription = this._subscriptions[key];\n      if (subscription && (subscription.callbackCount() === 0)) {\n        delete this._subscriptions[key];\n      }\n    }\n    this._cleanupChecks = [];\n  }\n\n  _formatRegistrationPoint(stackString) {\n    const stack = stackString.split('\\n');\n    let ii = 0;\n    let seenRx = false;\n    while (ii < stack.length) {\n      const hasRx = stack[ii].indexOf('rx.lite') !== -1;\n      seenRx = seenRx || hasRx;\n      if (seenRx === true && !hasRx) {\n        break;\n      }\n      ii += 1;\n    }\n\n    return stack.slice(ii, ii + 4).join('\\n');\n  }\n\n  _keyForQuery(query) {\n    return query.sql();\n  }\n\n  _setup() {\n    this._database.listen(this._onChange);\n  }\n\n  _onChange = (record) => {\n    for (const key of Object.keys(this._subscriptions)) {\n      const subscription = this._subscriptions[key];\n      subscription.applyChangeRecord(record);\n    }\n  }\n}\n"
  },
  {
    "__docId__": 288,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "QuerySubscriptionPool",
    "memberof": "lib/query-subscription-pool.js",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "access": "private",
    "export": true,
    "importPath": "electron-coresqlite/lib/query-subscription-pool.js",
    "importStyle": "QuerySubscriptionPool",
    "description": "The QuerySubscriptionPool maintains a list of all of the query\nsubscriptions in the app. In the future, this class will monitor performance,\nmerge equivalent subscriptions, etc.",
    "lineNumber": 11,
    "interface": false
  },
  {
    "__docId__": 289,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#constructor",
    "access": null,
    "description": null,
    "lineNumber": 12,
    "undocument": true,
    "params": [
      {
        "name": "database",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 290,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_database",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#_database",
    "access": null,
    "description": null,
    "lineNumber": 13,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 291,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_subscriptions",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#_subscriptions",
    "access": null,
    "description": null,
    "lineNumber": 14,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 292,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_cleanupChecks",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#_cleanupChecks",
    "access": null,
    "description": null,
    "lineNumber": 15,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 293,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "add",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#add",
    "access": null,
    "description": null,
    "lineNumber": 19,
    "undocument": true,
    "params": [
      {
        "name": "query",
        "types": [
          "*"
        ]
      },
      {
        "name": "callback",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 294,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "addPrivateSubscription",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#addPrivateSubscription",
    "access": null,
    "description": null,
    "lineNumber": 39,
    "undocument": true,
    "params": [
      {
        "name": "key",
        "types": [
          "*"
        ]
      },
      {
        "name": "subscription",
        "types": [
          "*"
        ]
      },
      {
        "name": "callback",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 295,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "printSubscriptions",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#printSubscriptions",
    "access": null,
    "description": null,
    "lineNumber": 48,
    "undocument": true,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 296,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_scheduleCleanupCheckForSubscription",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#_scheduleCleanupCheckForSubscription",
    "access": null,
    "description": null,
    "lineNumber": 66,
    "undocument": true,
    "params": [
      {
        "name": "key",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 297,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_runCleanupChecks",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#_runCleanupChecks",
    "access": null,
    "description": null,
    "lineNumber": 75,
    "undocument": true,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 298,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_cleanupChecks",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#_cleanupChecks",
    "access": null,
    "description": null,
    "lineNumber": 82,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 299,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_formatRegistrationPoint",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#_formatRegistrationPoint",
    "access": null,
    "description": null,
    "lineNumber": 85,
    "undocument": true,
    "params": [
      {
        "name": "stackString",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 300,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_keyForQuery",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#_keyForQuery",
    "access": null,
    "description": null,
    "lineNumber": 101,
    "undocument": true,
    "params": [
      {
        "name": "query",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 301,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_setup",
    "memberof": "lib/query-subscription-pool.js~QuerySubscriptionPool",
    "longname": "lib/query-subscription-pool.js~QuerySubscriptionPool#_setup",
    "access": null,
    "description": null,
    "lineNumber": 105,
    "undocument": true,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 302,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/query-subscription.js",
    "memberof": null,
    "longname": "lib/query-subscription.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import QueryRange from './query-range';\nimport MutableQueryResultSet from './mutable-query-result-set';\n\nexport default class QuerySubscription {\n  constructor(query, options = {}) {\n    this._query = query;\n    this._options = options;\n\n    this._set = null;\n    this._callbacks = [];\n    this._lastResult = null;\n    this._updateInFlight = false;\n    this._queuedChangeRecords = [];\n    this._queryVersion = 1;\n\n    if (this._query) {\n      if (this._query._count) {\n        throw new Error(\"QuerySubscription::constructor - You cannot listen to count queries.\")\n      }\n\n      this._query.finalize();\n\n      if (this._options.initialModels) {\n        this._set = new MutableQueryResultSet();\n        this._set.addModelsInRange(this._options.initialModels, new QueryRange({\n          limit: this._options.initialModels.length,\n          offset: 0,\n        }));\n        this._createResultAndTrigger();\n      } else {\n        this.update();\n      }\n    }\n  }\n\n  query = () => {\n    return this._query;\n  }\n\n  addCallback = (callback) => {\n    if (!(callback instanceof Function)) {\n      throw new Error(`QuerySubscription:addCallback - expects a function, received ${callback}`);\n    }\n    this._callbacks.push(callback);\n\n    if (this._lastResult) {\n      process.nextTick(() => {\n        if (!this._lastResult) { return; }\n        callback(this._lastResult);\n      });\n    }\n  }\n\n  hasCallback = (callback) => {\n    return (this._callbacks.indexOf(callback) !== -1);\n  }\n\n  removeCallback(callback) {\n    if (!(callback instanceof Function)) {\n      throw new Error(`QuerySubscription:removeCallback - expects a function, received ${callback}`)\n    }\n    this._callbacks = this._callbacks.filter(c => c !== callback);\n    if (this.callbackCount() === 0) {\n      this.onLastCallbackRemoved()\n    }\n  }\n\n  onLastCallbackRemoved() {\n\n  }\n\n  callbackCount = () => {\n    return this._callbacks.length;\n  }\n\n  applyChangeRecord = (record) => {\n    if (!this._query || record.objectClass !== this._query.objectClass()) {\n      return;\n    }\n    if (record.objects.length === 0) {\n      return;\n    }\n\n    this._queuedChangeRecords.push(record);\n    if (!this._updateInFlight) {\n      this._processChangeRecords();\n    }\n  }\n\n  cancelPendingUpdate = () => {\n    this._queryVersion += 1;\n    this._updateInFlight = false;\n  }\n\n  // Scan through change records and apply them to the last result set.\n  _processChangeRecords = () => {\n    if (this._queuedChangeRecords.length === 0) {\n      return;\n    }\n    if (!this._set) {\n      this.update();\n      return;\n    }\n\n    let knownImpacts = 0;\n    let unknownImpacts = 0;\n\n    this._queuedChangeRecords.forEach((record) => {\n      if (record.type === 'unpersist') {\n        for (const item of record.objects) {\n          const offset = this._set.offsetOfId(item.id)\n          if (offset !== -1) {\n            this._set.removeModelAtOffset(item, offset);\n            unknownImpacts += 1;\n          }\n        }\n      } else if (record.type === 'persist') {\n        for (const item of record.objects) {\n          const offset = this._set.offsetOfId(item.id);\n          const itemIsInSet = offset !== -1;\n          const itemShouldBeInSet = item.matches(this._query.matchers());\n\n          if (itemIsInSet && !itemShouldBeInSet) {\n            this._set.removeModelAtOffset(item, offset)\n            unknownImpacts += 1\n          } else if (itemShouldBeInSet && !itemIsInSet) {\n            this._set.updateModel(item)\n            unknownImpacts += 1;\n          } else if (itemIsInSet) {\n            const oldItem = this._set.modelWithId(item.id);\n            this._set.updateModel(item);\n\n            if (this._itemSortOrderHasChanged(oldItem, item)) {\n              unknownImpacts += 1\n            } else {\n              knownImpacts += 1\n            }\n          }\n        }\n        // If we're not at the top of the result set, we can't be sure whether an\n        // item previously matched the set and doesn't anymore, impacting the items\n        // in the query range. We need to refetch IDs to be sure our set === correct.\n        if ((this._query.range().offset > 0) && (unknownImpacts + knownImpacts) < record.objects.length) {\n          unknownImpacts += 1\n        }\n      }\n    });\n\n    this._queuedChangeRecords = [];\n\n    if (unknownImpacts > 0) {\n      this.update({mustRefetchEntireRange: true});\n    } else if (knownImpacts > 0) {\n      this._createResultAndTrigger();\n    }\n  }\n\n  _itemSortOrderHasChanged(old, updated) {\n    for (const descriptor of this._query.orderSortDescriptors()) {\n      const oldSortValue = old[descriptor.attr.modelKey];\n      const updatedSortValue = updated[descriptor.attr.modelKey];\n\n      // http://stackoverflow.com/questions/4587060/determining-date-equality-in-javascript\n      if (!(oldSortValue >= updatedSortValue && oldSortValue <= updatedSortValue)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  update({mustRefetchEntireRange} = {}) {\n    this._updateInFlight = true;\n\n    const desiredRange = this._query.range();\n    const currentRange = this._set ? this._set.range() : null;\n    const hasNonInfiniteRange = currentRange && !currentRange.isInfinite() && !desiredRange.isInfinite();\n\n    // If we have a limited range, and changes don't require that we refetch\n    // the entire range, just fetch the missing items. This is the path typically\n    // used while scrolling.\n    if (hasNonInfiniteRange && !mustRefetchEntireRange) {\n      const missingRange = this._getMissingRange(desiredRange, currentRange);\n      this._fetchRange(missingRange, {\n        version: this._queryVersion,\n        fetchEntireModels: true,\n      });\n    } else {\n      const haveNoModels = !this._set || this._set.modelCacheCount() === 0;\n      this._fetchRange(desiredRange, {\n        version: this._queryVersion,\n        fetchEntireModels: haveNoModels,\n      });\n    }\n  }\n\n  _getMissingRange = (desiredRange, currentRange) => {\n    if (currentRange && !currentRange.isInfinite() && !desiredRange.isInfinite()) {\n      const ranges = QueryRange.rangesBySubtracting(desiredRange, currentRange);\n      return (ranges.length === 1) ? ranges[0] : desiredRange;\n    }\n    return desiredRange;\n  }\n\n  _getQueryForRange = (range, fetchEntireModels) => {\n    let rangeQuery = null;\n    if (!range.isInfinite()) {\n      rangeQuery = rangeQuery || this._query.clone();\n      rangeQuery.offset(range.offset).limit(range.limit);\n    }\n    if (!fetchEntireModels) {\n      rangeQuery = rangeQuery || this._query.clone();\n      rangeQuery.idsOnly();\n    }\n    rangeQuery = rangeQuery || this._query;\n    return rangeQuery;\n  }\n\n  _fetchRange(range, {version, fetchEntireModels}) {\n    const rangeQuery = this._getQueryForRange(range, fetchEntireModels);\n\n    this._query._database.run(rangeQuery, {format: false}).then((results) => {\n      if (this._queryVersion !== version) {\n        return;\n      }\n\n      if (this._set && !this._set.range().isContiguousWith(range)) {\n        this._set = null;\n      }\n      this._set = this._set || new MutableQueryResultSet();\n\n      if (fetchEntireModels) {\n        this._set.addModelsInRange(results, range);\n      } else {\n        this._set.addIdsInRange(results, range);\n      }\n\n      this._set.clipToRange(this._query.range());\n\n      this._fetchMissingModels().then((models) => {\n        if (this._queryVersion !== version) {\n          return;\n        }\n        for (const m of models) {\n          this._set.updateModel(m);\n        }\n        this._createResultAndTrigger();\n      });\n    });\n  }\n\n  _fetchMissingModels() {\n    const missingIds = this._set.ids().filter(id => !this._set.modelWithId(id));\n    if (missingIds.length === 0) {\n      return Promise.resolve([]);\n    }\n    return this._query._database.findAll(this._query._klass, {id: missingIds});\n  }\n\n  _createResultAndTrigger = () => {\n    const allCompleteModels = this._set.isComplete()\n    const uniqueSeen = {};\n    let uniqueCount = 0;\n    for (const i of this._set.ids()) {\n      if (!uniqueSeen[i]) {\n        uniqueCount += 1;\n      }\n      uniqueSeen[i] = true;\n    }\n\n    const allUniqueIds = uniqueCount === this._set.ids().length\n\n    let error = null;\n    if (!allCompleteModels) {\n      error = new Error(\"QuerySubscription: Applied all changes and result set is missing models.\");\n    }\n    if (!allUniqueIds) {\n      error = new Error(\"QuerySubscription: Applied all changes and result set contains duplicate IDs.\");\n    }\n\n    if (error) {\n      // TODO NylasEnv.reportError(error);\n      this._set = null;\n      this.update();\n      return;\n    }\n\n    if (this._options.emitResultSet) {\n      this._set.setQuery(this._query);\n      this._lastResult = this._set.immutableClone();\n    } else {\n      this._lastResult = this._query.formatResult(this._set.models());\n    }\n\n    this._callbacks.forEach((callback) => callback(this._lastResult));\n\n    // process any additional change records that have arrived\n    if (this._updateInFlight) {\n      this._updateInFlight = false;\n      this._processChangeRecords();\n    }\n  }\n}\n"
  },
  {
    "__docId__": 303,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "QuerySubscription",
    "memberof": "lib/query-subscription.js",
    "longname": "lib/query-subscription.js~QuerySubscription",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/query-subscription.js",
    "importStyle": "QuerySubscription",
    "description": null,
    "lineNumber": 4,
    "undocument": true,
    "interface": false
  },
  {
    "__docId__": 304,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#constructor",
    "access": null,
    "description": null,
    "lineNumber": 5,
    "undocument": true,
    "params": [
      {
        "name": "query",
        "types": [
          "*"
        ]
      },
      {
        "name": "options",
        "optional": true,
        "types": [
          "{}"
        ],
        "defaultRaw": {},
        "defaultValue": "{}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 305,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_query",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_query",
    "access": null,
    "description": null,
    "lineNumber": 6,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 306,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_options",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_options",
    "access": null,
    "description": null,
    "lineNumber": 7,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 307,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_set",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_set",
    "access": null,
    "description": null,
    "lineNumber": 9,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 308,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_callbacks",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_callbacks",
    "access": null,
    "description": null,
    "lineNumber": 10,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 309,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_lastResult",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_lastResult",
    "access": null,
    "description": null,
    "lineNumber": 11,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 310,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_updateInFlight",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_updateInFlight",
    "access": null,
    "description": null,
    "lineNumber": 12,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 311,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_queuedChangeRecords",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_queuedChangeRecords",
    "access": null,
    "description": null,
    "lineNumber": 13,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 312,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_queryVersion",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_queryVersion",
    "access": null,
    "description": null,
    "lineNumber": 14,
    "undocument": true,
    "type": {
      "types": [
        "number"
      ]
    }
  },
  {
    "__docId__": 313,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_set",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_set",
    "access": null,
    "description": null,
    "lineNumber": 24,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 314,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "removeCallback",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#removeCallback",
    "access": null,
    "description": null,
    "lineNumber": 58,
    "undocument": true,
    "params": [
      {
        "name": "callback",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 315,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_callbacks",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_callbacks",
    "access": null,
    "description": null,
    "lineNumber": 62,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 316,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "onLastCallbackRemoved",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#onLastCallbackRemoved",
    "access": null,
    "description": null,
    "lineNumber": 68,
    "undocument": true,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 317,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_itemSortOrderHasChanged",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_itemSortOrderHasChanged",
    "access": null,
    "description": null,
    "lineNumber": 158,
    "undocument": true,
    "params": [
      {
        "name": "old",
        "types": [
          "*"
        ]
      },
      {
        "name": "updated",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "boolean"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 318,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "update",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#update",
    "access": null,
    "description": null,
    "lineNumber": 171,
    "undocument": true,
    "params": [
      {
        "name": "objectPattern",
        "optional": true,
        "types": [
          "{\"mustRefetchEntireRange\": *}"
        ],
        "defaultRaw": {},
        "defaultValue": "{}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 319,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_updateInFlight",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_updateInFlight",
    "access": null,
    "description": null,
    "lineNumber": 172,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 320,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_fetchRange",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_fetchRange",
    "access": null,
    "description": null,
    "lineNumber": 218,
    "undocument": true,
    "params": [
      {
        "name": "range",
        "types": [
          "*"
        ]
      },
      {
        "name": "objectPattern1",
        "types": [
          "{\"version\": *, \"fetchEntireModels\": *}"
        ],
        "defaultRaw": {
          "version": null,
          "fetchEntireModels": null
        },
        "defaultValue": "{\"version\":null,\"fetchEntireModels\":null}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 321,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_set",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_set",
    "access": null,
    "description": null,
    "lineNumber": 227,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 322,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_set",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_set",
    "access": null,
    "description": null,
    "lineNumber": 229,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 323,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_fetchMissingModels",
    "memberof": "lib/query-subscription.js~QuerySubscription",
    "longname": "lib/query-subscription.js~QuerySubscription#_fetchMissingModels",
    "access": null,
    "description": null,
    "lineNumber": 251,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 324,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/query.js",
    "memberof": null,
    "longname": "lib/query.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint global-require: 0 */\n/* eslint import/newline-after-import: 0 */\nimport Rx from 'rx-lite';\nimport Attributes from './attributes';\nimport QueryRange from './query-range';\nimport {tableNameForJoin} from './utils';\n\nconst {Matcher, AttributeJoinedData, AttributeCollection} = Attributes;\n\n/**\nModelQuery exposes an ActiveRecord-style syntax for building database queries\nthat return models and model counts. Model queries are returned from the factory methods\n{RxDatabase::find}, {RxDatabase::findBy}, {RxDatabase::findAll},\nand {RxDatabase::count}, and are the primary interface for retrieving data\nfrom the app's local cache.\n\nModelQuery does not allow you to modify the local cache. To create, update or\ndelete items from the local cache, see {RxDatabase::inTransaction}\nand {DatabaseTransaction::persistModel}.\n\n**Simple Example:** Fetch a thread\n\n```js\nconst query = db.find(Thread, '123a2sc1ef4131');\nquery.then((thread) {\n  // thread or null\n});\n```\n\n**Advanced Example:** Fetch 50 threads in the inbox, in descending order\n\n```coffee\nconst query = db.findAll(Thread);\nquery.where([Thread.attributes.categories.contains('label-id')])\n     .order([Thread.attributes.lastMessageReceivedTimestamp.descending()])\n     .limit(100).offset(50)\n     .then((threads) {\n  // array of threads\n});\n```\n*/\nexport default class ModelQuery {\n\n  /**\n  @param {Model} class - A {Model} class to query\n  @param {RxDatabase} [database] - An optional reference to a {RxDatabase}\n    the query will be executed on.\n  */\n  constructor(klass, database) {\n    this._klass = klass;\n    this._database = database || require('./rx-database').default;\n    this._matchers = [];\n    this._orders = [];\n    this._distinct = false;\n    this._range = QueryRange.infinite();\n    this._returnOne = false;\n    this._returnIds = false;\n    this._includeJoinedData = [];\n    this._count = false;\n  }\n\n  /**\n  @returns {Query} - A deep copy of the Query that can be modified.\n  */\n  clone() {\n    const q = new ModelQuery(this._klass, this._database).where(this._matchers).order(this._orders);\n    q._orders = [].concat(this._orders);\n    q._includeJoinedData = [].concat(this._includeJoinedData);\n    q._range = this._range.clone();\n    q._distinct = this._distinct;\n    q._returnOne = this._returnOne;\n    q._returnIds = this._returnIds;\n    q._count = this._count;\n    return q;\n  }\n\n  distinct() {\n    this._distinct = true;\n    return this;\n  }\n\n  /**\n  Add one or more where clauses to the query\n  This method is chainable.\n\n  @param {Array} matchers - Array of {Matcher} objects that add where clauses\n    to the underlying query.\n  */\n  where(matchers) {\n    this._assertNotFinalized();\n\n    if (matchers instanceof Matcher) {\n      this._matchers.push(matchers);\n    } else if (matchers instanceof Array) {\n      for (const m of matchers) {\n        if (!(m instanceof Matcher)) {\n          throw new Error(\"You must provide instances of `Matcher`\");\n        }\n      }\n      this._matchers = this._matchers.concat(matchers);\n    } else if (matchers instanceof Object) {\n      // Support a shorthand format of {id: '123', accountId: '123'}\n      for (const key of Object.keys(matchers)) {\n        const value = matchers[key];\n        const attr = this._klass.attributes[key];\n        if (!attr) {\n          const msg = `Cannot create where clause \\`${key}:${value}\\`. ${key} is not an attribute of ${this._klass.name}`;\n          throw new Error(msg);\n        }\n\n        if (value instanceof Array) {\n          this._matchers.push(attr.in(value));\n        } else {\n          this._matchers.push(attr.equal(value));\n        }\n      }\n    }\n    return this;\n  }\n\n  whereAny(matchers) {\n    this._assertNotFinalized();\n    this._matchers.push(new Matcher.Or(matchers));\n    return this;\n  }\n\n  search(query) {\n    this._assertNotFinalized();\n    this._matchers.push(new Matcher.Search(query));\n    return this;\n  }\n\n  /**\n  Include specific joined data attributes in result objects.\n\n  @param {AttributeJoinedData} attr - Attribute that you want to be populated in\n  the returned models. Note: This results in a LEFT OUTER JOIN.\n  See {AttributeJoinedData} for more information.\n\n  This method is chainable.\n  */\n  include(attr) {\n    this._assertNotFinalized();\n    if (!(attr instanceof AttributeJoinedData)) {\n      throw new Error(\"query.include() must be called with a joined data attribute\");\n    }\n    this._includeJoinedData.push(attr);\n    return this;\n  }\n\n  /**\n  Include all of the available joined data attributes in returned models.\n\n  This method is chainable.\n  */\n  includeAll() {\n    this._assertNotFinalized()\n    for (const key of Object.keys(this._klass.attributes)) {\n      const attr = this._klass.attributes[key];\n      if (attr instanceof AttributeJoinedData) {\n        this.include(attr);\n      }\n    }\n    return this;\n  }\n\n  /**\n  Apply a sort order to the query.\n\n  @param {Array} ordersOrOrder - An {Array} of one or more {SortOrder} objects\n    that determine the sort order of returned models.\n\n  This method is chainable.\n  */\n  order(ordersOrOrder) {\n    this._assertNotFinalized();\n    const orders = (ordersOrOrder instanceof Array) ? ordersOrOrder : [ordersOrOrder];\n    this._orders = this._orders.concat(orders);\n    return this;\n  }\n\n  /**\n  Set the `singular` flag - only one model will be returned from the\n  query, and a `LIMIT 1` clause will be used.\n\n  This method is chainable.\n  */\n  one() {\n    this._assertNotFinalized();\n    this._returnOne = true;\n    return this;\n  }\n\n  /**\n  Limit the number of query results.\n\n  @param {Number} limit - The number of models that should be returned.\n\n  This method is chainable.\n  */\n  limit(limit) {\n    this._assertNotFinalized()\n    if (this._returnOne && limit > 1) {\n      throw new Error(\"Cannot use limit > 1 with one()\");\n    }\n    this._range = this._range.clone();\n    this._range.limit = limit;\n    return this;\n  }\n\n  /**\n  @param {Number} offset - The start offset of the query.\n  This method is chainable.\n  */\n  offset(offset) {\n    this._assertNotFinalized();\n    this._range = this._range.clone();\n    this._range.offset = offset;\n    return this;\n  }\n\n  /**\n  A convenience method for setting both limit and offset given a desired page size.\n  */\n  page(start, end, pageSize = 50, pagePadding = 100) {\n    const roundToPage = (n) => Math.max(0, Math.floor(n / pageSize) * pageSize)\n    this.offset(roundToPage(start - pagePadding));\n    this.limit(roundToPage((end - start) + pagePadding * 2));\n    return this;\n  }\n\n  /**\n  Set the `count` flag - instead of returning inflated models,\n  the query will return the result `COUNT`.\n\n  This method is chainable.\n  */\n  count() {\n    this._assertNotFinalized();\n    this._count = true;\n    return this;\n  }\n\n  idsOnly() {\n    this._assertNotFinalized();\n    this._returnIds = true;\n    return this;\n  }\n\n  // Query Execution\n\n  /**\n  Short-hand syntax that calls run().then(fn) with the provided function.\n\n  @returns {Promise} - A promise that resolves with the Models returned by the\n  query, or rejects with an error from the Database layer.\n  */\n  then(next) {\n    return this.run(this).then(next);\n  }\n\n  /**\n  @returns {Promise} - A Promise that resolves with the Models returned by the\n  query, or rejects with an error from the Database layer.\n  */\n  run() {\n    return this._database.run(this);\n  }\n\n  inflateResult(result) {\n    if (!result) {\n      return null;\n    }\n\n    if (this._count) {\n      return result[0].count / 1;\n    }\n    if (this._returnIds) {\n      return result.map(row => row.id);\n    }\n\n    try {\n      return result.map((row) => {\n        const json = JSON.parse(row.data, this._database.models.JSONReviver);\n        const object = (new this._klass()).fromJSON(json);\n        for (const attr of this._includeJoinedData) {\n          let value = row[attr.jsonKey];\n          if (value === AttributeJoinedData.NullPlaceholder) {\n            value = null;\n          }\n          object[attr.modelKey] = value;\n        }\n        return object;\n      });\n    } catch (jsonError) {\n      throw new Error(`Query could not parse the database result. Query: ${this.sql()}, Error: ${jsonError.toString()}`);\n    }\n  }\n\n  formatResult(inflated) {\n    if (this._returnOne) {\n      return inflated[0];\n    }\n    if (this._count) {\n      return inflated;\n    }\n    return [].concat(inflated);\n  }\n\n  // Query SQL Building\n\n  /**\n  @returns {String} - The SQL generated for the query.\n  */\n  sql() {\n    this.finalize();\n\n    let result = null;\n\n    if (this._count) {\n      result = `COUNT(*) as count`;\n    } else if (this._returnIds) {\n      result = `\\`${this._klass.name}\\`.\\`id\\``;\n    } else {\n      result = `\\`${this._klass.name}\\`.\\`data\\``;\n      this._includeJoinedData.forEach((attr) => {\n        result += `, ${attr.selectSQL(this._klass)} `;\n      })\n    }\n\n    const order = this._count ? '' : this._orderClause();\n\n    let limit = '';\n    if (Number.isInteger(this._range.limit)) {\n      limit = `LIMIT ${this._range.limit}`;\n    } else {\n      limit = ''\n    }\n    if (Number.isInteger(this._range.offset)) {\n      limit += ` OFFSET ${this._range.offset}`;\n    }\n\n    const distinct = this._distinct ? ' DISTINCT' : '';\n    const allMatchers = this.matchersFlattened();\n\n    const joins = allMatchers.filter((matcher) => matcher.attr instanceof AttributeCollection)\n\n    if ((joins.length === 1) && this._canSubselectForJoin(joins[0], allMatchers)) {\n      const subSql = this._subselectSQL(joins[0], this._matchers, order, limit);\n      return `SELECT${distinct} ${result} FROM \\`${this._klass.name}\\` WHERE \\`id\\` IN (${subSql}) ${order}`;\n    }\n\n    return `SELECT${distinct} ${result} FROM \\`${this._klass.name}\\` ${this._whereClause()} ${order} ${limit}`;\n  }\n\n  // If one of our matchers requires a join, and the attribute configuration lists\n  // all of the other order and matcher attributes in \\`joinQueryableBy\\`, it means\n  // we can make the entire WHERE and ORDER BY on a sub-query, which improves\n  // performance considerably vs. finding all results from the join table and then\n  // doing the ordering after pulling the results in the main table.\n  //\n  // Note: This is currently only intended for use in the thread list\n  //\n  _canSubselectForJoin(matcher, allMatchers) {\n    const joinAttribute = matcher.attribute();\n\n    if (!Number.isInteger(this._range.limit)) {\n      return false;\n    }\n\n    const allMatchersOnJoinTable = allMatchers.every((m) =>\n      (m === matcher) || (joinAttribute.joinQueryableBy.includes(m.attr.modelKey)) || (m.attr.modelKey === 'id')\n    );\n    const allOrdersOnJoinTable = this._orders.every((o) =>\n      (joinAttribute.joinQueryableBy.includes(o.attr.modelKey))\n    );\n\n    return (allMatchersOnJoinTable && allOrdersOnJoinTable);\n  }\n\n  _subselectSQL(returningMatcher, subselectMatchers, order, limit) {\n    const returningAttribute = returningMatcher.attribute()\n\n    const table = tableNameForJoin(this._klass, returningAttribute.itemClass);\n    const wheres = subselectMatchers.map(c => c.whereSQL(this._klass)).filter(c => !!c);\n\n    let innerSQL = `SELECT \\`id\\` FROM \\`${table}\\` WHERE ${wheres.join(' AND ')} ${order} ${limit}`;\n    innerSQL = innerSQL.replace(new RegExp(`\\`${this._klass.name}\\``, 'g'), `\\`${table}\\``);\n    innerSQL = innerSQL.replace(new RegExp(`\\`${returningMatcher.joinTableRef()}\\``, 'g'), `\\`${table}\\``);\n    return innerSQL;\n  }\n\n  _whereClause() {\n    const joins = [];\n    this._matchers.forEach((c) => {\n      const join = c.joinSQL(this._klass)\n      if (join) {\n        joins.push(join);\n      }\n    });\n\n    this._includeJoinedData.forEach((attr) => {\n      const join = attr.includeSQL(this._klass)\n      if (join) {\n        joins.push(join);\n      }\n    });\n\n    const wheres = [];\n    this._matchers.forEach(c => {\n      const where = c.whereSQL(this._klass);\n      if (where) {\n        wheres.push(where)\n      }\n    });\n\n    let sql = joins.join(' ')\n    if (wheres.length > 0) {\n      sql += ` WHERE ${wheres.join(' AND ')}`;\n    }\n    return sql;\n  }\n\n  _orderClause() {\n    if (this._orders.length === 0) {\n      return ''\n    }\n\n    let sql = ' ORDER BY '\n    this._orders.forEach((sort) => {\n      sql += sort.orderBySQL(this._klass);\n    });\n    return sql;\n  }\n\n  // Private: Marks the object as final, preventing any changes to the where\n  // clauses, orders, etc.\n  finalize() {\n    if (this._finalized) {\n      return this;\n    }\n\n    if (this._orders.length === 0) {\n      const natural = this._klass.naturalSortOrder();\n      if (natural) {\n        this._orders.push(natural);\n      }\n    }\n\n    if (this._returnOne && !this._range.limit) {\n      this.limit(1);\n    }\n\n    this._finalized = true;\n    return this;\n  }\n\n  // Private: Throws an exception if the query has been frozen.\n  _assertNotFinalized() {\n    if (this._finalized) {\n      throw new Error(`ModelQuery: You cannot modify a query after calling \\`then\\` or \\`listen\\``);\n    }\n  }\n\n  // Observables\n\n  observe({allowQueryChanges = false, name = null} = {}) {\n    return Rx.Observable.create((observer) => {\n      const pool = this._database._subscriptionPool;\n      let unsubscribe = null;\n      if (allowQueryChanges) {\n        unsubscribe = pool.addPrivateSubscription(name, this, (v) => observer.onNext(v));\n      } else {\n        unsubscribe = pool.add(this, (v) => observer.onNext(v));\n      }\n      return Rx.Disposable.create(unsubscribe);\n    });\n  }\n\n  // Introspection\n  // (These are here to make specs easy)\n\n  matchers() {\n    return this._matchers;\n  }\n\n  matchersFlattened() {\n    const all = []\n    const traverse = (matchers) => {\n      if (!(matchers instanceof Array)) {\n        return;\n      }\n      for (const m of matchers) {\n        if (m.children) {\n          traverse(m.children);\n        } else {\n          all.push(m);\n        }\n      }\n    }\n    traverse(this._matchers);\n    return all;\n  }\n\n  matcherValueForModelKey(key) {\n    const matcher = this._matchers.find(m => m.attr.modelKey === key)\n    return matcher ? matcher.val : null;\n  }\n\n  range() {\n    return this._range;\n  }\n\n  orderSortDescriptors() {\n    return this._orders;\n  }\n\n  objectClass() {\n    return this._klass.name;\n  }\n}\n"
  },
  {
    "__docId__": 325,
    "kind": "variable",
    "static": true,
    "variation": null,
    "name": "Matcher",
    "memberof": "lib/query.js",
    "longname": "lib/query.js~Matcher",
    "access": null,
    "export": false,
    "importPath": "electron-coresqlite/lib/query.js",
    "importStyle": null,
    "description": null,
    "lineNumber": 8,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 326,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "ModelQuery",
    "memberof": "lib/query.js",
    "longname": "lib/query.js~ModelQuery",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/query.js",
    "importStyle": "ModelQuery",
    "description": "ModelQuery exposes an ActiveRecord-style syntax for building database queries\nthat return models and model counts. Model queries are returned from the factory methods\n{RxDatabase::find}, {RxDatabase::findBy}, {RxDatabase::findAll},\nand {RxDatabase::count}, and are the primary interface for retrieving data\nfrom the app's local cache.\n\nModelQuery does not allow you to modify the local cache. To create, update or\ndelete items from the local cache, see {RxDatabase::inTransaction}\nand {DatabaseTransaction::persistModel}.\n\n*Simple Example:** Fetch a thread\n\n```js\nconst query = db.find(Thread, '123a2sc1ef4131');\nquery.then((thread) {\n// thread or null\n});\n```\n\n*Advanced Example:** Fetch 50 threads in the inbox, in descending order\n\n```coffee\nconst query = db.findAll(Thread);\nquery.where([Thread.attributes.categories.contains('label-id')])\n.order([Thread.attributes.lastMessageReceivedTimestamp.descending()])\n.limit(100).offset(50)\n.then((threads) {\n// array of threads\n});\n```",
    "lineNumber": 42,
    "interface": false
  },
  {
    "__docId__": 327,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#constructor",
    "access": null,
    "description": "",
    "lineNumber": 49,
    "params": [
      {
        "nullable": null,
        "types": [
          "Model"
        ],
        "spread": false,
        "optional": false,
        "name": "class",
        "description": "A {Model} class to query"
      },
      {
        "nullable": null,
        "types": [
          "RxDatabase"
        ],
        "spread": false,
        "optional": true,
        "name": "database",
        "description": "An optional reference to a {RxDatabase}\nthe query will be executed on."
      }
    ],
    "generator": false
  },
  {
    "__docId__": 328,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_klass",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_klass",
    "access": null,
    "description": null,
    "lineNumber": 50,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 329,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_database",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_database",
    "access": null,
    "description": null,
    "lineNumber": 51,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 330,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_matchers",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_matchers",
    "access": null,
    "description": null,
    "lineNumber": 52,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 331,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_orders",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_orders",
    "access": null,
    "description": null,
    "lineNumber": 53,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 332,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_distinct",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_distinct",
    "access": null,
    "description": null,
    "lineNumber": 54,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 333,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_range",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_range",
    "access": null,
    "description": null,
    "lineNumber": 55,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 334,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_returnOne",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_returnOne",
    "access": null,
    "description": null,
    "lineNumber": 56,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 335,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_returnIds",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_returnIds",
    "access": null,
    "description": null,
    "lineNumber": 57,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 336,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_includeJoinedData",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_includeJoinedData",
    "access": null,
    "description": null,
    "lineNumber": 58,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 337,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_count",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_count",
    "access": null,
    "description": null,
    "lineNumber": 59,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 338,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "clone",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#clone",
    "access": null,
    "description": "",
    "lineNumber": 65,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Query} - A deep copy of the Query that can be modified."
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "Query"
      ],
      "spread": false,
      "description": "A deep copy of the Query that can be modified."
    },
    "generator": false
  },
  {
    "__docId__": 339,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "distinct",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#distinct",
    "access": null,
    "description": null,
    "lineNumber": 77,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 340,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_distinct",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_distinct",
    "access": null,
    "description": null,
    "lineNumber": 78,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 341,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "where",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#where",
    "access": null,
    "description": "Add one or more where clauses to the query\nThis method is chainable.",
    "lineNumber": 89,
    "params": [
      {
        "nullable": null,
        "types": [
          "Array"
        ],
        "spread": false,
        "optional": false,
        "name": "matchers",
        "description": "Array of {Matcher} objects that add where clauses\nto the underlying query."
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 342,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_matchers",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_matchers",
    "access": null,
    "description": null,
    "lineNumber": 100,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 343,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "whereAny",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#whereAny",
    "access": null,
    "description": null,
    "lineNumber": 121,
    "undocument": true,
    "params": [
      {
        "name": "matchers",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 344,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "search",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#search",
    "access": null,
    "description": null,
    "lineNumber": 127,
    "undocument": true,
    "params": [
      {
        "name": "query",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 345,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "include",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#include",
    "access": null,
    "description": "Include specific joined data attributes in result objects.",
    "lineNumber": 142,
    "params": [
      {
        "nullable": null,
        "types": [
          "AttributeJoinedData"
        ],
        "spread": false,
        "optional": false,
        "name": "attr",
        "description": "Attribute that you want to be populated in\nthe returned models. Note: This results in a LEFT OUTER JOIN.\nSee {AttributeJoinedData} for more information.\n\nThis method is chainable."
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 346,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "includeAll",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#includeAll",
    "access": null,
    "description": "Include all of the available joined data attributes in returned models.\n\nThis method is chainable.",
    "lineNumber": 156,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 347,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "order",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#order",
    "access": null,
    "description": "Apply a sort order to the query.",
    "lineNumber": 175,
    "params": [
      {
        "nullable": null,
        "types": [
          "Array"
        ],
        "spread": false,
        "optional": false,
        "name": "ordersOrOrder",
        "description": "An {Array} of one or more {SortOrder} objects\nthat determine the sort order of returned models.\n\nThis method is chainable."
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 348,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_orders",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_orders",
    "access": null,
    "description": null,
    "lineNumber": 178,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 349,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "one",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#one",
    "access": null,
    "description": "Set the `singular` flag - only one model will be returned from the\nquery, and a `LIMIT 1` clause will be used.\n\nThis method is chainable.",
    "lineNumber": 188,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 350,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_returnOne",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_returnOne",
    "access": null,
    "description": null,
    "lineNumber": 190,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 351,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "limit",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#limit",
    "access": null,
    "description": "Limit the number of query results.",
    "lineNumber": 201,
    "params": [
      {
        "nullable": null,
        "types": [
          "Number"
        ],
        "spread": false,
        "optional": false,
        "name": "limit",
        "description": "The number of models that should be returned.\n\nThis method is chainable."
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 352,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_range",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_range",
    "access": null,
    "description": null,
    "lineNumber": 206,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 353,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "offset",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#offset",
    "access": null,
    "description": "",
    "lineNumber": 215,
    "params": [
      {
        "nullable": null,
        "types": [
          "Number"
        ],
        "spread": false,
        "optional": false,
        "name": "offset",
        "description": "The start offset of the query.\nThis method is chainable."
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 354,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_range",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_range",
    "access": null,
    "description": null,
    "lineNumber": 217,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 355,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "page",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#page",
    "access": null,
    "description": "A convenience method for setting both limit and offset given a desired page size.",
    "lineNumber": 225,
    "params": [
      {
        "name": "start",
        "types": [
          "*"
        ]
      },
      {
        "name": "end",
        "types": [
          "*"
        ]
      },
      {
        "name": "pageSize",
        "optional": true,
        "types": [
          "number"
        ],
        "defaultRaw": 50,
        "defaultValue": "50"
      },
      {
        "name": "pagePadding",
        "optional": true,
        "types": [
          "number"
        ],
        "defaultRaw": 100,
        "defaultValue": "100"
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 356,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "count",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#count",
    "access": null,
    "description": "Set the `count` flag - instead of returning inflated models,\nthe query will return the result `COUNT`.\n\nThis method is chainable.",
    "lineNumber": 238,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 357,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_count",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_count",
    "access": null,
    "description": null,
    "lineNumber": 240,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 358,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "idsOnly",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#idsOnly",
    "access": null,
    "description": null,
    "lineNumber": 244,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 359,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_returnIds",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_returnIds",
    "access": null,
    "description": null,
    "lineNumber": 246,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 360,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "then",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#then",
    "access": null,
    "description": "Short-hand syntax that calls run().then(fn) with the provided function.",
    "lineNumber": 258,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Promise} - A promise that resolves with the Models returned by the\nquery, or rejects with an error from the Database layer."
      }
    ],
    "params": [
      {
        "name": "next",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Promise"
      ],
      "spread": false,
      "description": "A promise that resolves with the Models returned by the\nquery, or rejects with an error from the Database layer."
    },
    "generator": false
  },
  {
    "__docId__": 361,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "run",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#run",
    "access": null,
    "description": "",
    "lineNumber": 266,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Promise} - A Promise that resolves with the Models returned by the\nquery, or rejects with an error from the Database layer."
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "Promise"
      ],
      "spread": false,
      "description": "A Promise that resolves with the Models returned by the\nquery, or rejects with an error from the Database layer."
    },
    "generator": false
  },
  {
    "__docId__": 362,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "inflateResult",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#inflateResult",
    "access": null,
    "description": null,
    "lineNumber": 270,
    "undocument": true,
    "params": [
      {
        "name": "result",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 363,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "formatResult",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#formatResult",
    "access": null,
    "description": null,
    "lineNumber": 300,
    "undocument": true,
    "params": [
      {
        "name": "inflated",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 364,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "sql",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#sql",
    "access": null,
    "description": "",
    "lineNumber": 315,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{String} - The SQL generated for the query."
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "String"
      ],
      "spread": false,
      "description": "The SQL generated for the query."
    },
    "generator": false
  },
  {
    "__docId__": 365,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_canSubselectForJoin",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_canSubselectForJoin",
    "access": null,
    "description": null,
    "lineNumber": 364,
    "undocument": true,
    "params": [
      {
        "name": "matcher",
        "types": [
          "*"
        ]
      },
      {
        "name": "allMatchers",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 366,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_subselectSQL",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_subselectSQL",
    "access": null,
    "description": null,
    "lineNumber": 381,
    "undocument": true,
    "params": [
      {
        "name": "returningMatcher",
        "types": [
          "*"
        ]
      },
      {
        "name": "subselectMatchers",
        "types": [
          "*"
        ]
      },
      {
        "name": "order",
        "types": [
          "*"
        ]
      },
      {
        "name": "limit",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 367,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_whereClause",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_whereClause",
    "access": null,
    "description": null,
    "lineNumber": 393,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 368,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_orderClause",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_orderClause",
    "access": null,
    "description": null,
    "lineNumber": 424,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 369,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "finalize",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#finalize",
    "access": null,
    "description": null,
    "lineNumber": 438,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 370,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_finalized",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_finalized",
    "access": null,
    "description": null,
    "lineNumber": 454,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 371,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_assertNotFinalized",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#_assertNotFinalized",
    "access": null,
    "description": null,
    "lineNumber": 459,
    "undocument": true,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 372,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "observe",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#observe",
    "access": null,
    "description": null,
    "lineNumber": 467,
    "undocument": true,
    "params": [
      {
        "name": "objectPattern",
        "optional": true,
        "types": [
          "{\"allowQueryChanges\": *, \"name\": *}"
        ],
        "defaultRaw": {},
        "defaultValue": "{}"
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 373,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "matchers",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#matchers",
    "access": null,
    "description": null,
    "lineNumber": 483,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 374,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "matchersFlattened",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#matchersFlattened",
    "access": null,
    "description": null,
    "lineNumber": 487,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 375,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "matcherValueForModelKey",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#matcherValueForModelKey",
    "access": null,
    "description": null,
    "lineNumber": 505,
    "undocument": true,
    "params": [
      {
        "name": "key",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 376,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "range",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#range",
    "access": null,
    "description": null,
    "lineNumber": 510,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 377,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "orderSortDescriptors",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#orderSortDescriptors",
    "access": null,
    "description": null,
    "lineNumber": 514,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 378,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "objectClass",
    "memberof": "lib/query.js~ModelQuery",
    "longname": "lib/query.js~ModelQuery#objectClass",
    "access": null,
    "description": null,
    "lineNumber": 518,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 379,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/rx-database.js",
    "memberof": null,
    "longname": "lib/rx-database.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint global-require: 0 */\nimport Sqlite3 from 'better-sqlite3';\nimport PromiseQueue from 'promise-queue';\nimport {ipcRenderer} from 'electron';\nimport LRU from 'lru-cache';\nimport {EventEmitter} from 'events';\n\nimport Query from './query';\nimport {logSQLString} from './console-utils';\nimport ModelRegistry from './model-registry';\nimport DatabaseChangeRecord from './database-change-record';\nimport DatabaseChangeRecordDebouncer from './database-change-record-debouncer';\nimport QuerySubscriptionPool from './query-subscription-pool';\nimport DatabaseTransaction from './database-transaction';\nimport DatabaseSetupQueryBuilder from './database-setup-query-builder';\nimport JSONBlob from './json-blob';\n\nconst DatabasePhase = {\n  Setup: 'setup',\n  Ready: 'ready',\n  Close: 'close',\n}\n\nclass IncorrectVersionError extends Error {\n  constructor({actual, expected}) {\n    super(`Incorrect database schema version: ${actual} not ${expected}`);\n  }\n}\n/**\nThe RxDatabase is the central database object of RxDB. You can instantiate\nas many databases as you'd like at the same time, and opening the same\ndatabase path in multiple windows is fine - RxDB uses SQLite transactions and\ndispatches change events across windows via the Electron IPC module.\n\nThis class extends EventEmitter, and you can subscribe to all changes to the\ndatabase by subscribing to the `trigger` event.\n\nFor more information about getting started with RxDB, see the Getting Started\nguide.\n\n@extends EventEmitter\n*/\n\nexport default class RxDatabase extends EventEmitter {\n\n  static ChangeRecord = DatabaseChangeRecord;\n  static IncorrectVersionError = IncorrectVersionError;\n\n  constructor({primary, databasePath, databaseVersion, logQueries, logQueryPlans} = {}) {\n    super();\n\n    this.setMaxListeners(100);\n\n    if (!databasePath) {\n      throw new Error(\"RxDatabase: You must provide a SQLite file path.\");\n    }\n    if (!databaseVersion || (typeof databaseVersion !== 'string')) {\n      throw new Error(\"RxDatabase: You must provide a database schema version number.\");\n    }\n\n    this.models = new ModelRegistry();\n\n    this._options = {primary, databasePath, databaseVersion, logQueries, logQueryPlans};\n\n    this._queryBuilder = new DatabaseSetupQueryBuilder();\n    this._transactionQueue = new PromiseQueue(1, Infinity);\n    this._subscriptionPool = new QuerySubscriptionPool(this);\n    this._preparedStatementCache = LRU({max: 500});\n    this._inflightTransactions = 0;\n    this._open = false;\n    this._waiting = [];\n    this._mutationHooks = [];\n    this._debouncer = new DatabaseChangeRecordDebouncer({\n      onTrigger: (record) => this.trigger(record),\n      maxTriggerDelay: 10,\n    })\n\n    // Listen to events from the application telling us when the database is ready,\n    // should be closed so it can be deleted, etc.\n    ipcRenderer.on('rxdb-phase-changed', this._onPhaseChanged);\n    setTimeout(() => this._onPhaseChanged(), 0);\n\n    // Listen for trigger events originating in other windows\n    ipcRenderer.on('rxdb-trigger', this._onIPCTrigger);\n  }\n\n  /**\n  Typically, instances of RxDatabase are long-lasting and are created in\n  renderer processes when they load. If you need to manually tear down an instance\n  of RxDatabase, call `disconnect`.\n  */\n  disconnect() {\n    ipcRenderer.removeListener('rxdb-phase-changed', this._onPhaseChanged);\n    ipcRenderer.removeListener('rxdb-trigger', this._onIPCTrigger);\n  }\n\n  _onIPCTrigger = ({json, path}) => {\n    if (path === this._options.databasePath) {\n      this.emit('trigger', new DatabaseChangeRecord(this, json));\n    }\n  }\n\n  _onPhaseChanged = () => {\n    const phase = ipcRenderer.sendSync('rxdb-get-phase');\n\n    if (phase === DatabasePhase.Setup && this._options.primary) {\n      this._openDatabase(() => {\n        this._checkDatabaseVersion({allowUnset: true}, () => {\n          this._runDatabaseSetup(() => {\n            ipcRenderer.sendSync('rxdb-set-phase', DatabasePhase.Ready);\n            setTimeout(() => this._runDatabaseAnalyze(), 60 * 1000);\n          });\n        });\n      });\n    } else if (phase === DatabasePhase.Ready) {\n      this._openDatabase(() => {\n        this._checkDatabaseVersion({}, () => {\n          this._open = true;\n          for (const w of this._waiting) {\n            w();\n          }\n          this._waiting = [];\n        });\n      });\n    } else if (phase === DatabasePhase.Close) {\n      this._open = false;\n      if (this._db) {\n        this._db.close();\n        this._db = null;\n      }\n    }\n  }\n\n  _openDatabase(ready) {\n    if (this._db) {\n      ready();\n      return;\n    }\n\n    this._db = new Sqlite3(this._options.databasePath, {});\n\n    this._db.on('close', (err) => {\n      this._handleSetupError(err);\n    })\n\n    this._db.on('open', () => {\n      // Note: These are properties of the connection, so they must be set regardless\n      // of whether the database setup queries are run.\n\n      // https://www.sqlite.org/wal.html\n      // WAL provides more concurrency as readers do not block writers and a writer\n      // does not block readers. Reading and writing can proceed concurrently.\n      this._db.pragma(`journal_mode = WAL`);\n\n      // https://www.sqlite.org/intern-v-extern-blob.html\n      // A database page size of 8192 or 16384 gives the best performance for large BLOB I/O.\n      this._db.pragma(`main.page_size = 8192`);\n      this._db.pragma(`main.cache_size = 20000`);\n      this._db.pragma(`main.synchronous = NORMAL`);\n\n      ready();\n    });\n  }\n\n  _checkDatabaseVersion({allowUnset} = {}, ready) {\n    const result = this._db.pragma('user_version', true);\n    const isUnsetVersion = (result === '0');\n    const isWrongVersion = (result !== this._options.databaseVersion);\n    if (isWrongVersion && !(isUnsetVersion && allowUnset)) {\n      return this._handleSetupError(new IncorrectVersionError({\n        actual: result,\n        expected: this._options.databaseVersion,\n      }));\n    }\n    return ready();\n  }\n\n  _runDatabaseSetup(ready) {\n    try {\n      for (const query of this._queryBuilder.setupQueries()) {\n        if (this._options.logQueries) {\n          console.log(`RxDatabase: ${query}`);\n        }\n        this._db.prepare(query).run();\n      }\n    } catch (err) {\n      return this._handleSetupError(err);\n    }\n\n    this._db.pragma(`user_version=${this._options.databaseVersion}`);\n\n    /**\n    @event RxDatabase#did-setup-database\n    @type {object}\n    @property {object} sqlite - The underlying SQLite3 database instance.\n    */\n    this.emit('did-setup-database', {sqlite: this._db});\n\n    return ready();\n  }\n\n  _runDatabaseAnalyze() {\n    const queries = this._queryBuilder.analyzeQueries();\n    const step = () => {\n      const query = queries.shift();\n      if (query) {\n        if (this._options.logQueries) {\n          console.log(`RxDatabase: ${query}`);\n        }\n        this._db.prepare(query).run();\n        setTimeout(step, 100);\n      } else {\n        console.log(`Completed ANALYZE of database`);\n      }\n    }\n    step();\n  }\n\n  _handleSetupError(error = (new Error(`Manually called _handleSetupError`))) {\n    /**\n    @event RxDatabase#will-rebuild-database\n    @type {object}\n    @property {object} sqlite - The underlying SQLite3 database instance.\n    @property {Error} error - The error that occurred.\n    */\n    this.emit('will-rebuild-database', {sqlite: this._db, error: error});\n    ipcRenderer.sendSync('rxdb-handle-setup-error');\n  }\n\n  /**\n  Executes a SQL string on the database. If a query is made before the database\n  has been opened, the query will be held in a queue and run / resolved when\n  the database is ready.\n\n  @protected\n\n  @param {String} query - A SQLite SQL string\n  @param {Array} values - An array of values, corresponding to `?` in the SQL string.\n  @returns {Promise} - Resolves when the query has been completed and rejects when\n    the query has failed.\n  */\n  _query(query, values = []) {\n    return new Promise((resolve, reject) => {\n      if (!this._open) {\n        this._waiting.push(() => this._query(query, values).then(resolve, reject));\n        return;\n      }\n\n      // Undefined, True, and False are not valid SQLite datatypes:\n      // https://www.sqlite.org/datatype3.html\n      values.forEach((val, idx) => {\n        if (val === false) {\n          values[idx] = 0;\n        } else if (val === true) {\n          values[idx] = 1;\n        } else if (val === undefined) {\n          values[idx] = null;\n        }\n      });\n\n      if (query.startsWith(`SELECT `) && this._options.logQueryPlans) {\n        const plan = this._db.prepare(`EXPLAIN QUERY PLAN ${query}`).all(values);\n        const planString = `${plan.map(row => row.detail).join('\\n')} for ${query}`;\n        if (planString.includes('ThreadCounts')) {\n          return;\n        }\n        if (planString.includes('ThreadSearch')) {\n          return;\n        }\n        if (planString.includes('SCAN') && !planString.includes('COVERING INDEX')) {\n          logSQLString(planString);\n        }\n      }\n\n      if (query.startsWith(`BEGIN`)) {\n        if (this._inflightTransactions !== 0) {\n          throw new Error(\"Assertion Failure: BEGIN called when an existing transaction is in-flight. Use inTransaction() to aquire transactions.\")\n        }\n        this._inflightTransactions += 1;\n      }\n\n      const fn = query.startsWith('SELECT') ? 'all' : 'run';\n      let tries = 0;\n      let results = null;\n\n      // Because other processes may be writing to the database and modifying the\n      // schema (running ANALYZE, etc.), we may `prepare` a statement and then be\n      // unable to execute it. Handle this case silently unless it's persistent.\n      while (!results) {\n        try {\n          let stmt = this._preparedStatementCache.get(query);\n          if (!stmt) {\n            stmt = this._db.prepare(query);\n            this._preparedStatementCache.set(query, stmt)\n          }\n          results = stmt[fn](values);\n        } catch (err) {\n          if (tries < 3 && err.toString().includes('database schema has changed')) {\n            this._preparedStatementCache.del(query);\n            tries += 1;\n          } else {\n            // note: this function may throw a promise, which causes our Promise to reject\n            throw new Error(`RxDatabase: Query ${query}, ${JSON.stringify(values)} failed ${err.toString()}`);\n          }\n        }\n      }\n\n      if (query === 'COMMIT') {\n        this._inflightTransactions -= 1;\n        if (this._inflightTransactions < 0) {\n          this._inflightTransactions = 0;\n          throw new Error(\"Assertion Failure: COMMIT was called too many times and the transaction count went negative.\")\n        }\n      }\n\n      resolve(results);\n    });\n  }\n\n  // PUBLIC METHODS #############################\n\n  // ActiveRecord-style Querying\n\n  /**\n  Creates a new Query for retrieving a single model specified by\n  the class and id.\n\n  @param {Model} klass - The class of the {Model} you're trying to retrieve.\n  @param {String} id - The id of the {Model} you're trying to retrieve\n\n  Example:\n\n  ```js\n  db.find(Thread, 'id-123').then((thread) => {\n    // thread is a Thread object, or null if no match was found.\n  });\n  ```\n\n  @returns {Query}\n  */\n  find(klass, id) {\n    if (!klass) {\n      throw new Error(`RxDatabase::find - You must provide a class`);\n    }\n    if (typeof id !== 'string') {\n      throw new Error(`RxDatabase::find - You must provide a string id. You may have intended to use findBy.`);\n    }\n    return new Query(klass, this).where({id}).one();\n  }\n\n  /**\n  Creates a new Model Query for retrieving a single model matching the\n  predicates provided.\n\n  @param {Model} klass - The class of the {Model} you're trying to retrieve.\n  @param {Matcher[]} predicates - the set of predicates the returned model must match.\n\n  @returns {Query}\n  */\n  findBy(klass, predicates = []) {\n    if (!klass) {\n      throw new Error(`RxDatabase::findBy - You must provide a class`);\n    }\n    return new Query(klass, this).where(predicates).one();\n  }\n\n  /**\n  Creates a new Model Query for retrieving all models matching the\n  predicates provided.\n\n  @param {Model} klass - The class you're trying to retrieve.\n  @param {Matcher[]} predicates - An array of matcher objects. The set of\n    predicates the returned model must match.\n\n  @returns {Query}\n  */\n  findAll(klass, predicates = []) {\n    if (!klass) {\n      throw new Error(`RxDatabase::findAll - You must provide a class`);\n    }\n    return new Query(klass, this).where(predicates);\n  }\n\n  /**\n  Creates a new Query that returns the number of models matching\n  the predicates provided.\n\n  @param {Model} klass - The Model class you're trying to retrieve.\n  @param {Matcher[]} predicates - The set of predicates the returned model\n  must match.\n\n  @returns {Query}\n  */\n  count(klass, predicates = []) {\n    if (!klass) {\n      throw new Error(`RxDatabase::count - You must provide a class`);\n    }\n    return new Query(klass, this).where(predicates).count();\n  }\n\n  /**\n  Modelify takes a mixed array of model IDs or model instances, and\n  queries for items that are missing. The returned array contains just model\n  instances, or null if the model could not be found.\n\n  This function is useful if your code may receive an item or it's ID.\n\n  Modelify is efficient and uses a single database query. It resolves Immediately\n  if no query is necessary. It does not change the order of items in the array.\n\n  @param {Model} klass - The model class desired\n  @param {Array} arr - An {Array} with a mix of string model IDs and/or models.\n\n  @returns {Promise} - A promise that resolves with the models.\n  */\n  modelify(klass, arr) {\n    if (!(arr instanceof Array) || (arr.length === 0)) {\n      return Promise.resolve([]);\n    }\n\n    const ids = []\n    for (const item of arr) {\n      if (item instanceof klass) {\n        ids.push(item.id);\n      } else if (typeof item === 'string') {\n        ids.push(item);\n      } else {\n        throw new Error(`modelify: Not sure how to convert ${item} into a ${klass.name}`);\n      }\n    }\n    if ((ids.length === 0) && (ids.length === 0)) {\n      return Promise.resolve(arr);\n    }\n\n    return this.findAll(klass).where(klass.attributes.id.in(ids)).then((modelsFromIds) => {\n      const modelsByString = {};\n      for (const model of modelsFromIds) {\n        modelsByString[model.id] = model;\n      }\n      return Promise.resolve(arr.map(item =>\n        (item instanceof klass ? item : modelsByString[item]))\n      );\n    });\n  }\n\n  /**\n  Executes a model {Query} on the local database. Typically, this method is\n  called transparently and you do not need to invoke it directly.\n\n  @protected\n\n  @param {Query} modelQuery - The query to execute.\n  @param {Object} options\n  @param {Boolean} options.format - Pass `format: true` to transform the result\n    into a set of models. Defaults to true.\n  @returns {Promise} - A promise that resolves with the result of the database query.\n  */\n  run(modelQuery, options = {format: true}) {\n    return this._query(modelQuery.sql(), []).then((result) => {\n      let transformed = modelQuery.inflateResult(result);\n      if (options.format !== false) {\n        transformed = modelQuery.formatResult(transformed)\n      }\n      return Promise.resolve(transformed);\n    });\n  }\n\n  findJSONBlob(id) {\n    return new JSONBlob.Query(JSONBlob, this).where({id}).one();\n  }\n\n  /**\n  Mutation hooks allow you to observe changes to the database and\n  add functionality within the transaction, before and/or after the standard\n  REPLACE / INSERT queries are made.\n\n   - beforeDatabaseChange: Run queries, etc. and return a promise. The RxDatabase\n     will proceed with changes once your promise has finished. You cannot call\n     persistModel or unpersistModel from this hook. Instead, use low level calls\n     like RxDatabase._query.\n\n   - afterDatabaseChange: Run queries, etc. after the `REPLACE` / `INSERT` queries\n\n  Warning: this is very low level. If you just want to watch for changes, You\n  should subscribe to the RxDatabase's trigger events.\n\n  Example: N1 uses these hooks to watch for changes to unread counts, which are\n  maintained in a separate table to avoid frequent `COUNT(*)` queries.\n  */\n  addMutationHook({beforeDatabaseChange, afterDatabaseChange}) {\n    if (!beforeDatabaseChange) {\n      throw new Error(`RxDatabase:addMutationHook - You must provide a beforeDatabaseChange function`);\n    }\n    if (!afterDatabaseChange) {\n      throw new Error(`RxDatabase:addMutationHook - You must provide a afterDatabaseChange function`);\n    }\n    this._mutationHooks.push({beforeDatabaseChange, afterDatabaseChange});\n  }\n\n  /**\n  Removes a previously registered mutation hook. You must pass the exact\n  same object that was provided to {RxDatabase.addMutationHook}.\n  */\n  removeMutationHook(hook) {\n    this._mutationHooks = this._mutationHooks.filter(h => h !== hook);\n  }\n\n  /**\n  @returns currently registered mutation hooks\n  */\n  mutationHooks() {\n    return this._mutationHooks;\n  }\n\n\n  /**\n  Opens a new database transaction and executes the provided `fn` within the\n  transaction. After the transaction function resolves, the transaction is\n  closed and changes are relayed to live queries and other subscribers.\n\n  RxDB makes the following guaruntees:\n\n  - Serial Execution: Once started, no other calls to `inTransaction` will\n    excute until the promise returned by `fn` has finished.\n\n  - Single Process Writing: No other process will be able to write to the\n    database while the provided function is running. RxDB uses SQLite's\n    `BEGIN IMMEDIATE TRANSACTION`, with the following semantics:\n      + No other connection will be able to write any changes.\n      + Other connections can read from the database, but they will not see\n        pending changes.\n\n  @param {Function} fn - A callback that will be executed inside a database\n    transaction\n\n  @returns {Promise} - A promise that resolves when the transaction has\n    successfully completed.\n\n  @emits RxDatabase#trigger\n  **/\n  inTransaction(fn) {\n    return this._transactionQueue.add(() =>\n      new DatabaseTransaction(this).execute(fn)\n    );\n  }\n\n  /**\n  @protected\n  */\n  transactionDidCommitChanges(changeRecords) {\n    for (const record of changeRecords) {\n      this._debouncer.accumulate(record);\n    }\n  }\n\n  // Search Index Operations\n\n  /**\n  @protected\n  */\n  createSearchIndex(klass) {\n    const sql = this._queryBuilder.createSearchIndexSql(klass);\n    return this._query(sql);\n  }\n\n  /**\n  @protected\n  */\n  searchIndexSize(klass) {\n    const searchTableName = `${klass.name}Search`;\n    const sql = `SELECT COUNT(content_id) as count FROM \\`${searchTableName}\\``;\n    return this._query(sql).then((result) => result[0].count);\n  }\n\n  /**\n  @protected\n  */\n  isIndexEmptyForAccount(accountId, modelKlass) {\n    const modelTable = modelKlass.name\n    const searchTable = `${modelTable}Search`\n    const sql = (\n      `SELECT \\`${searchTable}\\`.\\`content_id\\` FROM \\`${searchTable}\\` INNER JOIN \\`${modelTable}\\`\n      ON \\`${modelTable}\\`.id = \\`${searchTable}\\`.\\`content_id\\` WHERE \\`${modelTable}\\`.\\`account_id\\` = ?\n      LIMIT 1`\n    );\n    return this._query(sql, [accountId]).then(result => result.length === 0);\n  }\n\n  /**\n  @protected\n  */\n  dropSearchIndex(klass) {\n    if (!klass) {\n      throw new Error(`RxDatabase::createSearchIndex - You must provide a class`);\n    }\n    const searchTableName = `${klass.name}Search`\n    const sql = `DROP TABLE IF EXISTS \\`${searchTableName}\\``\n    return this._query(sql);\n  }\n\n  /**\n  @protected\n  */\n  isModelIndexed(model, isIndexed) {\n    if (isIndexed === true) {\n      return Promise.resolve(true);\n    }\n    const searchTableName = `${model.constructor.name}Search`\n    const exists = (\n      `SELECT rowid FROM \\`${searchTableName}\\` WHERE \\`${searchTableName}\\`.\\`content_id\\` = ?`\n    )\n    return this._query(exists, [model.id]).then((results) =>\n      Promise.resolve(results.length > 0)\n    )\n  }\n\n  /**\n  @protected\n  */\n  indexModel(model, indexData, isModelIndexed) {\n    const searchTableName = `${model.constructor.name}Search`;\n    return this.isModelIndexed(model, isModelIndexed).then((isIndexed) => {\n      if (isIndexed) {\n        return this.updateModelIndex(model, indexData, isIndexed);\n      }\n\n      const indexFields = Object.keys(indexData)\n      const keysSql = `content_id, ${indexFields.join(`, `)}`\n      const valsSql = `?, ${indexFields.map(() => '?').join(', ')}`\n      const values = [model.id].concat(indexFields.map(k => indexData[k]))\n      const sql = (\n        `INSERT INTO \\`${searchTableName}\\`(${keysSql}) VALUES (${valsSql})`\n      )\n      return this._query(sql, values);\n    });\n  }\n\n  /**\n  @protected\n  */\n  updateModelIndex(model, indexData, isModelIndexed) {\n    const searchTableName = `${model.constructor.name}Search`;\n    this.isModelIndexed(model, isModelIndexed).then((isIndexed) => {\n      if (!isIndexed) {\n        return this.indexModel(model, indexData, isIndexed);\n      }\n\n      const indexFields = Object.keys(indexData);\n      const values = indexFields.map(key => indexData[key]).concat([model.id]);\n      const setSql = (\n        indexFields\n        .map((key) => `\\`${key}\\` = ?`)\n        .join(', ')\n      );\n      const sql = (\n        `UPDATE \\`${searchTableName}\\` SET ${setSql} WHERE \\`${searchTableName}\\`.\\`content_id\\` = ?`\n      );\n      return this._query(sql, values);\n    });\n  }\n\n  /**\n  @protected\n  */\n  unindexModel(model) {\n    const searchTableName = `${model.constructor.name}Search`;\n    const sql = (\n      `DELETE FROM \\`${searchTableName}\\` WHERE \\`${searchTableName}\\`.\\`content_id\\` = ?`\n    );\n    return this._query(sql, [model.id]);\n  }\n\n  /**\n  @protected\n  */\n  unindexModelsForAccount(accountId, modelKlass) {\n    const modelTable = modelKlass.name;\n    const searchTableName = `${modelTable}Search`;\n    const sql = (\n      `DELETE FROM \\`${searchTableName}\\` WHERE \\`${searchTableName}\\`.\\`content_id\\` IN\n      (SELECT \\`id\\` FROM \\`${modelTable}\\` WHERE \\`${modelTable}\\`.\\`account_id\\` = ?)`\n    );\n    return this._query(sql, [accountId]);\n  }\n\n  // Compatibility with Reflux / Flux Stores\n\n  /**\n  For compatibility with Reflux, Flux and other libraries, you can subscribe to\n  the database using `listen`:\n\n  ```js\n  componentDidMount() {\n    this._unsubscribe = db.listen(this._onDataChanged, this);\n  }\n  ```\n\n  @param {Function} callback - The function to execute when the database triggers.\n  @param {Object} [bindContext] - Optional binding for `callback`.\n  */\n  listen(callback, bindContext = this) {\n    if (!callback) {\n      throw new Error(\"RxDatabase.listen called with undefined callback\");\n    }\n    let aborted = false\n    const eventHandler = (...args) => {\n      if (aborted) { return }\n      callback.apply(bindContext, args);\n    }\n    this.addListener('trigger', eventHandler);\n    return () => {\n      aborted = true;\n      this.removeListener('trigger', eventHandler);\n    }\n  }\n\n  /**\n  @protected\n  */\n  trigger(record) {\n    ipcRenderer.send('rxdb-trigger', {\n      path: this._options.databasePath,\n      json: record.toJSON(),\n    });\n    /**\n    @event RxDatabase#trigger\n    @type {DatabaseChangeRecord}\n    */\n    this.emit('trigger', record);\n  }\n}\n"
  },
  {
    "__docId__": 380,
    "kind": "variable",
    "static": true,
    "variation": null,
    "name": "DatabasePhase",
    "memberof": "lib/rx-database.js",
    "longname": "lib/rx-database.js~DatabasePhase",
    "access": null,
    "export": false,
    "importPath": "electron-coresqlite/lib/rx-database.js",
    "importStyle": null,
    "description": null,
    "lineNumber": 18,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 381,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "IncorrectVersionError",
    "memberof": "lib/rx-database.js",
    "longname": "lib/rx-database.js~IncorrectVersionError",
    "access": null,
    "export": false,
    "importPath": "electron-coresqlite/lib/rx-database.js",
    "importStyle": null,
    "description": null,
    "lineNumber": 24,
    "undocument": true,
    "interface": false,
    "extends": [
      "Error"
    ]
  },
  {
    "__docId__": 382,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/rx-database.js~IncorrectVersionError",
    "longname": "lib/rx-database.js~IncorrectVersionError#constructor",
    "access": null,
    "description": null,
    "lineNumber": 25,
    "undocument": true,
    "params": [
      {
        "name": "objectPattern",
        "types": [
          "{\"actual\": *, \"expected\": *}"
        ],
        "defaultRaw": {
          "actual": null,
          "expected": null
        },
        "defaultValue": "{\"actual\":null,\"expected\":null}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 383,
    "kind": "class",
    "static": true,
    "variation": null,
    "name": "RxDatabase",
    "memberof": "lib/rx-database.js",
    "longname": "lib/rx-database.js~RxDatabase",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/rx-database.js",
    "importStyle": "RxDatabase",
    "description": "The RxDatabase is the central database object of RxDB. You can instantiate\nas many databases as you'd like at the same time, and opening the same\ndatabase path in multiple windows is fine - RxDB uses SQLite transactions and\ndispatches change events across windows via the Electron IPC module.\n\nThis class extends EventEmitter, and you can subscribe to all changes to the\ndatabase by subscribing to the `trigger` event.\n\nFor more information about getting started with RxDB, see the Getting Started\nguide.",
    "lineNumber": 44,
    "interface": false,
    "extends": [
      "*"
    ]
  },
  {
    "__docId__": 384,
    "kind": "constructor",
    "static": false,
    "variation": null,
    "name": "constructor",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#constructor",
    "access": null,
    "description": null,
    "lineNumber": 49,
    "undocument": true,
    "params": [
      {
        "name": "objectPattern",
        "optional": true,
        "types": [
          "{\"primary\": *, \"databasePath\": *, \"databaseVersion\": *, \"logQueries\": *, \"logQueryPlans\": *}"
        ],
        "defaultRaw": {},
        "defaultValue": "{}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 385,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "models",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#models",
    "access": null,
    "description": null,
    "lineNumber": 61,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 386,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_options",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_options",
    "access": null,
    "description": null,
    "lineNumber": 63,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 387,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_queryBuilder",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_queryBuilder",
    "access": null,
    "description": null,
    "lineNumber": 65,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 388,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_transactionQueue",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_transactionQueue",
    "access": null,
    "description": null,
    "lineNumber": 66,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 389,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_subscriptionPool",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_subscriptionPool",
    "access": null,
    "description": null,
    "lineNumber": 67,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 390,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_preparedStatementCache",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_preparedStatementCache",
    "access": null,
    "description": null,
    "lineNumber": 68,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 391,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_inflightTransactions",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_inflightTransactions",
    "access": null,
    "description": null,
    "lineNumber": 69,
    "undocument": true,
    "type": {
      "types": [
        "number"
      ]
    }
  },
  {
    "__docId__": 392,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_open",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_open",
    "access": null,
    "description": null,
    "lineNumber": 70,
    "undocument": true,
    "type": {
      "types": [
        "boolean"
      ]
    }
  },
  {
    "__docId__": 393,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_waiting",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_waiting",
    "access": null,
    "description": null,
    "lineNumber": 71,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 394,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_mutationHooks",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_mutationHooks",
    "access": null,
    "description": null,
    "lineNumber": 72,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 395,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_debouncer",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_debouncer",
    "access": null,
    "description": null,
    "lineNumber": 73,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 396,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "disconnect",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#disconnect",
    "access": null,
    "description": "Typically, instances of RxDatabase are long-lasting and are created in\nrenderer processes when they load. If you need to manually tear down an instance\nof RxDatabase, call `disconnect`.",
    "lineNumber": 92,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 397,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_openDatabase",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_openDatabase",
    "access": null,
    "description": null,
    "lineNumber": 134,
    "undocument": true,
    "params": [
      {
        "name": "ready",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 398,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_db",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_db",
    "access": null,
    "description": null,
    "lineNumber": 140,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 399,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_checkDatabaseVersion",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_checkDatabaseVersion",
    "access": null,
    "description": null,
    "lineNumber": 165,
    "undocument": true,
    "params": [
      {
        "name": "objectPattern",
        "optional": true,
        "types": [
          "{\"allowUnset\": *}"
        ],
        "defaultRaw": {},
        "defaultValue": "{}"
      },
      {
        "name": "ready",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 400,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_runDatabaseSetup",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_runDatabaseSetup",
    "access": null,
    "description": null,
    "lineNumber": 178,
    "undocument": true,
    "params": [
      {
        "name": "ready",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 401,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_runDatabaseAnalyze",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_runDatabaseAnalyze",
    "access": null,
    "description": null,
    "lineNumber": 202,
    "undocument": true,
    "params": [],
    "generator": false
  },
  {
    "__docId__": 402,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_handleSetupError",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_handleSetupError",
    "access": null,
    "description": null,
    "lineNumber": 219,
    "undocument": true,
    "params": [
      {
        "name": "error",
        "optional": true,
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 403,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "_query",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_query",
    "access": "protected",
    "description": "Executes a SQL string on the database. If a query is made before the database\nhas been opened, the query will be held in a queue and run / resolved when\nthe database is ready.",
    "lineNumber": 242,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Promise} - Resolves when the query has been completed and rejects when\nthe query has failed."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "String"
        ],
        "spread": false,
        "optional": false,
        "name": "query",
        "description": "A SQLite SQL string"
      },
      {
        "nullable": null,
        "types": [
          "Array"
        ],
        "spread": false,
        "optional": false,
        "name": "values",
        "description": "An array of values, corresponding to `?` in the SQL string."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Promise"
      ],
      "spread": false,
      "description": "Resolves when the query has been completed and rejects when\nthe query has failed."
    },
    "generator": false
  },
  {
    "__docId__": 404,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_inflightTransactions",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_inflightTransactions",
    "access": null,
    "description": null,
    "lineNumber": 279,
    "undocument": true,
    "type": {
      "types": [
        "number"
      ]
    }
  },
  {
    "__docId__": 405,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_inflightTransactions",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_inflightTransactions",
    "access": null,
    "description": null,
    "lineNumber": 309,
    "undocument": true,
    "type": {
      "types": [
        "number"
      ]
    }
  },
  {
    "__docId__": 406,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_inflightTransactions",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_inflightTransactions",
    "access": null,
    "description": null,
    "lineNumber": 311,
    "undocument": true,
    "type": {
      "types": [
        "number"
      ]
    }
  },
  {
    "__docId__": 407,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "find",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#find",
    "access": null,
    "description": "Creates a new Query for retrieving a single model specified by\nthe class and id.",
    "lineNumber": 341,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Query}"
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Model"
        ],
        "spread": false,
        "optional": false,
        "name": "klass",
        "description": "The class of the {Model} you're trying to retrieve."
      },
      {
        "nullable": null,
        "types": [
          "String"
        ],
        "spread": false,
        "optional": false,
        "name": "id",
        "description": "The id of the {Model} you're trying to retrieve\n\nExample:\n\n```js\ndb.find(Thread, 'id-123').then((thread) => {\n// thread is a Thread object, or null if no match was found.\n});\n```"
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Query"
      ],
      "spread": false,
      "description": ""
    },
    "generator": false
  },
  {
    "__docId__": 408,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "findBy",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#findBy",
    "access": null,
    "description": "Creates a new Model Query for retrieving a single model matching the\npredicates provided.",
    "lineNumber": 360,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Query}"
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Model"
        ],
        "spread": false,
        "optional": false,
        "name": "klass",
        "description": "The class of the {Model} you're trying to retrieve."
      },
      {
        "nullable": null,
        "types": [
          "Matcher[]"
        ],
        "spread": false,
        "optional": false,
        "name": "predicates",
        "description": "the set of predicates the returned model must match."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Query"
      ],
      "spread": false,
      "description": ""
    },
    "generator": false
  },
  {
    "__docId__": 409,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "findAll",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#findAll",
    "access": null,
    "description": "Creates a new Model Query for retrieving all models matching the\npredicates provided.",
    "lineNumber": 377,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Query}"
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Model"
        ],
        "spread": false,
        "optional": false,
        "name": "klass",
        "description": "The class you're trying to retrieve."
      },
      {
        "nullable": null,
        "types": [
          "Matcher[]"
        ],
        "spread": false,
        "optional": false,
        "name": "predicates",
        "description": "An array of matcher objects. The set of\npredicates the returned model must match."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Query"
      ],
      "spread": false,
      "description": ""
    },
    "generator": false
  },
  {
    "__docId__": 410,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "count",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#count",
    "access": null,
    "description": "Creates a new Query that returns the number of models matching\nthe predicates provided.",
    "lineNumber": 394,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Query}"
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Model"
        ],
        "spread": false,
        "optional": false,
        "name": "klass",
        "description": "The Model class you're trying to retrieve."
      },
      {
        "nullable": null,
        "types": [
          "Matcher[]"
        ],
        "spread": false,
        "optional": false,
        "name": "predicates",
        "description": "The set of predicates the returned model\nmust match."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Query"
      ],
      "spread": false,
      "description": ""
    },
    "generator": false
  },
  {
    "__docId__": 411,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "modelify",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#modelify",
    "access": null,
    "description": "Modelify takes a mixed array of model IDs or model instances, and\nqueries for items that are missing. The returned array contains just model\ninstances, or null if the model could not be found.\n\nThis function is useful if your code may receive an item or it's ID.\n\nModelify is efficient and uses a single database query. It resolves Immediately\nif no query is necessary. It does not change the order of items in the array.",
    "lineNumber": 416,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Promise} - A promise that resolves with the models."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Model"
        ],
        "spread": false,
        "optional": false,
        "name": "klass",
        "description": "The model class desired"
      },
      {
        "nullable": null,
        "types": [
          "Array"
        ],
        "spread": false,
        "optional": false,
        "name": "arr",
        "description": "An {Array} with a mix of string model IDs and/or models."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Promise"
      ],
      "spread": false,
      "description": "A promise that resolves with the models."
    },
    "generator": false
  },
  {
    "__docId__": 412,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "run",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#run",
    "access": "protected",
    "description": "Executes a model {Query} on the local database. Typically, this method is\ncalled transparently and you do not need to invoke it directly.",
    "lineNumber": 458,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Promise} - A promise that resolves with the result of the database query."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Query"
        ],
        "spread": false,
        "optional": false,
        "name": "modelQuery",
        "description": "The query to execute."
      },
      {
        "nullable": null,
        "types": [
          "Object"
        ],
        "spread": false,
        "optional": false,
        "name": "options",
        "description": ""
      },
      {
        "nullable": null,
        "types": [
          "Boolean"
        ],
        "spread": false,
        "optional": false,
        "name": "options.format",
        "description": "Pass `format: true` to transform the result\ninto a set of models. Defaults to true."
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Promise"
      ],
      "spread": false,
      "description": "A promise that resolves with the result of the database query."
    },
    "generator": false
  },
  {
    "__docId__": 413,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "findJSONBlob",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#findJSONBlob",
    "access": null,
    "description": null,
    "lineNumber": 468,
    "undocument": true,
    "params": [
      {
        "name": "id",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 414,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "addMutationHook",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#addMutationHook",
    "access": null,
    "description": "Mutation hooks allow you to observe changes to the database and\nadd functionality within the transaction, before and/or after the standard\nREPLACE / INSERT queries are made.\n\n- beforeDatabaseChange: Run queries, etc. and return a promise. The RxDatabase\nwill proceed with changes once your promise has finished. You cannot call\npersistModel or unpersistModel from this hook. Instead, use low level calls\nlike RxDatabase._query.\n\n- afterDatabaseChange: Run queries, etc. after the `REPLACE` / `INSERT` queries\n\nWarning: this is very low level. If you just want to watch for changes, You\nshould subscribe to the RxDatabase's trigger events.\n\nExample: N1 uses these hooks to watch for changes to unread counts, which are\nmaintained in a separate table to avoid frequent `COUNT(*)` queries.",
    "lineNumber": 490,
    "params": [
      {
        "name": "objectPattern",
        "types": [
          "{\"beforeDatabaseChange\": *, \"afterDatabaseChange\": *}"
        ],
        "defaultRaw": {
          "beforeDatabaseChange": null,
          "afterDatabaseChange": null
        },
        "defaultValue": "{\"beforeDatabaseChange\":null,\"afterDatabaseChange\":null}"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 415,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "removeMutationHook",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#removeMutationHook",
    "access": null,
    "description": "Removes a previously registered mutation hook. You must pass the exact\nsame object that was provided to {RxDatabase.addMutationHook}.",
    "lineNumber": 504,
    "params": [
      {
        "name": "hook",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 416,
    "kind": "member",
    "static": false,
    "variation": null,
    "name": "_mutationHooks",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#_mutationHooks",
    "access": null,
    "description": null,
    "lineNumber": 505,
    "undocument": true,
    "type": {
      "types": [
        "*"
      ]
    }
  },
  {
    "__docId__": 417,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "mutationHooks",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#mutationHooks",
    "access": null,
    "description": "",
    "lineNumber": 511,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "currently registered mutation hooks"
      }
    ],
    "params": [],
    "return": {
      "nullable": null,
      "types": [
        "*"
      ],
      "spread": false,
      "description": "currently registered mutation hooks"
    },
    "generator": false
  },
  {
    "__docId__": 418,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "inTransaction",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#inTransaction",
    "access": null,
    "description": "Opens a new database transaction and executes the provided `fn` within the\ntransaction. After the transaction function resolves, the transaction is\nclosed and changes are relayed to live queries and other subscribers.\n\nRxDB makes the following guaruntees:\n\n- Serial Execution: Once started, no other calls to `inTransaction` will\nexcute until the promise returned by `fn` has finished.\n\n- Single Process Writing: No other process will be able to write to the\ndatabase while the provided function is running. RxDB uses SQLite's\n`BEGIN IMMEDIATE TRANSACTION`, with the following semantics:\n+ No other connection will be able to write any changes.\n+ Other connections can read from the database, but they will not see\npending changes.",
    "lineNumber": 541,
    "unknown": [
      {
        "tagName": "@returns",
        "tagValue": "{Promise} - A promise that resolves when the transaction has\nsuccessfully completed."
      }
    ],
    "params": [
      {
        "nullable": null,
        "types": [
          "Function"
        ],
        "spread": false,
        "optional": false,
        "name": "fn",
        "description": "A callback that will be executed inside a database\ntransaction"
      }
    ],
    "return": {
      "nullable": null,
      "types": [
        "Promise"
      ],
      "spread": false,
      "description": "A promise that resolves when the transaction has\nsuccessfully completed."
    },
    "emits": [
      {
        "types": [
          "*"
        ],
        "description": "RxDatabase#trigger"
      }
    ],
    "generator": false
  },
  {
    "__docId__": 419,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "transactionDidCommitChanges",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#transactionDidCommitChanges",
    "access": "protected",
    "description": "",
    "lineNumber": 550,
    "params": [
      {
        "name": "changeRecords",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 420,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "createSearchIndex",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#createSearchIndex",
    "access": "protected",
    "description": "",
    "lineNumber": 561,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 421,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "searchIndexSize",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#searchIndexSize",
    "access": "protected",
    "description": "",
    "lineNumber": 569,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 422,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "isIndexEmptyForAccount",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#isIndexEmptyForAccount",
    "access": "protected",
    "description": "",
    "lineNumber": 578,
    "params": [
      {
        "name": "accountId",
        "types": [
          "*"
        ]
      },
      {
        "name": "modelKlass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 423,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "dropSearchIndex",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#dropSearchIndex",
    "access": "protected",
    "description": "",
    "lineNumber": 592,
    "params": [
      {
        "name": "klass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 424,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "isModelIndexed",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#isModelIndexed",
    "access": "protected",
    "description": "",
    "lineNumber": 604,
    "params": [
      {
        "name": "model",
        "types": [
          "*"
        ]
      },
      {
        "name": "isIndexed",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 425,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "indexModel",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#indexModel",
    "access": "protected",
    "description": "",
    "lineNumber": 620,
    "params": [
      {
        "name": "model",
        "types": [
          "*"
        ]
      },
      {
        "name": "indexData",
        "types": [
          "*"
        ]
      },
      {
        "name": "isModelIndexed",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 426,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "updateModelIndex",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#updateModelIndex",
    "access": "protected",
    "description": "",
    "lineNumber": 641,
    "params": [
      {
        "name": "model",
        "types": [
          "*"
        ]
      },
      {
        "name": "indexData",
        "types": [
          "*"
        ]
      },
      {
        "name": "isModelIndexed",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 427,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "unindexModel",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#unindexModel",
    "access": "protected",
    "description": "",
    "lineNumber": 665,
    "params": [
      {
        "name": "model",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 428,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "unindexModelsForAccount",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#unindexModelsForAccount",
    "access": "protected",
    "description": "",
    "lineNumber": 676,
    "params": [
      {
        "name": "accountId",
        "types": [
          "*"
        ]
      },
      {
        "name": "modelKlass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 429,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "listen",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#listen",
    "access": null,
    "description": "For compatibility with Reflux, Flux and other libraries, you can subscribe to\nthe database using `listen`:\n\n```js\ncomponentDidMount() {\nthis._unsubscribe = db.listen(this._onDataChanged, this);\n}\n```",
    "lineNumber": 701,
    "params": [
      {
        "nullable": null,
        "types": [
          "Function"
        ],
        "spread": false,
        "optional": false,
        "name": "callback",
        "description": "The function to execute when the database triggers."
      },
      {
        "nullable": null,
        "types": [
          "Object"
        ],
        "spread": false,
        "optional": true,
        "name": "bindContext",
        "description": "Optional binding for `callback`."
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 430,
    "kind": "method",
    "static": false,
    "variation": null,
    "name": "trigger",
    "memberof": "lib/rx-database.js~RxDatabase",
    "longname": "lib/rx-database.js~RxDatabase#trigger",
    "access": "protected",
    "description": "",
    "lineNumber": 720,
    "params": [
      {
        "name": "record",
        "types": [
          "*"
        ]
      }
    ],
    "generator": false
  },
  {
    "__docId__": 431,
    "kind": "file",
    "static": true,
    "variation": null,
    "name": "lib/utils.js",
    "memberof": null,
    "longname": "lib/utils.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "export function modelFreeze(o) {\n  Object.freeze(o);\n  return Object.getOwnPropertyNames(o).forEach((key) => {\n    const val = o[key];\n    if (typeof val === 'object' && val !== null && !Object.isFrozen(val)) {\n      modelFreeze(val);\n    }\n  });\n}\n\nexport function generateTempId() {\n  const s4 = () => Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);\n  return `local-${s4()}${s4()}-${s4()}`;\n}\n\nexport function isTempId(id) {\n  if (!id || typeof id !== 'string') { return false; }\n  return id.slice(0, 6) === 'local-';\n}\n\nexport function tableNameForJoin(primaryKlass, secondaryKlass) {\n  return `${primaryKlass.name}${secondaryKlass.name}`;\n}\n"
  },
  {
    "__docId__": 432,
    "kind": "function",
    "static": true,
    "variation": null,
    "name": "modelFreeze",
    "memberof": "lib/utils.js",
    "longname": "lib/utils.js~modelFreeze",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/utils.js",
    "importStyle": "{modelFreeze}",
    "description": null,
    "lineNumber": 1,
    "undocument": true,
    "params": [
      {
        "name": "o",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 433,
    "kind": "function",
    "static": true,
    "variation": null,
    "name": "generateTempId",
    "memberof": "lib/utils.js",
    "longname": "lib/utils.js~generateTempId",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/utils.js",
    "importStyle": "{generateTempId}",
    "description": null,
    "lineNumber": 11,
    "undocument": true,
    "params": [],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 434,
    "kind": "function",
    "static": true,
    "variation": null,
    "name": "isTempId",
    "memberof": "lib/utils.js",
    "longname": "lib/utils.js~isTempId",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/utils.js",
    "importStyle": "{isTempId}",
    "description": null,
    "lineNumber": 16,
    "undocument": true,
    "params": [
      {
        "name": "id",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "*"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 435,
    "kind": "function",
    "static": true,
    "variation": null,
    "name": "tableNameForJoin",
    "memberof": "lib/utils.js",
    "longname": "lib/utils.js~tableNameForJoin",
    "access": null,
    "export": true,
    "importPath": "electron-coresqlite/lib/utils.js",
    "importStyle": "{tableNameForJoin}",
    "description": null,
    "lineNumber": 21,
    "undocument": true,
    "params": [
      {
        "name": "primaryKlass",
        "types": [
          "*"
        ]
      },
      {
        "name": "secondaryKlass",
        "types": [
          "*"
        ]
      }
    ],
    "return": {
      "types": [
        "string"
      ]
    },
    "generator": false
  },
  {
    "__docId__": 437,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Infinity",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Infinity",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 438,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "NaN",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~NaN",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 439,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "undefined",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~undefined",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 440,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "null",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~null",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 441,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Object",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Object",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 442,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "object",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~object",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 443,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Function",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Function",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 444,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "function",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~function",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 445,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Boolean",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Boolean",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 446,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "boolean",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~boolean",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 447,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Symbol",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Symbol",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 448,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Error",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Error",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 449,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "EvalError",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/EvalError",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~EvalError",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 450,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "InternalError",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/InternalError",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~InternalError",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 451,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "RangeError",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~RangeError",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 452,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "ReferenceError",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~ReferenceError",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 453,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "SyntaxError",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~SyntaxError",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 454,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "TypeError",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~TypeError",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 455,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "URIError",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/URIError",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~URIError",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 456,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Number",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Number",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 457,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "number",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~number",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 458,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Date",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Date",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 459,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "String",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~String",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 460,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "string",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~string",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 461,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "RegExp",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~RegExp",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 462,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Array",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Array",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 463,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Int8Array",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Int8Array",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 464,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Uint8Array",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Uint8Array",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 465,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Uint8ClampedArray",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Uint8ClampedArray",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 466,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Int16Array",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Int16Array",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 467,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Uint16Array",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Uint16Array",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 468,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Int32Array",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Int32Array",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 469,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Uint32Array",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Uint32Array",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 470,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Float32Array",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Float32Array",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 471,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Float64Array",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float64Array",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Float64Array",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 472,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Map",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Map",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 473,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Set",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Set",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 474,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "WeakMap",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~WeakMap",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 475,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "WeakSet",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~WeakSet",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 476,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "ArrayBuffer",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~ArrayBuffer",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 477,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "DataView",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~DataView",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 478,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "JSON",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~JSON",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 479,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Promise",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Promise",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 480,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Generator",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Generator",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 481,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "GeneratorFunction",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/GeneratorFunction",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~GeneratorFunction",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 482,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Reflect",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Reflect",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 483,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Proxy",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy",
    "memberof": "BuiltinExternal/ECMAScriptExternal.js",
    "longname": "BuiltinExternal/ECMAScriptExternal.js~Proxy",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 485,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "CanvasRenderingContext2D",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D",
    "memberof": "BuiltinExternal/WebAPIExternal.js",
    "longname": "BuiltinExternal/WebAPIExternal.js~CanvasRenderingContext2D",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 486,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "DocumentFragment",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment",
    "memberof": "BuiltinExternal/WebAPIExternal.js",
    "longname": "BuiltinExternal/WebAPIExternal.js~DocumentFragment",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 487,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Element",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/API/Element",
    "memberof": "BuiltinExternal/WebAPIExternal.js",
    "longname": "BuiltinExternal/WebAPIExternal.js~Element",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 488,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Event",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/API/Event",
    "memberof": "BuiltinExternal/WebAPIExternal.js",
    "longname": "BuiltinExternal/WebAPIExternal.js~Event",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 489,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "Node",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/API/Node",
    "memberof": "BuiltinExternal/WebAPIExternal.js",
    "longname": "BuiltinExternal/WebAPIExternal.js~Node",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 490,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "NodeList",
    "externalLink": "https://developer.mozilla.org/en-US/docs/Web/API/NodeList",
    "memberof": "BuiltinExternal/WebAPIExternal.js",
    "longname": "BuiltinExternal/WebAPIExternal.js~NodeList",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 491,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "XMLHttpRequest",
    "externalLink": "https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest",
    "memberof": "BuiltinExternal/WebAPIExternal.js",
    "longname": "BuiltinExternal/WebAPIExternal.js~XMLHttpRequest",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 492,
    "kind": "external",
    "static": true,
    "variation": null,
    "name": "AudioContext",
    "externalLink": "https://developer.mozilla.org/en/docs/Web/API/AudioContext",
    "memberof": "BuiltinExternal/WebAPIExternal.js",
    "longname": "BuiltinExternal/WebAPIExternal.js~AudioContext",
    "access": null,
    "description": "",
    "builtinExternal": true
  },
  {
    "__docId__": 493,
    "kind": "testFile",
    "static": true,
    "variation": null,
    "name": "spec/database-setup-query-builder-spec.js",
    "memberof": null,
    "longname": "spec/database-setup-query-builder-spec.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint quote-props: 0 */\nimport TestModel from './fixtures/test-model';\nimport Attributes from '../lib/attributes';\nimport DatabaseSetupQueryBuilder from '../lib/database-setup-query-builder';\n\ndescribe(\"DatabaseSetupQueryBuilder\", function DatabaseSetupQueryBuilderSpecs() {\n  beforeEach(() => {\n    this.builder = new DatabaseSetupQueryBuilder();\n  });\n\n  describe(\"setupQueriesForTable\", () => {\n    it(\"should return the queries for creating the table and the primary unique index\", () => {\n      TestModel.attributes = {\n        'attrQueryable': Attributes.DateTime({\n          queryable: true,\n          modelKey: 'attrQueryable',\n          jsonKey: 'attr_queryable',\n        }),\n\n        'attrNonQueryable': Attributes.Collection({\n          modelKey: 'attrNonQueryable',\n          jsonKey: 'attr_non_queryable',\n        }),\n      };\n      const queries = this.builder.setupQueriesForTable(TestModel);\n      const expected = [\n        'CREATE TABLE IF NOT EXISTS `TestModel` (id TEXT PRIMARY KEY,data BLOB,attr_queryable INTEGER)',\n        'CREATE UNIQUE INDEX IF NOT EXISTS `TestModel_id` ON `TestModel` (`id`)',\n      ];\n      queries.map((query, i) =>\n        expect(query).toBe(expected[i])\n      );\n    });\n\n    it(\"should correctly create join tables for models that have queryable collections\", () => {\n      TestModel.configureWithCollectionAttribute();\n      const queries = this.builder.setupQueriesForTable(TestModel);\n      const expected = [\n        'CREATE TABLE IF NOT EXISTS `TestModel` (id TEXT PRIMARY KEY,data BLOB,other TEXT)',\n        'CREATE UNIQUE INDEX IF NOT EXISTS `TestModel_id` ON `TestModel` (`id`)',\n        'CREATE TABLE IF NOT EXISTS `TestModelCategory` (id TEXT KEY,`value` TEXT,other TEXT)',\n        'CREATE INDEX IF NOT EXISTS `TestModelCategory_id` ON `TestModelCategory` (`id` ASC)',\n        'CREATE UNIQUE INDEX IF NOT EXISTS `TestModelCategory_val_id` ON `TestModelCategory` (`value` ASC, `id` ASC)',\n      ];\n      queries.map((query, i) =>\n        expect(query).toBe(expected[i])\n      );\n    });\n\n    it(\"should use the correct column type for each attribute\", () => {\n      TestModel.configureWithAllAttributes();\n      const queries = this.builder.setupQueriesForTable(TestModel);\n      expect(queries[0]).toBe('CREATE TABLE IF NOT EXISTS `TestModel` (id TEXT PRIMARY KEY,data BLOB,datetime INTEGER,string-json-key TEXT,boolean INTEGER,number INTEGER)');\n    });\n\n    describe(\"when the model provides additional sqlite config\", () => {\n      it(\"the setup method should return these queries\", () => {\n        TestModel.configureWithAdditionalSQLiteConfig();\n        spyOn(TestModel.additionalSQLiteConfig, 'setup').and.callThrough();\n        const queries = this.builder.setupQueriesForTable(TestModel);\n        expect(TestModel.additionalSQLiteConfig.setup).toHaveBeenCalledWith();\n        expect(queries.pop()).toBe('CREATE INDEX IF NOT EXISTS ThreadListIndex ON Thread(last_message_received_timestamp DESC, account_id, id)');\n      });\n\n      it(\"should not fail if additional config is present, but setup is undefined\", () => {\n        delete TestModel.additionalSQLiteConfig.setup;\n        this.m = new TestModel({id: 'local-6806434c-b0cd', body: 'hello world'});\n        expect(() => this.builder.setupQueriesForTable(TestModel)).not.toThrow();\n      });\n    });\n  });\n});\n"
  },
  {
    "__docId__": 494,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe0",
    "testId": 0,
    "memberof": "spec/database-setup-query-builder-spec.js",
    "testDepth": 0,
    "longname": "spec/database-setup-query-builder-spec.js~describe0",
    "access": null,
    "description": "DatabaseSetupQueryBuilder",
    "lineNumber": 6
  },
  {
    "__docId__": 495,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe1",
    "testId": 1,
    "memberof": "spec/database-setup-query-builder-spec.js~describe0",
    "testDepth": 1,
    "longname": "spec/database-setup-query-builder-spec.js~describe0.describe1",
    "access": null,
    "description": "setupQueriesForTable",
    "lineNumber": 11
  },
  {
    "__docId__": 496,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it2",
    "testId": 2,
    "memberof": "spec/database-setup-query-builder-spec.js~describe0.describe1",
    "testDepth": 2,
    "longname": "spec/database-setup-query-builder-spec.js~describe0.describe1.it2",
    "access": null,
    "description": "should return the queries for creating the table and the primary unique index",
    "lineNumber": 12
  },
  {
    "__docId__": 497,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it3",
    "testId": 3,
    "memberof": "spec/database-setup-query-builder-spec.js~describe0.describe1",
    "testDepth": 2,
    "longname": "spec/database-setup-query-builder-spec.js~describe0.describe1.it3",
    "access": null,
    "description": "should correctly create join tables for models that have queryable collections",
    "lineNumber": 35
  },
  {
    "__docId__": 498,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it4",
    "testId": 4,
    "memberof": "spec/database-setup-query-builder-spec.js~describe0.describe1",
    "testDepth": 2,
    "longname": "spec/database-setup-query-builder-spec.js~describe0.describe1.it4",
    "access": null,
    "description": "should use the correct column type for each attribute",
    "lineNumber": 50
  },
  {
    "__docId__": 499,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe5",
    "testId": 5,
    "memberof": "spec/database-setup-query-builder-spec.js~describe0.describe1",
    "testDepth": 2,
    "longname": "spec/database-setup-query-builder-spec.js~describe0.describe1.describe5",
    "access": null,
    "description": "when the model provides additional sqlite config",
    "lineNumber": 56
  },
  {
    "__docId__": 500,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it6",
    "testId": 6,
    "memberof": "spec/database-setup-query-builder-spec.js~describe0.describe1.describe5",
    "testDepth": 3,
    "longname": "spec/database-setup-query-builder-spec.js~describe0.describe1.describe5.it6",
    "access": null,
    "description": "the setup method should return these queries",
    "lineNumber": 57
  },
  {
    "__docId__": 501,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it7",
    "testId": 7,
    "memberof": "spec/database-setup-query-builder-spec.js~describe0.describe1.describe5",
    "testDepth": 3,
    "longname": "spec/database-setup-query-builder-spec.js~describe0.describe1.describe5.it7",
    "access": null,
    "description": "should not fail if additional config is present, but setup is undefined",
    "lineNumber": 65
  },
  {
    "__docId__": 502,
    "kind": "testFile",
    "static": true,
    "variation": null,
    "name": "spec/database-store-spec.js",
    "memberof": null,
    "longname": "spec/database-store-spec.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint quote-props: 0 */\nimport TestModel from './fixtures/test-model';\nimport Thread from './fixtures/thread';\nimport ModelQuery from '../lib/query';\nimport {Database} from './fixtures';\n\nconst testMatchers = {'id': 'b'};\n\ndescribe(\"Database\", function DatabaseSpecs() {\n  beforeEach(() => {\n    TestModel.configureBasic();\n    jasmine.clock().install();\n\n    Database._atomicallyQueue = undefined;\n    Database._mutationQueue = undefined;\n    Database._inTransaction = false;\n\n    spyOn(ModelQuery.prototype, 'where').and.callThrough();\n    spyOn(Database, 'transactionDidCommitChanges').and.callFake(() => Promise.resolve());\n\n    this.performed = [];\n\n    // Note: We spy on _query and test all of the convenience methods that sit above\n    // it. None of these tests evaluate whether _query works!\n    spyOn(Database, \"_query\").and.callFake((query, values = []) => {\n      this.performed.push({query, values});\n      return Promise.resolve([]);\n    });\n  });\n\n  afterEach(() => {\n    jasmine.clock().uninstall();\n  });\n\n  describe(\"find\", () =>\n    it(\"should return a ModelQuery for retrieving a single item by Id\", () => {\n      const q = Database.find(TestModel, \"4\");\n      expect(q.sql()).toBe(\"SELECT `TestModel`.`data` FROM `TestModel`  WHERE `TestModel`.`id` = '4'  LIMIT 1\");\n    })\n  );\n\n  describe(\"findBy\", () => {\n    it(\"should pass the provided predicates on to the ModelQuery\", () => {\n      Database.findBy(TestModel, testMatchers);\n      expect(ModelQuery.prototype.where).toHaveBeenCalledWith(testMatchers);\n    });\n\n    it(\"should return a ModelQuery ready to be executed\", () => {\n      const q = Database.findBy(TestModel, testMatchers);\n      expect(q.sql()).toBe(\"SELECT `TestModel`.`data` FROM `TestModel`  WHERE `TestModel`.`id` = 'b'  LIMIT 1\");\n    });\n  });\n\n  describe(\"findAll\", () => {\n    it(\"should pass the provided predicates on to the ModelQuery\", () => {\n      Database.findAll(TestModel, testMatchers);\n      expect(ModelQuery.prototype.where).toHaveBeenCalledWith(testMatchers);\n    });\n\n    it(\"should return a ModelQuery ready to be executed\", () => {\n      const q = Database.findAll(TestModel, testMatchers);\n      expect(q.sql()).toBe(\"SELECT `TestModel`.`data` FROM `TestModel`  WHERE `TestModel`.`id` = 'b'  \");\n    });\n  });\n\n  describe(\"modelify\", () => {\n    beforeEach(() => {\n      this.models = [\n        new Thread({id: 'local-A'}),\n        new Thread({id: 'local-B'}),\n        new Thread({id: 'local-C'}),\n        new Thread({id: 'local-D'}),\n      ];\n      // Actually returns correct sets for queries, since matchers can evaluate\n      // themselves against models in memory\n      spyOn(Database, 'run').and.callFake(query => {\n        const results = this.models.filter(model =>\n          query._matchers.every(matcher => matcher.evaluate(model))\n        );\n        return Promise.resolve(results);\n      });\n    });\n\n    describe(\"when given an array or input that is not an array\", () =>\n      it(\"resolves immediately with an empty array\", (done) => {\n        Database.modelify(Thread, null).then(output => {\n          expect(output).toEqual([]);\n          done();\n        });\n      })\n    );\n\n    describe(\"when given an array of mixed ids and models\", () =>\n      it(\"resolves with an array of models\", (done) => {\n        const input = ['local-B', 'local-C', this.models[0]];\n        const expectedOutput = [this.models[1], this.models[2], this.models[0]];\n        Database.modelify(Thread, input).then(output => {\n          expect(output).toEqual(expectedOutput);\n          done();\n        });\n      })\n\n    );\n\n    describe(\"when the input is only IDs\", () =>\n      it(\"resolves with an array of models\", (done) => {\n        const input = ['local-B', 'local-C', 'local-D'];\n        const expectedOutput = [this.models[1], this.models[2], this.models[3]];\n        Database.modelify(Thread, input).then(output => {\n          expect(output).toEqual(expectedOutput);\n          done();\n        });\n      })\n\n    );\n\n    describe(\"when the input is all models\", () =>\n      it(\"resolves with an array of models\", (done) => {\n        const input = [this.models[0], this.models[1], this.models[2], this.models[3]];\n        const expectedOutput = [this.models[0], this.models[1], this.models[2], this.models[3]];\n        Database.modelify(Thread, input).then(output => {\n          expect(output).toEqual(expectedOutput);\n          done();\n        });\n      })\n\n    );\n  });\n\n  describe(\"count\", () => {\n    it(\"should pass the provided predicates on to the ModelQuery\", () => {\n      Database.findAll(TestModel, testMatchers);\n      expect(ModelQuery.prototype.where).toHaveBeenCalledWith(testMatchers);\n    });\n\n    it(\"should return a ModelQuery configured for COUNT ready to be executed\", () => {\n      const q = Database.findAll(TestModel, testMatchers);\n      expect(q.sql()).toBe(\"SELECT `TestModel`.`data` FROM `TestModel`  WHERE `TestModel`.`id` = 'b'  \");\n    });\n  });\n\n  describe(\"inTransaction\", () => {\n    it(\"calls the provided function inside an exclusive transaction\", (done) =>\n      Database.inTransaction(() => {\n        return Database._query(\"TEST\");\n      }).then(() => {\n        expect(this.performed.length).toBe(3);\n        expect(this.performed[0].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[1].query).toBe(\"TEST\");\n        expect(this.performed[2].query).toBe(\"COMMIT\");\n        done();\n      })\n    );\n\n    it(\"preserves resolved values\", (done) =>\n      Database.inTransaction(() => {\n        Database._query(\"TEST\");\n        return Promise.resolve(\"myValue\");\n      }).then(myValue => {\n        expect(myValue).toBe(\"myValue\");\n        done();\n      })\n    );\n\n    it(\"always fires a COMMIT, even if the body function fails\", (done) =>\n      Database.inTransaction(() => {\n        throw new Error(\"BOOO\");\n      }).catch(() => {\n        expect(this.performed.length).toBe(2);\n        expect(this.performed[0].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[1].query).toBe(\"COMMIT\");\n        done();\n      })\n\n    );\n\n    it(\"can be called multiple times and get queued\", (done) =>\n      Promise.all([\n        Database.inTransaction(() => { }),\n        Database.inTransaction(() => { }),\n        Database.inTransaction(() => { }),\n      ]).then(() => {\n        expect(this.performed.length).toBe(6);\n        expect(this.performed[0].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[1].query).toBe(\"COMMIT\");\n        expect(this.performed[2].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[3].query).toBe(\"COMMIT\");\n        expect(this.performed[4].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[5].query).toBe(\"COMMIT\");\n        done();\n      })\n\n    );\n\n    it(\"carries on if one of them fails, but still calls the COMMIT for the failed block\", (done) => {\n      let caughtError = false;\n      Promise.all([\n        Database.inTransaction(() => Database._query(\"ONE\")),\n        Database.inTransaction(() => { throw new Error(\"fail\"); }).catch(() => { caughtError = true }),\n        Database.inTransaction(() => Database._query(\"THREE\")),\n      ]).then(() => {\n        expect(this.performed.length).toBe(8);\n        expect(this.performed[0].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[1].query).toBe(\"ONE\");\n        expect(this.performed[2].query).toBe(\"COMMIT\");\n        expect(this.performed[3].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[4].query).toBe(\"COMMIT\");\n        expect(this.performed[5].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[6].query).toBe(\"THREE\");\n        expect(this.performed[7].query).toBe(\"COMMIT\");\n        expect(caughtError).toBe(true);\n        done();\n      });\n    });\n\n    it(\"is actually running in series and blocks on never-finishing specs\", (done) => {\n      let resolver = null;\n      let blockedPromiseDone = false;\n      Database.inTransaction(() => { }).then(() => {\n        expect(this.performed.length).toBe(2);\n        expect(this.performed[0].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[1].query).toBe(\"COMMIT\");\n      })\n      .then(() => {\n        Database.inTransaction(() => new Promise((resolve) => {\n          resolver = resolve;\n        }))\n        Database.inTransaction(() => { }).then(() => {\n          blockedPromiseDone = true;\n        })\n\n        jasmine.waitFor(() => resolver).then(() => {\n          expect(this.performed.length).toBe(3);\n          expect(this.performed[2].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n          expect(blockedPromiseDone).toBe(false);\n\n          // Now that we've made our assertion about blocking, we need to clean up\n          // our test and actually resolve that blocked promise now, otherwise\n          // remaining tests won't run properly.\n          resolver();\n\n          jasmine.waitFor(() => blockedPromiseDone).then(() => {\n            expect(blockedPromiseDone).toBe(true);\n            done();\n          });\n        });\n      });\n    });\n\n    it(\"can be called multiple times and preserve return values\", (done) => {\n      let v1 = null;\n      let v2 = null;\n      let v3 = null;\n      Promise.all([\n        Database.inTransaction(() => \"a\").then(val => { v1 = val }),\n        Database.inTransaction(() => \"b\").then(val => { v2 = val }),\n        Database.inTransaction(() => \"c\").then(val => { v3 = val }),\n      ]).then(() => {\n        expect(v1).toBe(\"a\");\n        expect(v2).toBe(\"b\");\n        expect(v3).toBe(\"c\");\n        done();\n      });\n    });\n\n    it(\"can be called multiple times and get queued\", (done) =>\n      Database.inTransaction(() => { })\n      .then(() => Database.inTransaction(() => { }))\n      .then(() => Database.inTransaction(() => { }))\n      .then(() => {\n        expect(this.performed.length).toBe(6);\n        expect(this.performed[0].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[1].query).toBe(\"COMMIT\");\n        expect(this.performed[2].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[3].query).toBe(\"COMMIT\");\n        expect(this.performed[4].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[5].query).toBe(\"COMMIT\");\n        done();\n      })\n    );\n  });\n});\n"
  },
  {
    "__docId__": 503,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe8",
    "testId": 8,
    "memberof": "spec/database-store-spec.js",
    "testDepth": 0,
    "longname": "spec/database-store-spec.js~describe8",
    "access": null,
    "description": "Database",
    "lineNumber": 9
  },
  {
    "__docId__": 504,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe9",
    "testId": 9,
    "memberof": "spec/database-store-spec.js~describe8",
    "testDepth": 1,
    "longname": "spec/database-store-spec.js~describe8.describe9",
    "access": null,
    "description": "find",
    "lineNumber": 35
  },
  {
    "__docId__": 505,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe10",
    "testId": 10,
    "memberof": "spec/database-store-spec.js~describe8",
    "testDepth": 1,
    "longname": "spec/database-store-spec.js~describe8.describe10",
    "access": null,
    "description": "findBy",
    "lineNumber": 42
  },
  {
    "__docId__": 506,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it11",
    "testId": 11,
    "memberof": "spec/database-store-spec.js~describe8.describe10",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe10.it11",
    "access": null,
    "description": "should pass the provided predicates on to the ModelQuery",
    "lineNumber": 43
  },
  {
    "__docId__": 507,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it12",
    "testId": 12,
    "memberof": "spec/database-store-spec.js~describe8.describe10",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe10.it12",
    "access": null,
    "description": "should return a ModelQuery ready to be executed",
    "lineNumber": 48
  },
  {
    "__docId__": 508,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe13",
    "testId": 13,
    "memberof": "spec/database-store-spec.js~describe8",
    "testDepth": 1,
    "longname": "spec/database-store-spec.js~describe8.describe13",
    "access": null,
    "description": "findAll",
    "lineNumber": 54
  },
  {
    "__docId__": 509,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it14",
    "testId": 14,
    "memberof": "spec/database-store-spec.js~describe8.describe13",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe13.it14",
    "access": null,
    "description": "should pass the provided predicates on to the ModelQuery",
    "lineNumber": 55
  },
  {
    "__docId__": 510,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it15",
    "testId": 15,
    "memberof": "spec/database-store-spec.js~describe8.describe13",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe13.it15",
    "access": null,
    "description": "should return a ModelQuery ready to be executed",
    "lineNumber": 60
  },
  {
    "__docId__": 511,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe16",
    "testId": 16,
    "memberof": "spec/database-store-spec.js~describe8",
    "testDepth": 1,
    "longname": "spec/database-store-spec.js~describe8.describe16",
    "access": null,
    "description": "modelify",
    "lineNumber": 66
  },
  {
    "__docId__": 512,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe17",
    "testId": 17,
    "memberof": "spec/database-store-spec.js~describe8.describe16",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe16.describe17",
    "access": null,
    "description": "when given an array or input that is not an array",
    "lineNumber": 84
  },
  {
    "__docId__": 513,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe18",
    "testId": 18,
    "memberof": "spec/database-store-spec.js~describe8.describe16",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe16.describe18",
    "access": null,
    "description": "when given an array of mixed ids and models",
    "lineNumber": 93
  },
  {
    "__docId__": 514,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe19",
    "testId": 19,
    "memberof": "spec/database-store-spec.js~describe8.describe16",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe16.describe19",
    "access": null,
    "description": "when the input is only IDs",
    "lineNumber": 105
  },
  {
    "__docId__": 515,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe20",
    "testId": 20,
    "memberof": "spec/database-store-spec.js~describe8.describe16",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe16.describe20",
    "access": null,
    "description": "when the input is all models",
    "lineNumber": 117
  },
  {
    "__docId__": 516,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe21",
    "testId": 21,
    "memberof": "spec/database-store-spec.js~describe8",
    "testDepth": 1,
    "longname": "spec/database-store-spec.js~describe8.describe21",
    "access": null,
    "description": "count",
    "lineNumber": 130
  },
  {
    "__docId__": 517,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it22",
    "testId": 22,
    "memberof": "spec/database-store-spec.js~describe8.describe21",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe21.it22",
    "access": null,
    "description": "should pass the provided predicates on to the ModelQuery",
    "lineNumber": 131
  },
  {
    "__docId__": 518,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it23",
    "testId": 23,
    "memberof": "spec/database-store-spec.js~describe8.describe21",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe21.it23",
    "access": null,
    "description": "should return a ModelQuery configured for COUNT ready to be executed",
    "lineNumber": 136
  },
  {
    "__docId__": 519,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe24",
    "testId": 24,
    "memberof": "spec/database-store-spec.js~describe8",
    "testDepth": 1,
    "longname": "spec/database-store-spec.js~describe8.describe24",
    "access": null,
    "description": "inTransaction",
    "lineNumber": 142
  },
  {
    "__docId__": 520,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it25",
    "testId": 25,
    "memberof": "spec/database-store-spec.js~describe8.describe24",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe24.it25",
    "access": null,
    "description": "calls the provided function inside an exclusive transaction",
    "lineNumber": 143
  },
  {
    "__docId__": 521,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it26",
    "testId": 26,
    "memberof": "spec/database-store-spec.js~describe8.describe24",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe24.it26",
    "access": null,
    "description": "preserves resolved values",
    "lineNumber": 155
  },
  {
    "__docId__": 522,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it27",
    "testId": 27,
    "memberof": "spec/database-store-spec.js~describe8.describe24",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe24.it27",
    "access": null,
    "description": "always fires a COMMIT, even if the body function fails",
    "lineNumber": 165
  },
  {
    "__docId__": 523,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it28",
    "testId": 28,
    "memberof": "spec/database-store-spec.js~describe8.describe24",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe24.it28",
    "access": null,
    "description": "can be called multiple times and get queued",
    "lineNumber": 177
  },
  {
    "__docId__": 524,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it29",
    "testId": 29,
    "memberof": "spec/database-store-spec.js~describe8.describe24",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe24.it29",
    "access": null,
    "description": "carries on if one of them fails, but still calls the COMMIT for the failed block",
    "lineNumber": 195
  },
  {
    "__docId__": 525,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it30",
    "testId": 30,
    "memberof": "spec/database-store-spec.js~describe8.describe24",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe24.it30",
    "access": null,
    "description": "is actually running in series and blocks on never-finishing specs",
    "lineNumber": 216
  },
  {
    "__docId__": 526,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it31",
    "testId": 31,
    "memberof": "spec/database-store-spec.js~describe8.describe24",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe24.it31",
    "access": null,
    "description": "can be called multiple times and preserve return values",
    "lineNumber": 250
  },
  {
    "__docId__": 527,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it32",
    "testId": 32,
    "memberof": "spec/database-store-spec.js~describe8.describe24",
    "testDepth": 2,
    "longname": "spec/database-store-spec.js~describe8.describe24.it32",
    "access": null,
    "description": "can be called multiple times and get queued",
    "lineNumber": 266
  },
  {
    "__docId__": 528,
    "kind": "testFile",
    "static": true,
    "variation": null,
    "name": "spec/database-transaction-spec.js",
    "memberof": null,
    "longname": "spec/database-transaction-spec.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint dot-notation:0 */\nimport {Database, TestModel, Category} from './fixtures';\nimport DatabaseTransaction from '../lib/database-transaction';\nimport DatabaseChangeRecord from '../lib/database-change-record';\n\nconst testModelInstance = new TestModel({id: \"1234\"});\nconst testModelInstanceA = new TestModel({id: \"AAA\"});\nconst testModelInstanceB = new TestModel({id: \"BBB\"});\n\nfunction __range__(left, right, inclusive) {\n  const range = [];\n  const ascending = left < right;\n  const incr = ascending ? right + 1 : right - 1;\n  const end = !inclusive ? right : incr;\n  for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {\n    range.push(i);\n  }\n  return range;\n}\n\ndescribe(\"DatabaseTransaction\", function DatabaseTransactionSpecs() {\n  beforeEach(() => {\n    this.databaseMutationHooks = [];\n    this.performed = [];\n\n    spyOn(Database, '_query').and.callFake((query, values = []) => {\n      this.performed.push({query, values});\n      return Promise.resolve([]);\n    });\n    spyOn(Database, 'transactionDidCommitChanges');\n    spyOn(Database, 'mutationHooks').and.returnValue(this.databaseMutationHooks)\n\n    this.transaction = new DatabaseTransaction(Database);\n\n    jasmine.clock().install();\n  });\n\n  afterEach(() => {\n    jasmine.clock().uninstall();\n  });\n\n  describe(\"execute\", () => {});\n\n  describe(\"persistModel\", () => {\n    it(\"should throw an exception if the model is not a subclass of Model\", () =>\n      expect(() => this.transaction.persistModel({id: 'asd', subject: 'bla'})).toThrow()\n    );\n\n    it(\"should call through to persistModels\", () => {\n      spyOn(this.transaction, 'persistModels').and.returnValue(Promise.resolve());\n      this.transaction.persistModel(testModelInstance);\n      jasmine.clock().tick();\n      expect(this.transaction.persistModels.calls.count()).toBe(1);\n    });\n  });\n\n  describe(\"persistModels\", () => {\n    it(\"should call transactionDidCommitChanges with a change that contains the models\", (done) => {\n      this.transaction.execute(t => {\n        return t.persistModels([testModelInstanceA, testModelInstanceB]);\n      });\n\n      jasmine.waitFor(() =>\n        Database.transactionDidCommitChanges.calls.count() > 0\n      )\n      .then(() => {\n        const change = Database.transactionDidCommitChanges.calls.first().args[0];\n        expect(change).toEqual([new DatabaseChangeRecord(Database, {\n          objectClass: TestModel.name,\n          objectIds: [testModelInstanceA.id, testModelInstanceB.id],\n          objects: [testModelInstanceA, testModelInstanceB],\n          type: 'persist',\n        })]);\n        done();\n      });\n    });\n\n    it(\"should call through to _writeModels after checking them\", (done) => {\n      spyOn(this.transaction, '_writeModels').and.returnValue(Promise.resolve());\n      this.transaction.persistModels([testModelInstanceA, testModelInstanceB]);\n      jasmine.waitFor(() => this.transaction._writeModels.calls.count() > 0).then(() => {\n        expect(this.transaction._writeModels.calls.count()).toBe(1)\n        done()\n      });\n    });\n\n    it(\"should throw an exception if the models are not the same class, since it cannot be specified by the trigger payload\", () =>\n      expect(() => this.transaction.persistModels([testModelInstanceA, new Category()])).toThrow()\n    );\n\n    it(\"should throw an exception if the models are not a subclass of Model\", () =>\n      expect(() => this.transaction.persistModels([{id: 'asd', subject: 'bla'}])).toThrow()\n    );\n\n    describe(\"mutationHooks\", () => {\n      beforeEach(() => {\n        this.beforeShouldThrow = false;\n        this.beforeShouldReject = false;\n\n        this.hook = {\n          beforeDatabaseChange: jasmine.createSpy('beforeDatabaseChange').and.callFake(() => {\n            if (this.beforeShouldThrow) { throw new Error(\"beforeShouldThrow\"); }\n            return new Promise((resolve) => {\n              setTimeout(() => {\n                if (this.beforeShouldReject) { resolve(new Error(\"beforeShouldReject\")); }\n                resolve(\"value\");\n              }\n              , 1000);\n            });\n          }),\n          afterDatabaseChange: jasmine.createSpy('afterDatabaseChange').and.callFake(() => {\n            return new Promise((resolve) => setTimeout(() => resolve(), 1000));\n          }),\n        };\n\n        this.databaseMutationHooks.push(this.hook);\n\n        this.writeModelsResolve = null;\n        spyOn(this.transaction, '_writeModels').and.callFake(() => {\n          return new Promise((resolve) => {\n            this.writeModelsResolve = resolve;\n          });\n        });\n      });\n\n      it(\"should run pre-mutation hooks, wait to write models, and then run post-mutation hooks\", (done) => {\n        this.transaction.persistModels([testModelInstanceA, testModelInstanceB]);\n\n        expect(this.hook.beforeDatabaseChange).toHaveBeenCalledWith(\n          this.transaction._query,\n          {\n            objects: [testModelInstanceA, testModelInstanceB],\n            objectIds: [testModelInstanceA.id, testModelInstanceB.id],\n            objectClass: testModelInstanceA.constructor.name,\n            type: 'persist',\n          },\n          undefined\n        );\n        expect(this.transaction._writeModels).not.toHaveBeenCalled();\n        jasmine.clock().tick(1000);\n        jasmine.waitFor(() => this.transaction._writeModels.calls.count() > 0).then(() => {\n          expect(this.hook.afterDatabaseChange).not.toHaveBeenCalled();\n          this.writeModelsResolve();\n\n          jasmine.waitFor(() => this.hook.afterDatabaseChange.calls.count() > 0).then(() => {\n            expect(this.hook.afterDatabaseChange).toHaveBeenCalledWith(\n              this.transaction._query,\n              {\n                objects: [testModelInstanceA, testModelInstanceB],\n                objectIds: [testModelInstanceA.id, testModelInstanceB.id],\n                objectClass: testModelInstanceA.constructor.name,\n                type: 'persist',\n              },\n              \"value\"\n            );\n            done();\n          });\n        });\n      });\n\n      it(\"should carry on if a pre-mutation hook throws\", (done) => {\n        this.beforeShouldThrow = true;\n        this.transaction.persistModels([testModelInstanceA, testModelInstanceB]);\n        jasmine.clock().tick(1000);\n        expect(this.hook.beforeDatabaseChange).toHaveBeenCalled();\n        jasmine.waitFor(() => this.transaction._writeModels.calls.count() > 0).then(done);\n      });\n\n      it(\"should carry on if a pre-mutation hook rejects\", (done) => {\n        this.beforeShouldReject = true;\n        this.transaction.persistModels([testModelInstanceA, testModelInstanceB]);\n        jasmine.clock().tick(1000);\n        expect(this.hook.beforeDatabaseChange).toHaveBeenCalled();\n        jasmine.waitFor(() => this.transaction._writeModels.calls.count() > 0).then(done);\n      });\n    });\n  });\n\n  describe(\"unpersistModel\", () => {\n    it(\"should delete the model by id\", (done) =>\n      this.transaction.execute(() => {\n        return this.transaction.unpersistModel(testModelInstance);\n      })\n      .then(() => {\n        expect(this.performed.length).toBe(3);\n        expect(this.performed[0].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n        expect(this.performed[1].query).toBe(\"DELETE FROM `TestModel` WHERE `id` = ?\");\n        expect(this.performed[1].values[0]).toBe('1234');\n        expect(this.performed[2].query).toBe(\"COMMIT\");\n        done();\n      })\n    );\n\n    it(\"should call transactionDidCommitChanges with a change that contains the model\", (done) => {\n      this.transaction.execute(() => {\n        return this.transaction.unpersistModel(testModelInstance);\n      });\n      jasmine.waitFor(() =>\n        Database.transactionDidCommitChanges.calls.count() > 0\n      ).then(() => {\n        const change = Database.transactionDidCommitChanges.calls.first().args[0];\n        expect(change).toEqual([new DatabaseChangeRecord(Database, {\n          objectClass: TestModel.name,\n          objectIds: [testModelInstance.id],\n          objects: [testModelInstance],\n          type: 'unpersist',\n        })]);\n        done();\n      });\n    });\n\n    describe(\"when the model has collection attributes\", () =>\n      it(\"should delete all of the elements in the join tables\", (done) => {\n        TestModel.configureWithCollectionAttribute();\n        this.transaction.execute(t => {\n          return t.unpersistModel(testModelInstance);\n        })\n        .then(() => {\n          expect(this.performed.length).toBe(4);\n          expect(this.performed[0].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n          expect(this.performed[2].query).toBe(\"DELETE FROM `TestModelCategory` WHERE `id` = ?\");\n          expect(this.performed[2].values[0]).toBe('1234');\n          expect(this.performed[3].query).toBe(\"COMMIT\");\n          done();\n        });\n      })\n\n    );\n\n    describe(\"when the model has joined data attributes\", () =>\n      it(\"should delete the element in the joined data table\", (done) => {\n        TestModel.configureWithJoinedDataAttribute();\n        this.transaction.execute(t => {\n          return t.unpersistModel(testModelInstance);\n        })\n        .then(() => {\n          expect(this.performed.length).toBe(4);\n          expect(this.performed[0].query).toBe(\"BEGIN IMMEDIATE TRANSACTION\");\n          expect(this.performed[2].query).toBe(\"DELETE FROM `TestModelBody` WHERE `id` = ?\");\n          expect(this.performed[2].values[0]).toBe('1234');\n          expect(this.performed[3].query).toBe(\"COMMIT\");\n          done();\n        });\n      })\n\n    );\n  });\n\n  describe(\"_writeModels\", () => {\n    it(\"should compose a REPLACE INTO query to save the model\", () => {\n      TestModel.configureWithCollectionAttribute();\n      this.transaction._writeModels([testModelInstance]);\n      expect(this.performed[0].query).toBe(\"REPLACE INTO `TestModel` (id,data,other) VALUES (?,?,?)\");\n    });\n\n    it(\"should save the model JSON into the data column\", () => {\n      this.transaction._writeModels([testModelInstance]);\n      expect(this.performed[0].values[1]).toEqual(JSON.stringify(testModelInstance));\n    });\n\n    describe(\"when the model defines additional queryable attributes\", () => {\n      beforeEach(() => {\n        TestModel.configureWithAllAttributes();\n        this.m = new TestModel({\n          id: 'local-6806434c-b0cd',\n          datetime: new Date(),\n          string: 'hello world',\n          boolean: true,\n          number: 15,\n        });\n      });\n\n      it(\"should populate additional columns defined by the attributes\", () => {\n        this.transaction._writeModels([this.m]);\n        expect(this.performed[0].query).toBe(\"REPLACE INTO `TestModel` (id,data,datetime,string-json-key,boolean,number) VALUES (?,?,?,?,?,?)\");\n      });\n\n      it(\"should use the JSON-form values of the queryable attributes\", () => {\n        const json = this.m.toJSON();\n        this.transaction._writeModels([this.m]);\n\n        const { values } = this.performed[0];\n        expect(values[2]).toEqual(json['datetime']);\n        expect(values[3]).toEqual(json['string-json-key']);\n        expect(values[4]).toEqual(json['boolean']);\n        expect(values[5]).toEqual(json['number']);\n      });\n    });\n\n    describe(\"when the model has collection attributes\", () => {\n      beforeEach(() => {\n        TestModel.configureWithCollectionAttribute();\n        this.m = new TestModel({id: 'local-6806434c-b0cd', other: 'other'});\n        this.m.categories = [new Category({id: 'a'}), new Category({id: 'b'})];\n        this.transaction._writeModels([this.m]);\n      });\n\n      it(\"should delete all association records for the model from join tables\", () => {\n        expect(this.performed[1].query).toBe('DELETE FROM `TestModelCategory` WHERE `id` IN (\\'local-6806434c-b0cd\\')');\n      });\n\n      it(\"should insert new association records into join tables in a single query, and include queryableBy columns\", () => {\n        expect(this.performed[2].query).toBe('INSERT OR IGNORE INTO `TestModelCategory` (`id`,`value`,`other`) VALUES (?,?,?),(?,?,?)');\n        expect(this.performed[2].values).toEqual(['local-6806434c-b0cd', 'a', 'other', 'local-6806434c-b0cd', 'b', 'other']);\n      });\n    });\n\n    describe(\"model collection attributes query building\", () => {\n      beforeEach(() => {\n        TestModel.configureWithCollectionAttribute();\n        this.m = new TestModel({id: 'local-6806434c-b0cd', other: 'other'});\n        this.m.categories = [];\n      });\n\n      it(\"should page association records into multiple queries correctly\", () => {\n        const iterable = __range__(0, 199, true);\n        for (let j = 0; j < iterable.length; j++) {\n          const i = iterable[j];\n          this.m.categories.push(new Category({id: `id-${i}`}));\n        }\n        this.transaction._writeModels([this.m]);\n\n        const collectionAttributeQueries = this.performed.filter(i => i.query.indexOf('INSERT OR IGNORE INTO `TestModelCategory`') === 0\n        );\n\n        expect(collectionAttributeQueries.length).toBe(1);\n        expect(collectionAttributeQueries[0].values[(200 * 3) - 2]).toEqual('id-199');\n      });\n\n      it(\"should page association records into multiple queries correctly\", () => {\n        const iterable = __range__(0, 200, true);\n        for (let j = 0; j < iterable.length; j++) {\n          const i = iterable[j];\n          this.m.categories.push(new Category({id: `id-${i}`}));\n        }\n        this.transaction._writeModels([this.m]);\n\n        const collectionAttributeQueries = this.performed.filter(i => i.query.indexOf('INSERT OR IGNORE INTO `TestModelCategory`') === 0\n        );\n\n        expect(collectionAttributeQueries.length).toBe(2);\n        expect(collectionAttributeQueries[0].values[(200 * 3) - 2]).toEqual('id-199');\n        expect(collectionAttributeQueries[1].values[1]).toEqual('id-200');\n      });\n\n      it(\"should page association records into multiple queries correctly\", () => {\n        const iterable = __range__(0, 201, true);\n        for (let j = 0; j < iterable.length; j++) {\n          const i = iterable[j];\n          this.m.categories.push(new Category({id: `id-${i}`}));\n        }\n        this.transaction._writeModels([this.m]);\n\n        const collectionAttributeQueries = this.performed.filter(i => i.query.indexOf('INSERT OR IGNORE INTO `TestModelCategory`') === 0\n        );\n\n        expect(collectionAttributeQueries.length).toBe(2);\n        expect(collectionAttributeQueries[0].values[(200 * 3) - 2]).toEqual('id-199');\n        expect(collectionAttributeQueries[1].values[1]).toEqual('id-200');\n        expect(collectionAttributeQueries[1].values[4]).toEqual('id-201');\n      });\n    });\n\n    describe(\"when the model has joined data attributes\", () => {\n      beforeEach(() => TestModel.configureWithJoinedDataAttribute());\n\n      it(\"should not include the value to the joined attribute in the JSON written to the main model table\", () => {\n        this.m = new TestModel({id: 'local-6806434c-b0cd', body: 'hello world'});\n        this.transaction._writeModels([this.m]);\n        expect(this.performed[0].values).toEqual(['local-6806434c-b0cd', '{\"id\":\"local-6806434c-b0cd\"}']);\n      });\n\n      it(\"should write the value to the joined table if it is defined\", () => {\n        this.m = new TestModel({id: 'local-6806434c-b0cd', body: 'hello world'});\n        this.transaction._writeModels([this.m]);\n        expect(this.performed[1].query).toBe('REPLACE INTO `TestModelBody` (`id`, `value`) VALUES (?, ?)');\n        expect(this.performed[1].values).toEqual([this.m.id, this.m.body]);\n      });\n\n      it(\"should not write the value to the joined table if it undefined\", () => {\n        this.m = new TestModel({id: 'local-6806434c-b0cd'});\n        this.transaction._writeModels([this.m]);\n        expect(this.performed.length).toBe(1);\n      });\n    });\n  });\n});\n"
  },
  {
    "__docId__": 529,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe33",
    "testId": 33,
    "memberof": "spec/database-transaction-spec.js",
    "testDepth": 0,
    "longname": "spec/database-transaction-spec.js~describe33",
    "access": null,
    "description": "DatabaseTransaction",
    "lineNumber": 21
  },
  {
    "__docId__": 530,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe34",
    "testId": 34,
    "memberof": "spec/database-transaction-spec.js~describe33",
    "testDepth": 1,
    "longname": "spec/database-transaction-spec.js~describe33.describe34",
    "access": null,
    "description": "execute",
    "lineNumber": 42
  },
  {
    "__docId__": 531,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe35",
    "testId": 35,
    "memberof": "spec/database-transaction-spec.js~describe33",
    "testDepth": 1,
    "longname": "spec/database-transaction-spec.js~describe33.describe35",
    "access": null,
    "description": "persistModel",
    "lineNumber": 44
  },
  {
    "__docId__": 532,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it36",
    "testId": 36,
    "memberof": "spec/database-transaction-spec.js~describe33.describe35",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe35.it36",
    "access": null,
    "description": "should throw an exception if the model is not a subclass of Model",
    "lineNumber": 45
  },
  {
    "__docId__": 533,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it37",
    "testId": 37,
    "memberof": "spec/database-transaction-spec.js~describe33.describe35",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe35.it37",
    "access": null,
    "description": "should call through to persistModels",
    "lineNumber": 49
  },
  {
    "__docId__": 534,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe38",
    "testId": 38,
    "memberof": "spec/database-transaction-spec.js~describe33",
    "testDepth": 1,
    "longname": "spec/database-transaction-spec.js~describe33.describe38",
    "access": null,
    "description": "persistModels",
    "lineNumber": 57
  },
  {
    "__docId__": 535,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it39",
    "testId": 39,
    "memberof": "spec/database-transaction-spec.js~describe33.describe38",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe38.it39",
    "access": null,
    "description": "should call transactionDidCommitChanges with a change that contains the models",
    "lineNumber": 58
  },
  {
    "__docId__": 536,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it40",
    "testId": 40,
    "memberof": "spec/database-transaction-spec.js~describe33.describe38",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe38.it40",
    "access": null,
    "description": "should call through to _writeModels after checking them",
    "lineNumber": 78
  },
  {
    "__docId__": 537,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it41",
    "testId": 41,
    "memberof": "spec/database-transaction-spec.js~describe33.describe38",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe38.it41",
    "access": null,
    "description": "should throw an exception if the models are not the same class, since it cannot be specified by the trigger payload",
    "lineNumber": 87
  },
  {
    "__docId__": 538,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it42",
    "testId": 42,
    "memberof": "spec/database-transaction-spec.js~describe33.describe38",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe38.it42",
    "access": null,
    "description": "should throw an exception if the models are not a subclass of Model",
    "lineNumber": 91
  },
  {
    "__docId__": 539,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe43",
    "testId": 43,
    "memberof": "spec/database-transaction-spec.js~describe33.describe38",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe38.describe43",
    "access": null,
    "description": "mutationHooks",
    "lineNumber": 95
  },
  {
    "__docId__": 540,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it44",
    "testId": 44,
    "memberof": "spec/database-transaction-spec.js~describe33.describe38.describe43",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe38.describe43.it44",
    "access": null,
    "description": "should run pre-mutation hooks, wait to write models, and then run post-mutation hooks",
    "lineNumber": 126
  },
  {
    "__docId__": 541,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it45",
    "testId": 45,
    "memberof": "spec/database-transaction-spec.js~describe33.describe38.describe43",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe38.describe43.it45",
    "access": null,
    "description": "should carry on if a pre-mutation hook throws",
    "lineNumber": 161
  },
  {
    "__docId__": 542,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it46",
    "testId": 46,
    "memberof": "spec/database-transaction-spec.js~describe33.describe38.describe43",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe38.describe43.it46",
    "access": null,
    "description": "should carry on if a pre-mutation hook rejects",
    "lineNumber": 169
  },
  {
    "__docId__": 543,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe47",
    "testId": 47,
    "memberof": "spec/database-transaction-spec.js~describe33",
    "testDepth": 1,
    "longname": "spec/database-transaction-spec.js~describe33.describe47",
    "access": null,
    "description": "unpersistModel",
    "lineNumber": 179
  },
  {
    "__docId__": 544,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it48",
    "testId": 48,
    "memberof": "spec/database-transaction-spec.js~describe33.describe47",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe47.it48",
    "access": null,
    "description": "should delete the model by id",
    "lineNumber": 180
  },
  {
    "__docId__": 545,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it49",
    "testId": 49,
    "memberof": "spec/database-transaction-spec.js~describe33.describe47",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe47.it49",
    "access": null,
    "description": "should call transactionDidCommitChanges with a change that contains the model",
    "lineNumber": 194
  },
  {
    "__docId__": 546,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe50",
    "testId": 50,
    "memberof": "spec/database-transaction-spec.js~describe33.describe47",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe47.describe50",
    "access": null,
    "description": "when the model has collection attributes",
    "lineNumber": 212
  },
  {
    "__docId__": 547,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe51",
    "testId": 51,
    "memberof": "spec/database-transaction-spec.js~describe33.describe47",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe47.describe51",
    "access": null,
    "description": "when the model has joined data attributes",
    "lineNumber": 230
  },
  {
    "__docId__": 548,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe52",
    "testId": 52,
    "memberof": "spec/database-transaction-spec.js~describe33",
    "testDepth": 1,
    "longname": "spec/database-transaction-spec.js~describe33.describe52",
    "access": null,
    "description": "_writeModels",
    "lineNumber": 249
  },
  {
    "__docId__": 549,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it53",
    "testId": 53,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.it53",
    "access": null,
    "description": "should compose a REPLACE INTO query to save the model",
    "lineNumber": 250
  },
  {
    "__docId__": 550,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it54",
    "testId": 54,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.it54",
    "access": null,
    "description": "should save the model JSON into the data column",
    "lineNumber": 256
  },
  {
    "__docId__": 551,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe55",
    "testId": 55,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe55",
    "access": null,
    "description": "when the model defines additional queryable attributes",
    "lineNumber": 261
  },
  {
    "__docId__": 552,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it56",
    "testId": 56,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52.describe55",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe55.it56",
    "access": null,
    "description": "should populate additional columns defined by the attributes",
    "lineNumber": 273
  },
  {
    "__docId__": 553,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it57",
    "testId": 57,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52.describe55",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe55.it57",
    "access": null,
    "description": "should use the JSON-form values of the queryable attributes",
    "lineNumber": 278
  },
  {
    "__docId__": 554,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe58",
    "testId": 58,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe58",
    "access": null,
    "description": "when the model has collection attributes",
    "lineNumber": 290
  },
  {
    "__docId__": 555,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it59",
    "testId": 59,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52.describe58",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe58.it59",
    "access": null,
    "description": "should delete all association records for the model from join tables",
    "lineNumber": 298
  },
  {
    "__docId__": 556,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it60",
    "testId": 60,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52.describe58",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe58.it60",
    "access": null,
    "description": "should insert new association records into join tables in a single query, and include queryableBy columns",
    "lineNumber": 302
  },
  {
    "__docId__": 557,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe61",
    "testId": 61,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe61",
    "access": null,
    "description": "model collection attributes query building",
    "lineNumber": 308
  },
  {
    "__docId__": 558,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it62",
    "testId": 62,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52.describe61",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe61.it62",
    "access": null,
    "description": "should page association records into multiple queries correctly",
    "lineNumber": 315
  },
  {
    "__docId__": 559,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it63",
    "testId": 63,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52.describe61",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe61.it63",
    "access": null,
    "description": "should page association records into multiple queries correctly",
    "lineNumber": 330
  },
  {
    "__docId__": 560,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it64",
    "testId": 64,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52.describe61",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe61.it64",
    "access": null,
    "description": "should page association records into multiple queries correctly",
    "lineNumber": 346
  },
  {
    "__docId__": 561,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe65",
    "testId": 65,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52",
    "testDepth": 2,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe65",
    "access": null,
    "description": "when the model has joined data attributes",
    "lineNumber": 364
  },
  {
    "__docId__": 562,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it66",
    "testId": 66,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52.describe65",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe65.it66",
    "access": null,
    "description": "should not include the value to the joined attribute in the JSON written to the main model table",
    "lineNumber": 367
  },
  {
    "__docId__": 563,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it67",
    "testId": 67,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52.describe65",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe65.it67",
    "access": null,
    "description": "should write the value to the joined table if it is defined",
    "lineNumber": 373
  },
  {
    "__docId__": 564,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it68",
    "testId": 68,
    "memberof": "spec/database-transaction-spec.js~describe33.describe52.describe65",
    "testDepth": 3,
    "longname": "spec/database-transaction-spec.js~describe33.describe52.describe65.it68",
    "access": null,
    "description": "should not write the value to the joined table if it undefined",
    "lineNumber": 380
  },
  {
    "__docId__": 565,
    "kind": "testFile",
    "static": true,
    "variation": null,
    "name": "spec/model-registry-spec.js",
    "memberof": null,
    "longname": "spec/model-registry-spec.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint quote-props: 0 */\nimport Model from '../lib/model';\nimport Attributes from '../lib/attributes';\nimport ModelRegistry from '../lib/model-registry';\n\nclass GoodTest extends Model {\n  static attributes = Object.assign({}, Model.attributes, {\n    \"foo\": Attributes.String({\n      modelKey: 'foo',\n      jsonKey: 'foo',\n    }),\n  });\n}\n\nclass BetterTest extends Model {\n  static attributes = Object.assign({}, Model.attributes, {\n    \"bar\": Attributes.String({\n      modelKey: 'bar',\n      jsonKey: 'bar',\n    }),\n  });\n}\n\nclass RandomClass {\n\n}\n\ndescribe('ModelRegistry', function ModelRegistrySpecs() {\n  beforeEach(() => {\n    this.registry = new ModelRegistry();\n    this.registry.registerDeferred({name: \"GoodTest\", resolver: () => GoodTest});\n  });\n\n  describe(\"registerDeferred\", () => {\n    it(\"can register constructors\", () => {\n      const testFn = () => BetterTest;\n      this.registry.registerDeferred({name: \"BetterTest\", resolver: testFn});\n      expect(this.registry.get(\"BetterTest\")).toBe(BetterTest);\n    });\n  });\n\n  describe(\"has\", () => {\n    it(\"tests if a constructor is in the registry\", () => {\n      expect(this.registry.has(\"GoodTest\")).toEqual(true);\n      expect(this.registry.has(\"BadTest\")).toEqual(false);\n    });\n  });\n\n  describe(\"deserialize\", () => {\n    it(\"deserializes the objects for a constructor\", () => {\n      const obj = this.registry.deserialize(\"GoodTest\", {foo: \"bar\"});\n      expect(obj instanceof GoodTest).toBe(true);\n      expect(obj.foo).toBe(\"bar\");\n    });\n\n    it(\"throws an error if the object can't be deserialized\", () =>\n      expect(() => this.registry.deserialize(\"BadTest\", {foo: \"bar\"})).toThrow()\n    );\n\n    it(\"throws if the registered constructor was not a model subclass\", () => {\n      this.registry.registerDeferred({name: \"RandomClass\", resolver: () => RandomClass});\n      expect(() => this.registry.deserialize(\"RandomClass\", {foo: \"bar\"})).toThrow();\n    });\n  });\n});\n"
  },
  {
    "__docId__": 566,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe69",
    "testId": 69,
    "memberof": "spec/model-registry-spec.js",
    "testDepth": 0,
    "longname": "spec/model-registry-spec.js~describe69",
    "access": null,
    "description": "ModelRegistry",
    "lineNumber": 28
  },
  {
    "__docId__": 567,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe70",
    "testId": 70,
    "memberof": "spec/model-registry-spec.js~describe69",
    "testDepth": 1,
    "longname": "spec/model-registry-spec.js~describe69.describe70",
    "access": null,
    "description": "registerDeferred",
    "lineNumber": 34
  },
  {
    "__docId__": 568,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it71",
    "testId": 71,
    "memberof": "spec/model-registry-spec.js~describe69.describe70",
    "testDepth": 2,
    "longname": "spec/model-registry-spec.js~describe69.describe70.it71",
    "access": null,
    "description": "can register constructors",
    "lineNumber": 35
  },
  {
    "__docId__": 569,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe72",
    "testId": 72,
    "memberof": "spec/model-registry-spec.js~describe69",
    "testDepth": 1,
    "longname": "spec/model-registry-spec.js~describe69.describe72",
    "access": null,
    "description": "has",
    "lineNumber": 42
  },
  {
    "__docId__": 570,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it73",
    "testId": 73,
    "memberof": "spec/model-registry-spec.js~describe69.describe72",
    "testDepth": 2,
    "longname": "spec/model-registry-spec.js~describe69.describe72.it73",
    "access": null,
    "description": "tests if a constructor is in the registry",
    "lineNumber": 43
  },
  {
    "__docId__": 571,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe74",
    "testId": 74,
    "memberof": "spec/model-registry-spec.js~describe69",
    "testDepth": 1,
    "longname": "spec/model-registry-spec.js~describe69.describe74",
    "access": null,
    "description": "deserialize",
    "lineNumber": 49
  },
  {
    "__docId__": 572,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it75",
    "testId": 75,
    "memberof": "spec/model-registry-spec.js~describe69.describe74",
    "testDepth": 2,
    "longname": "spec/model-registry-spec.js~describe69.describe74.it75",
    "access": null,
    "description": "deserializes the objects for a constructor",
    "lineNumber": 50
  },
  {
    "__docId__": 573,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it76",
    "testId": 76,
    "memberof": "spec/model-registry-spec.js~describe69.describe74",
    "testDepth": 2,
    "longname": "spec/model-registry-spec.js~describe69.describe74.it76",
    "access": null,
    "description": "throws an error if the object can't be deserialized",
    "lineNumber": 56
  },
  {
    "__docId__": 574,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it77",
    "testId": 77,
    "memberof": "spec/model-registry-spec.js~describe69.describe74",
    "testDepth": 2,
    "longname": "spec/model-registry-spec.js~describe69.describe74.it77",
    "access": null,
    "description": "throws if the registered constructor was not a model subclass",
    "lineNumber": 60
  },
  {
    "__docId__": 575,
    "kind": "testFile",
    "static": true,
    "variation": null,
    "name": "spec/model-spec.js",
    "memberof": null,
    "longname": "spec/model-spec.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint quote-props: 0 */\nimport Model from '../lib/model';\nimport {isTempId} from '../lib/utils';\nimport Attributes from '../lib/attributes';\n\nclass SubSubmodel extends Model {\n  static attributes = Object.assign({}, Model.attributes, {\n    'value': Attributes.Number({\n      modelKey: 'value',\n      jsonKey: 'value',\n    }),\n  });\n}\n\nclass SubmodelItem extends Model {}\n\nclass Submodel extends Model {\n  static attributes = Object.assign({}, Model.attributes, {\n    'testBoolean': Attributes.Boolean({\n      modelKey: 'testBoolean',\n      jsonKey: 'test_boolean',\n    }),\n    'testCollection': Attributes.Collection({\n      modelKey: 'testCollection',\n      jsonKey: 'test_collection',\n      itemClass: SubmodelItem,\n    }),\n    'testJoinedData': Attributes.JoinedData({\n      modelKey: 'testJoinedData',\n      jsonKey: 'test_joined_data',\n    }),\n    'testNumber': Attributes.Number({\n      modelKey: 'testNumber',\n      jsonKey: 'test_number',\n    }),\n    'testString': Attributes.String({\n      modelKey: 'testString',\n      jsonKey: 'test_string',\n    }),\n    'testArray': Attributes.Collection({\n      itemClass: SubSubmodel,\n      modelKey: 'testArray',\n      jsonKey: 'test_array',\n    }),\n  });\n}\n\ndescribe(\"Model\", function modelSpecs() {\n  describe(\"constructor\", () => {\n    it(\"should accept a hash of attributes and assign them to the new Model\", () => {\n      const attrs = {\n        id: \"A\",\n        testNumber: \"B\",\n      };\n      const m = new Submodel(attrs);\n      expect(m.id).toBe(attrs.id);\n      expect(m.testNumber).toBe(attrs.testNumber);\n    });\n\n    it(\"automatically assigns an id to the model if no id is provided\", () => {\n      const m = new Model();\n      expect(isTempId(m.id)).toBe(true);\n    });\n  });\n\n  describe(\"attributes\", () => {\n    it(\"should return the attributes of the class\", () => {\n      const m = new Model();\n      expect(m.attributes()).toEqual(m.constructor.attributes);\n    })\n\n    it(\"should guard against accidental modification\", () => {\n      const m = new Model();\n      Object.assign(m.attributes(), {other: 1});\n      expect(m.attributes()).toEqual(m.constructor.attributes);\n    })\n  });\n\n  describe(\"clone\", () =>\n    it(\"should return a deep copy of the object\", () => {\n      const old = new Submodel({testNumber: 4, testArray: [new SubSubmodel({value: 2}), new SubSubmodel({value: 6})]});\n      const clone = old.clone();\n\n      // Check entire trees are equivalent\n      expect(old.toJSON()).toEqual(clone.toJSON());\n      // Check object identity has changed\n      expect(old.constructor.name).toEqual(clone.constructor.name);\n      expect(old.testArray).not.toBe(clone.testArray);\n      // Check classes\n      expect(old.testArray[0]).not.toBe(clone.testArray[0]);\n      expect(old.testArray[0].constructor.name).toEqual(clone.testArray[0].constructor.name);\n    })\n\n  );\n\n  describe(\"fromJSON\", () => {\n    beforeEach(() => {\n      this.json = {\n        'id': '1234',\n        'test_number': 4,\n        'test_boolean': true,\n        'daysOld': 4,\n        'test_string': 'bla',\n      };\n      this.m = new Submodel();\n    });\n\n    it(\"should assign attribute values by calling through to attribute fromJSON functions\", () => {\n      spyOn(Submodel.attributes.testString, 'fromJSON').and.callFake(() => 'inflated value!');\n      this.m.fromJSON(this.json);\n      expect(Submodel.attributes.testString.fromJSON.calls.count()).toBe(1);\n      expect(this.m.testString).toBe('inflated value!');\n    });\n\n    it(\"should not touch attributes that are missing in the json\", () => {\n      this.m.fromJSON(this.json);\n      expect(this.m.object).toBe(undefined);\n\n      this.m.object = 'abc';\n      this.m.fromJSON(this.json);\n      expect(this.m.object).toBe('abc');\n    });\n\n    it(\"should not do anything with extra JSON keys\", () => {\n      this.m.fromJSON(this.json);\n      expect(this.m.daysOld).toBe(undefined);\n    });\n\n    it(\"should maintain empty string as empty strings\", () => {\n      expect(this.m.testString).toBe(undefined);\n      this.m.fromJSON({test_string: ''});\n      expect(this.m.testString).toBe('');\n    });\n\n    describe(\"Attributes.Number\", () =>\n      it(\"should read number attributes and coerce them to numeric values\", () => {\n        this.m.fromJSON({'test_number': 4});\n        expect(this.m.testNumber).toBe(4);\n\n        this.m.fromJSON({'test_number': '4'});\n        expect(this.m.testNumber).toBe(4);\n\n        this.m.fromJSON({'test_number': 'lolz'});\n        expect(this.m.testNumber).toBe(null);\n\n        this.m.fromJSON({'test_number': 0});\n        expect(this.m.testNumber).toBe(0);\n      })\n\n    );\n\n    describe(\"Attributes.JoinedData\", () =>\n      it(\"should read joined data attributes and coerce them to string values\", () => {\n        this.m.fromJSON({'test_joined_data': null});\n        expect(this.m.testJoinedData).toBe(null);\n\n        this.m.fromJSON({'test_joined_data': ''});\n        expect(this.m.testJoinedData).toBe('');\n\n        this.m.fromJSON({'test_joined_data': 'lolz'});\n        expect(this.m.testJoinedData).toBe('lolz');\n      })\n\n    );\n\n    describe(\"Attributes.Collection\", () => {\n      it(\"should parse and inflate items\", () => {\n        this.m.fromJSON({'test_collection': [{id: '123'}]});\n        expect(this.m.testCollection.length).toBe(1);\n        expect(this.m.testCollection[0].id).toBe('123');\n        expect(this.m.testCollection[0].constructor.name).toBe('SubmodelItem');\n      });\n\n      it(\"should be fine with malformed arrays\", () => {\n        this.m.fromJSON({'test_collection': [null]});\n        expect(this.m.testCollection.length).toBe(0);\n        this.m.fromJSON({'test_collection': []});\n        expect(this.m.testCollection.length).toBe(0);\n        this.m.fromJSON({'test_collection': null});\n        expect(this.m.testCollection.length).toBe(0);\n      });\n    });\n\n    describe(\"Attributes.Boolean\", () =>\n      it(\"should read `true` or true and coerce everything else to false\", () => {\n        this.m.fromJSON({'test_boolean': true});\n        expect(this.m.testBoolean).toBe(true);\n\n        this.m.fromJSON({'test_boolean': 'true'});\n        expect(this.m.testBoolean).toBe(true);\n\n        this.m.fromJSON({'test_boolean': 4});\n        expect(this.m.testBoolean).toBe(false);\n\n        this.m.fromJSON({'test_boolean': '4'});\n        expect(this.m.testBoolean).toBe(false);\n\n        this.m.fromJSON({'test_boolean': false});\n        expect(this.m.testBoolean).toBe(false);\n\n        this.m.fromJSON({'test_boolean': 0});\n        expect(this.m.testBoolean).toBe(false);\n\n        this.m.fromJSON({'test_boolean': null});\n        expect(this.m.testBoolean).toBe(false);\n      })\n\n    );\n  });\n\n  describe(\"toJSON\", () => {\n    beforeEach(() => {\n      this.model = new Submodel({\n        id: \"1234\",\n        testString: \"ACD\",\n      });\n      return;\n    });\n\n    it(\"should return a JSON object and call attribute toJSON functions to map values\", () => {\n      spyOn(Submodel.attributes.testString, 'toJSON').and.callFake(() => 'inflated value!');\n\n      const json = this.model.toJSON();\n      expect(json instanceof Object).toBe(true);\n      expect(json.id).toBe('1234');\n      expect(json.test_string).toBe('inflated value!');\n    });\n\n    it(\"should surface any exception one of the attribute toJSON functions raises\", () => {\n      spyOn(Submodel.attributes.testString, 'toJSON').and.callFake(() => {\n        throw new Error(\"Can't convert value into JSON format\");\n      });\n      expect(() => { this.model.toJSON(); }).toThrow();\n    });\n  });\n\n  describe(\"matches\", () => {\n    beforeEach(() => {\n      this.model = new Model({\n        id: \"1234\",\n        testString: \"ACD\",\n      });\n\n      this.truthyMatcher = {evaluate() { return true; }};\n      this.falsyMatcher = {evaluate() { return false; }};\n    });\n\n    it(\"should run the matchers and return true iff all matchers pass\", () => {\n      expect(this.model.matches([this.truthyMatcher, this.truthyMatcher])).toBe(true);\n      expect(this.model.matches([this.truthyMatcher, this.falsyMatcher])).toBe(false);\n      expect(this.model.matches([this.falsyMatcher, this.truthyMatcher])).toBe(false);\n    });\n\n    it(\"should pass itself as an argument to the matchers\", () => {\n      spyOn(this.truthyMatcher, 'evaluate').and.callFake(param => {\n        expect(param).toBe(this.model);\n      });\n      this.model.matches([this.truthyMatcher]);\n    });\n  });\n});\n"
  },
  {
    "__docId__": 576,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe78",
    "testId": 78,
    "memberof": "spec/model-spec.js",
    "testDepth": 0,
    "longname": "spec/model-spec.js~describe78",
    "access": null,
    "description": "Model",
    "lineNumber": 48
  },
  {
    "__docId__": 577,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe79",
    "testId": 79,
    "memberof": "spec/model-spec.js~describe78",
    "testDepth": 1,
    "longname": "spec/model-spec.js~describe78.describe79",
    "access": null,
    "description": "constructor",
    "lineNumber": 49
  },
  {
    "__docId__": 578,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it80",
    "testId": 80,
    "memberof": "spec/model-spec.js~describe78.describe79",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe79.it80",
    "access": null,
    "description": "should accept a hash of attributes and assign them to the new Model",
    "lineNumber": 50
  },
  {
    "__docId__": 579,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it81",
    "testId": 81,
    "memberof": "spec/model-spec.js~describe78.describe79",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe79.it81",
    "access": null,
    "description": "automatically assigns an id to the model if no id is provided",
    "lineNumber": 60
  },
  {
    "__docId__": 580,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe82",
    "testId": 82,
    "memberof": "spec/model-spec.js~describe78",
    "testDepth": 1,
    "longname": "spec/model-spec.js~describe78.describe82",
    "access": null,
    "description": "attributes",
    "lineNumber": 66
  },
  {
    "__docId__": 581,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it83",
    "testId": 83,
    "memberof": "spec/model-spec.js~describe78.describe82",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe82.it83",
    "access": null,
    "description": "should return the attributes of the class",
    "lineNumber": 67
  },
  {
    "__docId__": 582,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it84",
    "testId": 84,
    "memberof": "spec/model-spec.js~describe78.describe82",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe82.it84",
    "access": null,
    "description": "should guard against accidental modification",
    "lineNumber": 72
  },
  {
    "__docId__": 583,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe85",
    "testId": 85,
    "memberof": "spec/model-spec.js~describe78",
    "testDepth": 1,
    "longname": "spec/model-spec.js~describe78.describe85",
    "access": null,
    "description": "clone",
    "lineNumber": 79
  },
  {
    "__docId__": 584,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe86",
    "testId": 86,
    "memberof": "spec/model-spec.js~describe78",
    "testDepth": 1,
    "longname": "spec/model-spec.js~describe78.describe86",
    "access": null,
    "description": "fromJSON",
    "lineNumber": 96
  },
  {
    "__docId__": 585,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it87",
    "testId": 87,
    "memberof": "spec/model-spec.js~describe78.describe86",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe86.it87",
    "access": null,
    "description": "should assign attribute values by calling through to attribute fromJSON functions",
    "lineNumber": 108
  },
  {
    "__docId__": 586,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it88",
    "testId": 88,
    "memberof": "spec/model-spec.js~describe78.describe86",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe86.it88",
    "access": null,
    "description": "should not touch attributes that are missing in the json",
    "lineNumber": 115
  },
  {
    "__docId__": 587,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it89",
    "testId": 89,
    "memberof": "spec/model-spec.js~describe78.describe86",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe86.it89",
    "access": null,
    "description": "should not do anything with extra JSON keys",
    "lineNumber": 124
  },
  {
    "__docId__": 588,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it90",
    "testId": 90,
    "memberof": "spec/model-spec.js~describe78.describe86",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe86.it90",
    "access": null,
    "description": "should maintain empty string as empty strings",
    "lineNumber": 129
  },
  {
    "__docId__": 589,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe91",
    "testId": 91,
    "memberof": "spec/model-spec.js~describe78.describe86",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe86.describe91",
    "access": null,
    "description": "Attributes.Number",
    "lineNumber": 135
  },
  {
    "__docId__": 590,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe92",
    "testId": 92,
    "memberof": "spec/model-spec.js~describe78.describe86",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe86.describe92",
    "access": null,
    "description": "Attributes.JoinedData",
    "lineNumber": 152
  },
  {
    "__docId__": 591,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe93",
    "testId": 93,
    "memberof": "spec/model-spec.js~describe78.describe86",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe86.describe93",
    "access": null,
    "description": "Attributes.Collection",
    "lineNumber": 166
  },
  {
    "__docId__": 592,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it94",
    "testId": 94,
    "memberof": "spec/model-spec.js~describe78.describe86.describe93",
    "testDepth": 3,
    "longname": "spec/model-spec.js~describe78.describe86.describe93.it94",
    "access": null,
    "description": "should parse and inflate items",
    "lineNumber": 167
  },
  {
    "__docId__": 593,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it95",
    "testId": 95,
    "memberof": "spec/model-spec.js~describe78.describe86.describe93",
    "testDepth": 3,
    "longname": "spec/model-spec.js~describe78.describe86.describe93.it95",
    "access": null,
    "description": "should be fine with malformed arrays",
    "lineNumber": 174
  },
  {
    "__docId__": 594,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe96",
    "testId": 96,
    "memberof": "spec/model-spec.js~describe78.describe86",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe86.describe96",
    "access": null,
    "description": "Attributes.Boolean",
    "lineNumber": 184
  },
  {
    "__docId__": 595,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe97",
    "testId": 97,
    "memberof": "spec/model-spec.js~describe78",
    "testDepth": 1,
    "longname": "spec/model-spec.js~describe78.describe97",
    "access": null,
    "description": "toJSON",
    "lineNumber": 211
  },
  {
    "__docId__": 596,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it98",
    "testId": 98,
    "memberof": "spec/model-spec.js~describe78.describe97",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe97.it98",
    "access": null,
    "description": "should return a JSON object and call attribute toJSON functions to map values",
    "lineNumber": 220
  },
  {
    "__docId__": 597,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it99",
    "testId": 99,
    "memberof": "spec/model-spec.js~describe78.describe97",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe97.it99",
    "access": null,
    "description": "should surface any exception one of the attribute toJSON functions raises",
    "lineNumber": 229
  },
  {
    "__docId__": 598,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe100",
    "testId": 100,
    "memberof": "spec/model-spec.js~describe78",
    "testDepth": 1,
    "longname": "spec/model-spec.js~describe78.describe100",
    "access": null,
    "description": "matches",
    "lineNumber": 237
  },
  {
    "__docId__": 599,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it101",
    "testId": 101,
    "memberof": "spec/model-spec.js~describe78.describe100",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe100.it101",
    "access": null,
    "description": "should run the matchers and return true iff all matchers pass",
    "lineNumber": 248
  },
  {
    "__docId__": 600,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it102",
    "testId": 102,
    "memberof": "spec/model-spec.js~describe78.describe100",
    "testDepth": 2,
    "longname": "spec/model-spec.js~describe78.describe100.it102",
    "access": null,
    "description": "should pass itself as an argument to the matchers",
    "lineNumber": 254
  },
  {
    "__docId__": 601,
    "kind": "testFile",
    "static": true,
    "variation": null,
    "name": "spec/mutable-query-result-set-spec.js",
    "memberof": null,
    "longname": "spec/mutable-query-result-set-spec.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint quote-props: 0 */\nimport MutableQueryResultSet from '../lib/mutable-query-result-set';\nimport QueryRange from '../lib/query-range';\n\ndescribe(\"MutableQueryResultSet\", function MutableQueryResultSetSpecs() {\n  describe(\"clipToRange\", () => {\n    it(\"should do nothing if the clipping range is infinite\", () => {\n      const set = new MutableQueryResultSet({_ids: ['A', 'B', 'C', 'D', 'E'], _offset: 5});\n      const beforeRange = set.range();\n      set.clipToRange(QueryRange.infinite());\n      const afterRange = set.range();\n\n      expect(beforeRange.isEqual(afterRange)).toBe(true);\n    });\n\n    it(\"should correctly trim the result set 5-10 to the clipping range 2-9\", () => {\n      const set = new MutableQueryResultSet({_ids: ['A', 'B', 'C', 'D', 'E'], _offset: 5});\n      expect(set.range().isEqual(new QueryRange({offset: 5, limit: 5}))).toBe(true);\n      set.clipToRange(new QueryRange({offset: 2, limit: 7}));\n      expect(set.range().isEqual(new QueryRange({offset: 5, limit: 4}))).toBe(true);\n      expect(set.ids()).toEqual(['A', 'B', 'C', 'D']);\n    });\n\n    it(\"should correctly trim the result set 5-10 to the clipping range 5-10\", () => {\n      const set = new MutableQueryResultSet({_ids: ['A', 'B', 'C', 'D', 'E'], _offset: 5});\n      set.clipToRange(new QueryRange({start: 5, end: 10}));\n      expect(set.range().isEqual(new QueryRange({start: 5, end: 10}))).toBe(true);\n      expect(set.ids()).toEqual(['A', 'B', 'C', 'D', 'E']);\n    });\n\n    it(\"should correctly trim the result set 5-10 to the clipping range 6\", () => {\n      const set = new MutableQueryResultSet({_ids: ['A', 'B', 'C', 'D', 'E'], _offset: 5});\n      set.clipToRange(new QueryRange({offset: 6, limit: 1}));\n      expect(set.range().isEqual(new QueryRange({offset: 6, limit: 1}))).toBe(true);\n      expect(set.ids()).toEqual(['B']);\n    });\n\n    it(\"should correctly trim the result set 5-10 to the clipping range 100-200\", () => {\n      const set = new MutableQueryResultSet({_ids: ['A', 'B', 'C', 'D', 'E'], _offset: 5});\n      set.clipToRange(new QueryRange({start: 100, end: 200}));\n      expect(set.range().isEqual(new QueryRange({start: 100, end: 100}))).toBe(true);\n      expect(set.ids()).toEqual([]);\n    });\n\n    it(\"should correctly trim the result set 5-10 to the clipping range 0-2\", () => {\n      const set = new MutableQueryResultSet({_ids: ['A', 'B', 'C', 'D', 'E'], _offset: 5});\n      set.clipToRange(new QueryRange({offset: 0, limit: 2}));\n      expect(set.range().isEqual(new QueryRange({offset: 5, limit: 0}))).toBe(true);\n      expect(set.ids()).toEqual([]);\n    });\n\n    it(\"should trim the models cache to remove models no longer needed\", () => {\n      const set = new MutableQueryResultSet({\n        _ids: ['A', 'B', 'C', 'D', 'E'],\n        _offset: 5,\n        _modelsHash: {\n          'A': {id: 'A'},\n          'B': {id: 'B'},\n          'C': {id: 'C'},\n          'D': {id: 'D'},\n          'E': {id: 'E'},\n        }});\n\n      set.clipToRange(new QueryRange({start: 5, end: 8}));\n      expect(set._modelsHash).toEqual({\n        'A': {id: 'A'},\n        'B': {id: 'B'},\n        'C': {id: 'C'},\n      });\n    });\n  });\n\n  describe(\"addIdsInRange\", () => {\n    describe(\"when the set is currently empty\", () =>\n      it(\"should set the result set to the provided one\", () => {\n        this.set = new MutableQueryResultSet();\n        this.set.addIdsInRange(['B', 'C', 'D'], new QueryRange({start: 1, end: 4}));\n        expect(this.set.ids()).toEqual(['B', 'C', 'D']);\n        expect(this.set.range().isEqual(new QueryRange({start: 1, end: 4}))).toBe(true);\n      })\n\n    );\n\n    describe(\"when the set has existing values\", () => {\n      beforeEach(() => {\n        this.set = new MutableQueryResultSet({\n          _ids: ['A', 'B', 'C', 'D', 'E'],\n          _offset: 5,\n          _modelsHash: {'A': {id: 'A'}, 'B': {id: 'B'}, 'C': {id: 'C'}, 'D': {id: 'D'}, 'E': {id: 'E'}},\n        });\n      });\n\n      it(\"should throw an exception if the range provided doesn't intersect (trailing)\", () => {\n        expect(() => {\n          this.set.addIdsInRange(['G', 'H', 'I'], new QueryRange({offset: 11, limit: 3}));\n        }).toThrow();\n\n        expect(() => {\n          this.set.addIdsInRange(['F', 'G', 'H'], new QueryRange({offset: 10, limit: 3}));\n        }).not.toThrow();\n      });\n\n      it(\"should throw an exception if the range provided doesn't intersect (leading)\", () => {\n        expect(() => {\n          this.set.addIdsInRange(['0', '1', '2'], new QueryRange({offset: 1, limit: 3}));\n        }).toThrow();\n\n        expect(() => {\n          this.set.addIdsInRange(['0', '1', '2'], new QueryRange({offset: 2, limit: 3}));\n        }).not.toThrow();\n      });\n\n      it(\"should work if the IDs array is shorter than the result range they represent (addition)\", () => {\n        this.set.addIdsInRange(['F', 'G', 'H'], new QueryRange({offset: 10, limit: 5}));\n        expect(this.set.ids()).toEqual(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']);\n      });\n\n      it(\"should work if the IDs array is shorter than the result range they represent (replacement)\", () => {\n        this.set.addIdsInRange(['A', 'B', 'C'], new QueryRange({offset: 5, limit: 5}));\n        expect(this.set.ids()).toEqual(['A', 'B', 'C']);\n      });\n\n      it(\"should correctly add ids (trailing) and update the offset\", () => {\n        this.set.addIdsInRange(['F', 'G', 'H'], new QueryRange({offset: 10, limit: 3}));\n        expect(this.set.ids()).toEqual(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']);\n        expect(this.set.range().offset).toEqual(5);\n      });\n\n      it(\"should correctly add ids (leading) and update the offset\", () => {\n        this.set.addIdsInRange(['0', '1', '2'], new QueryRange({offset: 2, limit: 3}));\n        expect(this.set.ids()).toEqual(['0', '1', '2', 'A', 'B', 'C', 'D', 'E']);\n        expect(this.set.range().offset).toEqual(2);\n      });\n\n      it(\"should correctly add ids (middle) and update the offset\", () => {\n        this.set.addIdsInRange(['B-new', 'C-new', 'D-new'], new QueryRange({offset: 6, limit: 3}));\n        expect(this.set.ids()).toEqual(['A', 'B-new', 'C-new', 'D-new', 'E']);\n        expect(this.set.range().offset).toEqual(5);\n      });\n\n      it(\"should correctly add ids (middle+trailing) and update the offset\", () => {\n        this.set.addIdsInRange(['D-new', 'E-new', 'F-new'], new QueryRange({offset: 8, limit: 3}));\n        expect(this.set.ids()).toEqual(['A', 'B', 'C', 'D-new', 'E-new', 'F-new']);\n        expect(this.set.range().offset).toEqual(5);\n      });\n    });\n  });\n});\n"
  },
  {
    "__docId__": 602,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe103",
    "testId": 103,
    "memberof": "spec/mutable-query-result-set-spec.js",
    "testDepth": 0,
    "longname": "spec/mutable-query-result-set-spec.js~describe103",
    "access": null,
    "description": "MutableQueryResultSet",
    "lineNumber": 5
  },
  {
    "__docId__": 603,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe104",
    "testId": 104,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103",
    "testDepth": 1,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe104",
    "access": null,
    "description": "clipToRange",
    "lineNumber": 6
  },
  {
    "__docId__": 604,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it105",
    "testId": 105,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe104",
    "testDepth": 2,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe104.it105",
    "access": null,
    "description": "should do nothing if the clipping range is infinite",
    "lineNumber": 7
  },
  {
    "__docId__": 605,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it106",
    "testId": 106,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe104",
    "testDepth": 2,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe104.it106",
    "access": null,
    "description": "should correctly trim the result set 5-10 to the clipping range 2-9",
    "lineNumber": 16
  },
  {
    "__docId__": 606,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it107",
    "testId": 107,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe104",
    "testDepth": 2,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe104.it107",
    "access": null,
    "description": "should correctly trim the result set 5-10 to the clipping range 5-10",
    "lineNumber": 24
  },
  {
    "__docId__": 607,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it108",
    "testId": 108,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe104",
    "testDepth": 2,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe104.it108",
    "access": null,
    "description": "should correctly trim the result set 5-10 to the clipping range 6",
    "lineNumber": 31
  },
  {
    "__docId__": 608,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it109",
    "testId": 109,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe104",
    "testDepth": 2,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe104.it109",
    "access": null,
    "description": "should correctly trim the result set 5-10 to the clipping range 100-200",
    "lineNumber": 38
  },
  {
    "__docId__": 609,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it110",
    "testId": 110,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe104",
    "testDepth": 2,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe104.it110",
    "access": null,
    "description": "should correctly trim the result set 5-10 to the clipping range 0-2",
    "lineNumber": 45
  },
  {
    "__docId__": 610,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it111",
    "testId": 111,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe104",
    "testDepth": 2,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe104.it111",
    "access": null,
    "description": "should trim the models cache to remove models no longer needed",
    "lineNumber": 52
  },
  {
    "__docId__": 611,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe112",
    "testId": 112,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103",
    "testDepth": 1,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe112",
    "access": null,
    "description": "addIdsInRange",
    "lineNumber": 73
  },
  {
    "__docId__": 612,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe113",
    "testId": 113,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe112",
    "testDepth": 2,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe113",
    "access": null,
    "description": "when the set is currently empty",
    "lineNumber": 74
  },
  {
    "__docId__": 613,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe114",
    "testId": 114,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe112",
    "testDepth": 2,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114",
    "access": null,
    "description": "when the set has existing values",
    "lineNumber": 84
  },
  {
    "__docId__": 614,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it115",
    "testId": 115,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114",
    "testDepth": 3,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114.it115",
    "access": null,
    "description": "should throw an exception if the range provided doesn't intersect (trailing)",
    "lineNumber": 93
  },
  {
    "__docId__": 615,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it116",
    "testId": 116,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114",
    "testDepth": 3,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114.it116",
    "access": null,
    "description": "should throw an exception if the range provided doesn't intersect (leading)",
    "lineNumber": 103
  },
  {
    "__docId__": 616,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it117",
    "testId": 117,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114",
    "testDepth": 3,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114.it117",
    "access": null,
    "description": "should work if the IDs array is shorter than the result range they represent (addition)",
    "lineNumber": 113
  },
  {
    "__docId__": 617,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it118",
    "testId": 118,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114",
    "testDepth": 3,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114.it118",
    "access": null,
    "description": "should work if the IDs array is shorter than the result range they represent (replacement)",
    "lineNumber": 118
  },
  {
    "__docId__": 618,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it119",
    "testId": 119,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114",
    "testDepth": 3,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114.it119",
    "access": null,
    "description": "should correctly add ids (trailing) and update the offset",
    "lineNumber": 123
  },
  {
    "__docId__": 619,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it120",
    "testId": 120,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114",
    "testDepth": 3,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114.it120",
    "access": null,
    "description": "should correctly add ids (leading) and update the offset",
    "lineNumber": 129
  },
  {
    "__docId__": 620,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it121",
    "testId": 121,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114",
    "testDepth": 3,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114.it121",
    "access": null,
    "description": "should correctly add ids (middle) and update the offset",
    "lineNumber": 135
  },
  {
    "__docId__": 621,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it122",
    "testId": 122,
    "memberof": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114",
    "testDepth": 3,
    "longname": "spec/mutable-query-result-set-spec.js~describe103.describe112.describe114.it122",
    "access": null,
    "description": "should correctly add ids (middle+trailing) and update the offset",
    "lineNumber": 141
  },
  {
    "__docId__": 622,
    "kind": "testFile",
    "static": true,
    "variation": null,
    "name": "spec/query-range-spec.js",
    "memberof": null,
    "longname": "spec/query-range-spec.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import QueryRange from '../lib/query-range';\n\ndescribe(\"QueryRange\", function QueryRangeSpecs() {\n  describe(\"@infinite\", () =>\n    it(\"should return a query range with a null limit and offset\", () => {\n      const infinite = QueryRange.infinite();\n      expect(infinite.limit).toBe(null);\n      expect(infinite.offset).toBe(null);\n    })\n\n  );\n\n  describe(\"@rangesBySubtracting\", () => {\n    it(\"should throw an exception if either range is infinite\", () => {\n      const infinite = QueryRange.infinite();\n\n      expect(() =>\n        QueryRange.rangesBySubtracting(infinite, new QueryRange({offset: 0, limit: 10}))\n      ).toThrow();\n\n      expect(() =>\n        QueryRange.rangesBySubtracting(new QueryRange({offset: 0, limit: 10}), infinite)\n      ).toThrow();\n    });\n\n    it(\"should return one or more ranges created by punching the provided range\", () => {\n      const test = ({a, b, result}) => expect(QueryRange.rangesBySubtracting(a, b)).toEqual(result);\n      test({\n        a: new QueryRange({offset: 0, limit: 10}),\n        b: new QueryRange({offset: 3, limit: 3}),\n        result: [new QueryRange({offset: 0, limit: 3}), new QueryRange({offset: 6, limit: 4})]});\n\n      test({\n        a: new QueryRange({offset: 0, limit: 10}),\n        b: new QueryRange({offset: 3, limit: 10}),\n        result: [new QueryRange({offset: 0, limit: 3})]});\n\n      test({\n        a: new QueryRange({offset: 0, limit: 10}),\n        b: new QueryRange({offset: 0, limit: 10}),\n        result: []});\n\n      test({\n        a: new QueryRange({offset: 5, limit: 10}),\n        b: new QueryRange({offset: 0, limit: 4}),\n        result: [new QueryRange({offset: 5, limit: 10})]});\n\n      test({\n        a: new QueryRange({offset: 5, limit: 10}),\n        b: new QueryRange({offset: 0, limit: 8}),\n        result: [new QueryRange({offset: 8, limit: 7})]});\n    });\n  });\n\n  describe(\"isInfinite\", () =>\n    it(\"should return true for an infinite range, false otherwise\", () => {\n      const infinite = QueryRange.infinite();\n      expect(infinite.isInfinite()).toBe(true);\n      expect(new QueryRange({offset: 0, limit: 4}).isInfinite()).toBe(false);\n    })\n  );\n\n  describe(\"start\", () =>\n    it(\"should be an alias for offset\", () =>\n      expect((new QueryRange({offset: 3, limit: 4})).start).toBe(3)\n    )\n  );\n\n  describe(\"end\", () =>\n    it(\"should be offset + limit\", () =>\n      expect((new QueryRange({offset: 3, limit: 4})).end).toBe(7)\n    )\n  );\n\n  describe(\"isContiguousWith\", () => {\n    it(\"should return true if either range is infinite\", () => {\n      const a = new QueryRange({offset: 3, limit: 4});\n      expect(a.isContiguousWith(QueryRange.infinite())).toBe(true);\n      expect(QueryRange.infinite().isContiguousWith(a)).toBe(true);\n    });\n\n    it(\"should return true if the ranges intersect or touch, false otherwise\", () => {\n      const a = new QueryRange({offset: 3, limit: 4});\n      const b = new QueryRange({offset: 0, limit: 2});\n      const c = new QueryRange({offset: 0, limit: 3});\n      const d = new QueryRange({offset: 7, limit: 10});\n      const e = new QueryRange({offset: 8, limit: 10});\n\n      // True\n\n      expect(a.isContiguousWith(d)).toBe(true);\n      expect(d.isContiguousWith(a)).toBe(true);\n\n      expect(a.isContiguousWith(c)).toBe(true);\n      expect(c.isContiguousWith(a)).toBe(true);\n\n      // False\n\n      expect(a.isContiguousWith(b)).toBe(false);\n      expect(b.isContiguousWith(a)).toBe(false);\n\n      expect(a.isContiguousWith(e)).toBe(false);\n      expect(e.isContiguousWith(a)).toBe(false);\n\n      expect(b.isContiguousWith(e)).toBe(false);\n      expect(e.isContiguousWith(b)).toBe(false);\n    });\n  });\n});\n"
  },
  {
    "__docId__": 623,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe123",
    "testId": 123,
    "memberof": "spec/query-range-spec.js",
    "testDepth": 0,
    "longname": "spec/query-range-spec.js~describe123",
    "access": null,
    "description": "QueryRange",
    "lineNumber": 3
  },
  {
    "__docId__": 624,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe124",
    "testId": 124,
    "memberof": "spec/query-range-spec.js~describe123",
    "testDepth": 1,
    "longname": "spec/query-range-spec.js~describe123.describe124",
    "access": null,
    "description": "@infinite",
    "lineNumber": 4
  },
  {
    "__docId__": 625,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe125",
    "testId": 125,
    "memberof": "spec/query-range-spec.js~describe123",
    "testDepth": 1,
    "longname": "spec/query-range-spec.js~describe123.describe125",
    "access": null,
    "description": "@rangesBySubtracting",
    "lineNumber": 13
  },
  {
    "__docId__": 626,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it126",
    "testId": 126,
    "memberof": "spec/query-range-spec.js~describe123.describe125",
    "testDepth": 2,
    "longname": "spec/query-range-spec.js~describe123.describe125.it126",
    "access": null,
    "description": "should throw an exception if either range is infinite",
    "lineNumber": 14
  },
  {
    "__docId__": 627,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it127",
    "testId": 127,
    "memberof": "spec/query-range-spec.js~describe123.describe125",
    "testDepth": 2,
    "longname": "spec/query-range-spec.js~describe123.describe125.it127",
    "access": null,
    "description": "should return one or more ranges created by punching the provided range",
    "lineNumber": 26
  },
  {
    "__docId__": 628,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "test128",
    "testId": 128,
    "memberof": "spec/query-range-spec.js~describe123.describe125.it127",
    "testDepth": 3,
    "longname": "spec/query-range-spec.js~describe123.describe125.it127.test128",
    "access": null,
    "lineNumber": 28
  },
  {
    "__docId__": 629,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "test129",
    "testId": 129,
    "memberof": "spec/query-range-spec.js~describe123.describe125.it127",
    "testDepth": 3,
    "longname": "spec/query-range-spec.js~describe123.describe125.it127.test129",
    "access": null,
    "lineNumber": 33
  },
  {
    "__docId__": 630,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "test130",
    "testId": 130,
    "memberof": "spec/query-range-spec.js~describe123.describe125.it127",
    "testDepth": 3,
    "longname": "spec/query-range-spec.js~describe123.describe125.it127.test130",
    "access": null,
    "lineNumber": 38
  },
  {
    "__docId__": 631,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "test131",
    "testId": 131,
    "memberof": "spec/query-range-spec.js~describe123.describe125.it127",
    "testDepth": 3,
    "longname": "spec/query-range-spec.js~describe123.describe125.it127.test131",
    "access": null,
    "lineNumber": 43
  },
  {
    "__docId__": 632,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "test132",
    "testId": 132,
    "memberof": "spec/query-range-spec.js~describe123.describe125.it127",
    "testDepth": 3,
    "longname": "spec/query-range-spec.js~describe123.describe125.it127.test132",
    "access": null,
    "lineNumber": 48
  },
  {
    "__docId__": 633,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe133",
    "testId": 133,
    "memberof": "spec/query-range-spec.js~describe123",
    "testDepth": 1,
    "longname": "spec/query-range-spec.js~describe123.describe133",
    "access": null,
    "description": "isInfinite",
    "lineNumber": 55
  },
  {
    "__docId__": 634,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe134",
    "testId": 134,
    "memberof": "spec/query-range-spec.js~describe123",
    "testDepth": 1,
    "longname": "spec/query-range-spec.js~describe123.describe134",
    "access": null,
    "description": "start",
    "lineNumber": 63
  },
  {
    "__docId__": 635,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe135",
    "testId": 135,
    "memberof": "spec/query-range-spec.js~describe123",
    "testDepth": 1,
    "longname": "spec/query-range-spec.js~describe123.describe135",
    "access": null,
    "description": "end",
    "lineNumber": 69
  },
  {
    "__docId__": 636,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe136",
    "testId": 136,
    "memberof": "spec/query-range-spec.js~describe123",
    "testDepth": 1,
    "longname": "spec/query-range-spec.js~describe123.describe136",
    "access": null,
    "description": "isContiguousWith",
    "lineNumber": 75
  },
  {
    "__docId__": 637,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it137",
    "testId": 137,
    "memberof": "spec/query-range-spec.js~describe123.describe136",
    "testDepth": 2,
    "longname": "spec/query-range-spec.js~describe123.describe136.it137",
    "access": null,
    "description": "should return true if either range is infinite",
    "lineNumber": 76
  },
  {
    "__docId__": 638,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it138",
    "testId": 138,
    "memberof": "spec/query-range-spec.js~describe123.describe136",
    "testDepth": 2,
    "longname": "spec/query-range-spec.js~describe123.describe136.it138",
    "access": null,
    "description": "should return true if the ranges intersect or touch, false otherwise",
    "lineNumber": 82
  },
  {
    "__docId__": 639,
    "kind": "testFile",
    "static": true,
    "variation": null,
    "name": "spec/query-spec.js",
    "memberof": null,
    "longname": "spec/query-spec.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "/* eslint quote-props: 0 */\nimport Model from '../lib/model';\nimport ModelQuery from '../lib/query';\nimport Attributes from '../lib/attributes';\n\nimport Thread from './fixtures/thread';\nimport Message from './fixtures/message';\n\nexport default class Account extends Model {\n  static attributes = Object.assign({}, Model.attributes, {\n    name: Attributes.String({\n      modelKey: 'name',\n    }),\n\n    provider: Attributes.String({\n      modelKey: 'provider',\n    }),\n\n    emailAddress: Attributes.String({\n      queryable: true,\n      modelKey: 'emailAddress',\n      jsonKey: 'email_address',\n    }),\n\n    organizationUnit: Attributes.String({\n      modelKey: 'organizationUnit',\n      jsonKey: 'organization_unit',\n    }),\n\n    label: Attributes.String({\n      modelKey: 'label',\n    }),\n\n    aliases: Attributes.Object({\n      modelKey: 'aliases',\n    }),\n\n    defaultAlias: Attributes.Object({\n      modelKey: 'defaultAlias',\n      jsonKey: 'default_alias',\n    }),\n\n    syncState: Attributes.String({\n      modelKey: 'syncState',\n      jsonKey: 'sync_state',\n    }),\n  });\n}\n\ndescribe(\"ModelQuery\", function ModelQuerySpecs() {\n  beforeEach(() => {\n    this.db = {};\n  });\n\n  describe(\"where\", () => {\n    beforeEach(() => {\n      this.q = new ModelQuery(Thread, this.db);\n      this.m1 = Thread.attributes.id.equal(4);\n      this.m2 = Thread.attributes.categories.contains('category-id');\n    });\n\n    it(\"should accept an array of Matcher objects\", () => {\n      this.q.where([this.m1, this.m2]);\n      expect(this.q._matchers.length).toBe(2);\n      expect(this.q._matchers[0]).toBe(this.m1);\n      expect(this.q._matchers[1]).toBe(this.m2);\n    });\n\n    it(\"should accept a single Matcher object\", () => {\n      this.q.where(this.m1);\n      expect(this.q._matchers.length).toBe(1);\n      expect(this.q._matchers[0]).toBe(this.m1);\n    });\n\n    it(\"should append to any existing where clauses\", () => {\n      this.q.where(this.m1);\n      this.q.where(this.m2);\n      expect(this.q._matchers.length).toBe(2);\n      expect(this.q._matchers[0]).toBe(this.m1);\n      expect(this.q._matchers[1]).toBe(this.m2);\n    });\n\n    it(\"should accept a shorthand format\", () => {\n      this.q.where({id: 4, lastMessageReceivedTimestamp: 1234});\n      expect(this.q._matchers.length).toBe(2);\n      expect(this.q._matchers[0].attr.modelKey).toBe('id');\n      expect(this.q._matchers[0].comparator).toBe('=');\n      expect(this.q._matchers[0].val).toBe(4);\n    });\n\n    it(\"should return the query so it can be chained\", () => {\n      expect(this.q.where({id: 4})).toBe(this.q);\n    });\n\n    it(\"should immediately raise an exception if an un-queryable attribute is specified\", () =>\n      expect(() => {\n        this.q.where({snippet: 'My Snippet'});\n      }).toThrow()\n    );\n\n    it(\"should immediately raise an exception if a non-existent attribute is specified\", () =>\n      expect(() => {\n        this.q.where({looksLikeADuck: 'of course'});\n      }).toThrow()\n    );\n  });\n\n  describe(\"order\", () => {\n    beforeEach(() => {\n      this.q = new ModelQuery(Thread, this.db);\n      this.o1 = Thread.attributes.lastMessageReceivedTimestamp.descending();\n      this.o2 = Thread.attributes.subject.descending();\n    });\n\n    it(\"should accept an array of SortOrders\", () => {\n      this.q.order([this.o1, this.o2]);\n      expect(this.q._orders.length).toBe(2);\n    });\n\n    it(\"should accept a single SortOrder object\", () => {\n      this.q.order(this.o2);\n      expect(this.q._orders.length).toBe(1);\n    });\n\n    it(\"should extend any existing ordering\", () => {\n      this.q.order(this.o1);\n      this.q.order(this.o2);\n      expect(this.q._orders.length).toBe(2);\n      expect(this.q._orders[0]).toBe(this.o1);\n      expect(this.q._orders[1]).toBe(this.o2);\n    });\n\n    it(\"should return the query so it can be chained\", () => {\n      expect(this.q.order(this.o2)).toBe(this.q);\n    });\n  });\n\n  describe(\"include\", () => {\n    beforeEach(() => {\n      this.q = new ModelQuery(Message, this.db);\n    });\n\n    it(\"should throw an exception if the attribute is not a joined data attribute\", () =>\n      expect(() => {\n        this.q.include(Message.attributes.unread);\n      }).toThrow()\n\n    );\n\n    it(\"should add the provided property to the list of joined properties\", () => {\n      expect(this.q._includeJoinedData).toEqual([]);\n      this.q.include(Message.attributes.body);\n      expect(this.q._includeJoinedData).toEqual([Message.attributes.body]);\n    });\n  });\n\n  describe(\"includeAll\", () => {\n    beforeEach(() => {\n      this.q = new ModelQuery(Message, this.db);\n    });\n\n    it(\"should add all the JoinedData attributes of the class\", () => {\n      expect(this.q._includeJoinedData).toEqual([]);\n      this.q.includeAll();\n      expect(this.q._includeJoinedData).toEqual([Message.attributes.body]);\n    });\n  });\n\n  describe(\"response formatting\", () =>\n    it(\"should always return a Number for counts\", () => {\n      const q = new ModelQuery(Message, this.db);\n      q.where({accountId: 'abcd'}).count();\n\n      const raw = [{count: \"12\"}];\n      expect(q.formatResult(q.inflateResult(raw))).toBe(12);\n    })\n\n  );\n\n  describe(\"sql\", () => {\n    beforeEach(() => {\n      this.runScenario = (klass, scenario) => {\n        const q = new ModelQuery(klass, this.db);\n        Attributes.Matcher.muid = 1;\n        scenario.builder(q);\n        expect(q.sql().trim()).toBe(scenario.sql.trim());\n      };\n    });\n\n    it(\"should finalize the query so no further changes can be made\", () => {\n      const q = new ModelQuery(Account, this.db);\n      spyOn(q, 'finalize');\n      q.sql();\n      expect(q.finalize).toHaveBeenCalled();\n    });\n\n    it(\"should correctly generate queries with multiple where clauses\", () => {\n      this.runScenario(Account, {\n        builder: (q) =>\n          q.where({emailAddress: 'ben@nylas.com'}).where({id: 2}),\n        sql: \"SELECT `Account`.`data` FROM `Account`  \" +\n             \"WHERE `Account`.`email_address` = 'ben@nylas.com' AND `Account`.`id` = 2\",\n      });\n    });\n\n    it(\"should correctly escape single quotes with more double single quotes (LIKE)\", () => {\n      this.runScenario(Account, {\n        builder: (q) =>\n          q.where(Account.attributes.emailAddress.like(\"you're\")),\n        sql: \"SELECT `Account`.`data` FROM `Account`  WHERE `Account`.`email_address` like '%you''re%'\",\n      });\n    });\n\n    it(\"should correctly escape single quotes with more double single quotes (equal)\", () => {\n      this.runScenario(Account, {\n        builder: (q) =>\n          q.where(Account.attributes.emailAddress.equal(\"you're\")),\n        sql: \"SELECT `Account`.`data` FROM `Account`  WHERE `Account`.`email_address` = 'you''re'\",\n      });\n    });\n\n    it(\"should correctly generate COUNT queries\", () => {\n      this.runScenario(Thread, {\n        builder: (q) =>\n          q.where({accountId: 'abcd'}).count(),\n        sql: \"SELECT COUNT(*) as count FROM `Thread`  \" +\n             \"WHERE `Thread`.`account_id` = 'abcd'  \",\n      });\n    });\n\n    it(\"should correctly generate LIMIT 1 queries for single items\", () => {\n      this.runScenario(Thread, {\n        builder: (q) =>\n          q.where({accountId: 'abcd'}).one(),\n        sql: \"SELECT `Thread`.`data` FROM `Thread`  \" +\n             \"WHERE `Thread`.`account_id` = 'abcd'  \" +\n             \"ORDER BY `Thread`.`last_message_received_timestamp` DESC LIMIT 1\",\n      });\n    });\n\n    it(\"should correctly generate `contains` queries using JOINS\", () => {\n      this.runScenario(Thread, {\n        builder: (q) =>\n          q.where(Thread.attributes.categories.contains('category-id')).where({id: '1234'}),\n        sql: \"SELECT `Thread`.`data` FROM `Thread` \" +\n             \"INNER JOIN `ThreadCategory` AS `M1` ON `M1`.`id` = `Thread`.`id` \" +\n             \"WHERE `M1`.`value` = 'category-id' AND `Thread`.`id` = '1234'  \" +\n             \"ORDER BY `Thread`.`last_message_received_timestamp` DESC\",\n      });\n\n      this.runScenario(Thread, {\n        builder: (q) =>\n          q.where([Thread.attributes.categories.contains('l-1'), Thread.attributes.categories.contains('l-2')]),\n        sql: \"SELECT `Thread`.`data` FROM `Thread` \" +\n             \"INNER JOIN `ThreadCategory` AS `M1` ON `M1`.`id` = `Thread`.`id` \" +\n             \"INNER JOIN `ThreadCategory` AS `M2` ON `M2`.`id` = `Thread`.`id` \" +\n             \"WHERE `M1`.`value` = 'l-1' AND `M2`.`value` = 'l-2'  \" +\n             \"ORDER BY `Thread`.`last_message_received_timestamp` DESC\",\n      });\n    });\n\n    it(\"should correctly generate queries with the class's naturalSortOrder when one is available and no other orders are provided\", () => {\n      this.runScenario(Thread, {\n        builder: (q) =>\n          q.where({accountId: 'abcd'}),\n        sql: \"SELECT `Thread`.`data` FROM `Thread`  \" +\n             \"WHERE `Thread`.`account_id` = 'abcd'  \" +\n             \"ORDER BY `Thread`.`last_message_received_timestamp` DESC\",\n      });\n\n      this.runScenario(Thread, {\n        builder: (q) =>\n          q.where({accountId: 'abcd'}).order(Thread.attributes.lastMessageReceivedTimestamp.ascending()),\n        sql: \"SELECT `Thread`.`data` FROM `Thread`  \" +\n             \"WHERE `Thread`.`account_id` = 'abcd'  \" +\n             \"ORDER BY `Thread`.`last_message_received_timestamp` ASC\",\n      });\n\n      this.runScenario(Account, {\n        builder: (q) =>\n          q.where({id: 'abcd'}),\n        sql: \"SELECT `Account`.`data` FROM `Account`  \" +\n             \"WHERE `Account`.`id` = 'abcd'  \",\n      });\n    });\n\n    it(\"should correctly generate queries requesting joined data attributes\", () => {\n      this.runScenario(Message, {\n        builder: (q) =>\n          q.where({id: '1234'}).include(Message.attributes.body),\n        sql: \"SELECT `Message`.`data`, IFNULL(`MessageBody`.`value`, '!NULLVALUE!') AS `body`  \" +\n             \"FROM `Message` LEFT OUTER JOIN `MessageBody` ON `MessageBody`.`id` = `Message`.`id` \" +\n             \"WHERE `Message`.`id` = '1234'\",\n      });\n    });\n  });\n});\n"
  },
  {
    "__docId__": 640,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe139",
    "testId": 139,
    "memberof": "spec/query-spec.js",
    "testDepth": 0,
    "longname": "spec/query-spec.js~describe139",
    "access": null,
    "description": "ModelQuery",
    "lineNumber": 50
  },
  {
    "__docId__": 641,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe140",
    "testId": 140,
    "memberof": "spec/query-spec.js~describe139",
    "testDepth": 1,
    "longname": "spec/query-spec.js~describe139.describe140",
    "access": null,
    "description": "where",
    "lineNumber": 55
  },
  {
    "__docId__": 642,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it141",
    "testId": 141,
    "memberof": "spec/query-spec.js~describe139.describe140",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe140.it141",
    "access": null,
    "description": "should accept an array of Matcher objects",
    "lineNumber": 62
  },
  {
    "__docId__": 643,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it142",
    "testId": 142,
    "memberof": "spec/query-spec.js~describe139.describe140",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe140.it142",
    "access": null,
    "description": "should accept a single Matcher object",
    "lineNumber": 69
  },
  {
    "__docId__": 644,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it143",
    "testId": 143,
    "memberof": "spec/query-spec.js~describe139.describe140",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe140.it143",
    "access": null,
    "description": "should append to any existing where clauses",
    "lineNumber": 75
  },
  {
    "__docId__": 645,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it144",
    "testId": 144,
    "memberof": "spec/query-spec.js~describe139.describe140",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe140.it144",
    "access": null,
    "description": "should accept a shorthand format",
    "lineNumber": 83
  },
  {
    "__docId__": 646,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it145",
    "testId": 145,
    "memberof": "spec/query-spec.js~describe139.describe140",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe140.it145",
    "access": null,
    "description": "should return the query so it can be chained",
    "lineNumber": 91
  },
  {
    "__docId__": 647,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it146",
    "testId": 146,
    "memberof": "spec/query-spec.js~describe139.describe140",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe140.it146",
    "access": null,
    "description": "should immediately raise an exception if an un-queryable attribute is specified",
    "lineNumber": 95
  },
  {
    "__docId__": 648,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it147",
    "testId": 147,
    "memberof": "spec/query-spec.js~describe139.describe140",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe140.it147",
    "access": null,
    "description": "should immediately raise an exception if a non-existent attribute is specified",
    "lineNumber": 101
  },
  {
    "__docId__": 649,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe148",
    "testId": 148,
    "memberof": "spec/query-spec.js~describe139",
    "testDepth": 1,
    "longname": "spec/query-spec.js~describe139.describe148",
    "access": null,
    "description": "order",
    "lineNumber": 108
  },
  {
    "__docId__": 650,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it149",
    "testId": 149,
    "memberof": "spec/query-spec.js~describe139.describe148",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe148.it149",
    "access": null,
    "description": "should accept an array of SortOrders",
    "lineNumber": 115
  },
  {
    "__docId__": 651,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it150",
    "testId": 150,
    "memberof": "spec/query-spec.js~describe139.describe148",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe148.it150",
    "access": null,
    "description": "should accept a single SortOrder object",
    "lineNumber": 120
  },
  {
    "__docId__": 652,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it151",
    "testId": 151,
    "memberof": "spec/query-spec.js~describe139.describe148",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe148.it151",
    "access": null,
    "description": "should extend any existing ordering",
    "lineNumber": 125
  },
  {
    "__docId__": 653,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it152",
    "testId": 152,
    "memberof": "spec/query-spec.js~describe139.describe148",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe148.it152",
    "access": null,
    "description": "should return the query so it can be chained",
    "lineNumber": 133
  },
  {
    "__docId__": 654,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe153",
    "testId": 153,
    "memberof": "spec/query-spec.js~describe139",
    "testDepth": 1,
    "longname": "spec/query-spec.js~describe139.describe153",
    "access": null,
    "description": "include",
    "lineNumber": 138
  },
  {
    "__docId__": 655,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it154",
    "testId": 154,
    "memberof": "spec/query-spec.js~describe139.describe153",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe153.it154",
    "access": null,
    "description": "should throw an exception if the attribute is not a joined data attribute",
    "lineNumber": 143
  },
  {
    "__docId__": 656,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it155",
    "testId": 155,
    "memberof": "spec/query-spec.js~describe139.describe153",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe153.it155",
    "access": null,
    "description": "should add the provided property to the list of joined properties",
    "lineNumber": 150
  },
  {
    "__docId__": 657,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe156",
    "testId": 156,
    "memberof": "spec/query-spec.js~describe139",
    "testDepth": 1,
    "longname": "spec/query-spec.js~describe139.describe156",
    "access": null,
    "description": "includeAll",
    "lineNumber": 157
  },
  {
    "__docId__": 658,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it157",
    "testId": 157,
    "memberof": "spec/query-spec.js~describe139.describe156",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe156.it157",
    "access": null,
    "description": "should add all the JoinedData attributes of the class",
    "lineNumber": 162
  },
  {
    "__docId__": 659,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe158",
    "testId": 158,
    "memberof": "spec/query-spec.js~describe139",
    "testDepth": 1,
    "longname": "spec/query-spec.js~describe139.describe158",
    "access": null,
    "description": "response formatting",
    "lineNumber": 169
  },
  {
    "__docId__": 660,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe159",
    "testId": 159,
    "memberof": "spec/query-spec.js~describe139",
    "testDepth": 1,
    "longname": "spec/query-spec.js~describe139.describe159",
    "access": null,
    "description": "sql",
    "lineNumber": 180
  },
  {
    "__docId__": 661,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it160",
    "testId": 160,
    "memberof": "spec/query-spec.js~describe139.describe159",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe159.it160",
    "access": null,
    "description": "should finalize the query so no further changes can be made",
    "lineNumber": 190
  },
  {
    "__docId__": 662,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it161",
    "testId": 161,
    "memberof": "spec/query-spec.js~describe139.describe159",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe159.it161",
    "access": null,
    "description": "should correctly generate queries with multiple where clauses",
    "lineNumber": 197
  },
  {
    "__docId__": 663,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it162",
    "testId": 162,
    "memberof": "spec/query-spec.js~describe139.describe159",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe159.it162",
    "access": null,
    "description": "should correctly escape single quotes with more double single quotes (LIKE)",
    "lineNumber": 206
  },
  {
    "__docId__": 664,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it163",
    "testId": 163,
    "memberof": "spec/query-spec.js~describe139.describe159",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe159.it163",
    "access": null,
    "description": "should correctly escape single quotes with more double single quotes (equal)",
    "lineNumber": 214
  },
  {
    "__docId__": 665,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it164",
    "testId": 164,
    "memberof": "spec/query-spec.js~describe139.describe159",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe159.it164",
    "access": null,
    "description": "should correctly generate COUNT queries",
    "lineNumber": 222
  },
  {
    "__docId__": 666,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it165",
    "testId": 165,
    "memberof": "spec/query-spec.js~describe139.describe159",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe159.it165",
    "access": null,
    "description": "should correctly generate LIMIT 1 queries for single items",
    "lineNumber": 231
  },
  {
    "__docId__": 667,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it166",
    "testId": 166,
    "memberof": "spec/query-spec.js~describe139.describe159",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe159.it166",
    "access": null,
    "description": "should correctly generate `contains` queries using JOINS",
    "lineNumber": 241
  },
  {
    "__docId__": 668,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it167",
    "testId": 167,
    "memberof": "spec/query-spec.js~describe139.describe159",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe159.it167",
    "access": null,
    "description": "should correctly generate queries with the class's naturalSortOrder when one is available and no other orders are provided",
    "lineNumber": 262
  },
  {
    "__docId__": 669,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it168",
    "testId": 168,
    "memberof": "spec/query-spec.js~describe139.describe159",
    "testDepth": 2,
    "longname": "spec/query-spec.js~describe139.describe159.it168",
    "access": null,
    "description": "should correctly generate queries requesting joined data attributes",
    "lineNumber": 287
  },
  {
    "__docId__": 670,
    "kind": "testFile",
    "static": true,
    "variation": null,
    "name": "spec/query-subscription-pool-spec.js",
    "memberof": null,
    "longname": "spec/query-subscription-pool-spec.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import QuerySubscriptionPool from '../lib/query-subscription-pool';\nimport {Database, Category} from './fixtures';\n\ndescribe(\"QuerySubscriptionPool\", function QuerySubscriptionPoolSpecs() {\n  beforeEach(() => {\n    this.pool = new QuerySubscriptionPool(Database);\n    this.query = Database.findAll(Category);\n    this.queryKey = this.query.sql();\n  });\n\n  describe(\"add\", () => {\n    it(\"should add a new subscription with the callback\", () => {\n      const callback = jasmine.createSpy('callback');\n      this.pool.add(this.query, callback);\n      expect(this.pool._subscriptions[this.queryKey]).toBeDefined();\n\n      const subscription = this.pool._subscriptions[this.queryKey];\n      expect(subscription.hasCallback(callback)).toBe(true);\n    });\n\n    it(\"should yield database changes to the subscription\", () => {\n      const callback = jasmine.createSpy('callback');\n      this.pool.add(this.query, callback);\n      const subscription = this.pool._subscriptions[this.queryKey];\n      spyOn(subscription, 'applyChangeRecord');\n\n      const record = {objectType: 'whateves'};\n      this.pool._onChange(record);\n      expect(subscription.applyChangeRecord).toHaveBeenCalledWith(record);\n    });\n\n    describe(\"unsubscribe\", () => {\n      it(\"should return an unsubscribe method\", () => {\n        expect(this.pool.add(this.query, () => {}) instanceof Function).toBe(true);\n      });\n\n      it(\"should remove the callback from the subscription\", () => {\n        const cb = () => {};\n\n        const unsub = this.pool.add(this.query, cb);\n        const subscription = this.pool._subscriptions[this.queryKey];\n\n        expect(subscription.hasCallback(cb)).toBe(true);\n        unsub();\n        expect(subscription.hasCallback(cb)).toBe(false);\n      });\n\n      it(\"should wait before removing the subscription to make sure it's not reused\", () => {\n        jasmine.clock().install();\n\n        const unsub = this.pool.add(this.query, () => {});\n        expect(this.pool._subscriptions[this.queryKey]).toBeDefined();\n        unsub();\n        expect(this.pool._subscriptions[this.queryKey]).toBeDefined();\n        jasmine.clock().tick(2);\n        expect(this.pool._subscriptions[this.queryKey]).toBeUndefined();\n\n        jasmine.clock().uninstall();\n      });\n    });\n  });\n});\n"
  },
  {
    "__docId__": 671,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe169",
    "testId": 169,
    "memberof": "spec/query-subscription-pool-spec.js",
    "testDepth": 0,
    "longname": "spec/query-subscription-pool-spec.js~describe169",
    "access": null,
    "description": "QuerySubscriptionPool",
    "lineNumber": 4
  },
  {
    "__docId__": 672,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe170",
    "testId": 170,
    "memberof": "spec/query-subscription-pool-spec.js~describe169",
    "testDepth": 1,
    "longname": "spec/query-subscription-pool-spec.js~describe169.describe170",
    "access": null,
    "description": "add",
    "lineNumber": 11
  },
  {
    "__docId__": 673,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it171",
    "testId": 171,
    "memberof": "spec/query-subscription-pool-spec.js~describe169.describe170",
    "testDepth": 2,
    "longname": "spec/query-subscription-pool-spec.js~describe169.describe170.it171",
    "access": null,
    "description": "should add a new subscription with the callback",
    "lineNumber": 12
  },
  {
    "__docId__": 674,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it172",
    "testId": 172,
    "memberof": "spec/query-subscription-pool-spec.js~describe169.describe170",
    "testDepth": 2,
    "longname": "spec/query-subscription-pool-spec.js~describe169.describe170.it172",
    "access": null,
    "description": "should yield database changes to the subscription",
    "lineNumber": 21
  },
  {
    "__docId__": 675,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe173",
    "testId": 173,
    "memberof": "spec/query-subscription-pool-spec.js~describe169.describe170",
    "testDepth": 2,
    "longname": "spec/query-subscription-pool-spec.js~describe169.describe170.describe173",
    "access": null,
    "description": "unsubscribe",
    "lineNumber": 32
  },
  {
    "__docId__": 676,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it174",
    "testId": 174,
    "memberof": "spec/query-subscription-pool-spec.js~describe169.describe170.describe173",
    "testDepth": 3,
    "longname": "spec/query-subscription-pool-spec.js~describe169.describe170.describe173.it174",
    "access": null,
    "description": "should return an unsubscribe method",
    "lineNumber": 33
  },
  {
    "__docId__": 677,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it175",
    "testId": 175,
    "memberof": "spec/query-subscription-pool-spec.js~describe169.describe170.describe173",
    "testDepth": 3,
    "longname": "spec/query-subscription-pool-spec.js~describe169.describe170.describe173.it175",
    "access": null,
    "description": "should remove the callback from the subscription",
    "lineNumber": 37
  },
  {
    "__docId__": 678,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it176",
    "testId": 176,
    "memberof": "spec/query-subscription-pool-spec.js~describe169.describe170.describe173",
    "testDepth": 3,
    "longname": "spec/query-subscription-pool-spec.js~describe169.describe170.describe173.it176",
    "access": null,
    "description": "should wait before removing the subscription to make sure it's not reused",
    "lineNumber": 48
  },
  {
    "__docId__": 679,
    "kind": "testFile",
    "static": true,
    "variation": null,
    "name": "spec/query-subscription-spec.js",
    "memberof": null,
    "longname": "spec/query-subscription-spec.js",
    "access": null,
    "description": null,
    "lineNumber": 1,
    "content": "import QueryRange from '../lib/query-range';\nimport MutableQueryResultSet from '../lib/mutable-query-result-set';\nimport QuerySubscription from '../lib/query-subscription';\nimport * as Utils from '../lib/utils';\n\nimport {Database, Thread} from './fixtures';\n\ndescribe(\"QuerySubscription\", function QuerySubscriptionSpecs() {\n  beforeEach(() => {\n    jasmine.clock().install();\n  });\n\n  afterEach(() => {\n    jasmine.clock().uninstall();\n  });\n\n  describe(\"constructor\", () =>\n    describe(\"when a query is provided\", () => {\n      it(\"should finalize the query\", () => {\n        const query = Database.findAll(Thread);\n        const subscription = new QuerySubscription(query);\n        expect(subscription).toBeDefined();\n        expect(query._finalized).toBe(true);\n      });\n\n      it(\"should throw an exception if the query is a count query, which cannot be observed\", () => {\n        const query = Database.count(Thread);\n        expect(() => {\n          const subscription = new QuerySubscription(query);\n          return subscription;\n        })\n        .toThrow();\n      });\n\n      it(\"should call `update` to initialize the result set\", () => {\n        const query = Database.findAll(Thread);\n        spyOn(QuerySubscription.prototype, 'update');\n        const subscription = new QuerySubscription(query);\n        expect(subscription).toBeDefined();\n        expect(QuerySubscription.prototype.update).toHaveBeenCalled();\n      });\n\n      describe(\"when initialModels are provided\", () =>\n        it(\"should apply the models and trigger\", () => {\n          const query = Database.findAll(Thread);\n          const threads = [1, 2, 3, 4, 5].map(i => new Thread({id: i}));\n          const subscription = new QuerySubscription(query, {initialModels: threads});\n          expect(subscription._set).not.toBe(null);\n        })\n\n      );\n    })\n\n  );\n\n  describe(\"query\", () =>\n    it(\"should return the query\", () => {\n      const query = Database.findAll(Thread);\n      const subscription = new QuerySubscription(query);\n      expect(subscription.query()).toBe(query);\n    })\n\n  );\n\n  describe(\"addCallback\", () =>\n    it(\"should emit the last result to the new callback if one is available\", (done) => {\n      const cb = jasmine.createSpy('callback');\n      spyOn(QuerySubscription.prototype, 'update').and.returnValue();\n      const subscription = new QuerySubscription(Database.findAll(Thread));\n      subscription._lastResult = 'something';\n\n      subscription.addCallback(cb);\n      jasmine.waitFor(() => cb.calls.count() > 0).then(() => {\n        expect(cb).toHaveBeenCalledWith('something');\n        done();\n      });\n    })\n  );\n\n  describe(\"applyChangeRecord\", () => {\n    const scenarios = [{\n      name: \"query with full set of objects (4)\",\n      query: Database.findAll(Thread).where(Thread.attributes.accountId.equal('a')).limit(4).offset(2),\n      lastModels: [\n        new Thread({accountId: 'a', id: '4', lastMessageReceivedTimestamp: 4}),\n        new Thread({accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3}),\n        new Thread({accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2}),\n        new Thread({accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1}),\n      ],\n      tests: [{\n        name: 'Item in set saved - new values, same sort value',\n        change: {\n          objectClass: Thread.name,\n          objects: [new Thread({accountId: 'a', id: '4', lastMessageReceivedTimestamp: 4, subject: 'hello'})],\n          type: 'persist',\n        },\n        nextModels: [\n          new Thread({accountId: 'a', id: '4', lastMessageReceivedTimestamp: 4, subject: 'hello'}),\n          new Thread({accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3}),\n          new Thread({accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2}),\n          new Thread({accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1}),\n        ],\n        mustUpdate: false,\n        mustTrigger: true,\n      }, {\n        name: 'Item in set saved - new sort value',\n        change: {\n          objectClass: Thread.name,\n          objects: [new Thread({accountId: 'a', id: '5', lastMessageReceivedTimestamp: 3.5})],\n          type: 'persist',\n        },\n        nextModels: [\n          new Thread({accountId: 'a', id: '4', lastMessageReceivedTimestamp: 4}),\n          new Thread({accountId: 'a', id: '5', lastMessageReceivedTimestamp: 3.5}),\n          new Thread({accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3}),\n          new Thread({accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2}),\n        ],\n        mustUpdate: true,\n        mustTrigger: true,\n      }, {\n        name: 'Item saved - does not match query clauses, offset > 0',\n        change: {\n          objectClass: Thread.name,\n          objects: [new Thread({accountId: 'b', id: '5', lastMessageReceivedTimestamp: 5})],\n          type: 'persist',\n        },\n        nextModels: 'unchanged',\n        mustUpdate: true,\n      }, {\n        name: 'Item saved - matches query clauses',\n        change: {\n          objectClass: Thread.name,\n          objects: [new Thread({accountId: 'a', id: '5', lastMessageReceivedTimestamp: -2})],\n          type: 'persist',\n        },\n        mustUpdate: true,\n      }, {\n        name: 'Item in set saved - no longer matches query clauses',\n        change: {\n          objectClass: Thread.name,\n          objects: [new Thread({accountId: 'b', id: '4', lastMessageReceivedTimestamp: 4})],\n          type: 'persist',\n        },\n        nextModels: [\n          new Thread({accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3}),\n          new Thread({accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2}),\n          new Thread({accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1}),\n        ],\n        mustUpdate: true,\n      }, {\n        name: 'Item in set deleted',\n        change: {\n          objectClass: Thread.name,\n          objects: [new Thread({accountId: 'a', id: '4'})],\n          type: 'unpersist',\n        },\n        nextModels: [\n          new Thread({accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3}),\n          new Thread({accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2}),\n          new Thread({accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1}),\n        ],\n        mustUpdate: true,\n      }, {\n        name: 'Item not in set deleted',\n        change: {\n          objectClass: Thread.name,\n          objects: [new Thread({accountId: 'a', id: '5'})],\n          type: 'unpersist',\n        },\n        nextModels: 'unchanged',\n        mustUpdate: false,\n      }],\n    }, {\n      name: \"query with multiple sort orders\",\n      query: Database.findAll(Thread).where(Thread.attributes.accountId.equal('a')).limit(4).offset(2).order([\n        Thread.attributes.lastMessageReceivedTimestamp.ascending(),\n        Thread.attributes.unread.descending(),\n      ]),\n      lastModels: [\n        new Thread({accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1, unread: true}),\n        new Thread({accountId: 'a', id: '2', lastMessageReceivedTimestamp: 1, unread: false}),\n        new Thread({accountId: 'a', id: '3', lastMessageReceivedTimestamp: 1, unread: false}),\n        new Thread({accountId: 'a', id: '4', lastMessageReceivedTimestamp: 2, unread: true}),\n      ],\n      tests: [{\n        name: 'Item in set saved, secondary sort order changed',\n        change: {\n          objectClass: Thread.name,\n          objects: [new Thread({accountId: 'a', id: '3', lastMessageReceivedTimestamp: 1, unread: true})],\n          type: 'persist',\n        },\n        mustUpdate: true,\n      }],\n    }];\n\n    describe(\"scenarios\", () =>\n      scenarios.forEach(scenario => {\n        scenario.tests.forEach(test => {\n          it(`with ${scenario.name}, should correctly apply ${test.name}`, () => {\n            spyOn(Utils, 'generateTempId').and.callFake(() => undefined);\n\n            const subscription = new QuerySubscription(scenario.query);\n            subscription._set = new MutableQueryResultSet();\n            subscription._set.addModelsInRange(scenario.lastModels, new QueryRange({start: 0, end: scenario.lastModels.length}));\n\n            spyOn(subscription, 'update');\n            spyOn(subscription, '_createResultAndTrigger');\n            subscription._updateInFlight = false;\n            subscription.applyChangeRecord(test.change);\n\n            if (test.mustUpdate) {\n              expect(subscription.update).toHaveBeenCalledWith({mustRefetchEntireRange: true});\n            } else {\n              if (test.nextModels === 'unchanged') {\n                expect(subscription._set.models()).toEqual(scenario.lastModels);\n              } else {\n                expect(subscription._set.models()).toEqual(test.nextModels);\n              }\n            }\n\n            if (test.mustTriger) {\n              expect(subscription._createResultAndTrigger).toHaveBeenCalled();\n            }\n          });\n        });\n      })\n\n    );\n  });\n\n  describe(\"update\", () => {\n    beforeEach(() =>\n      spyOn(QuerySubscription.prototype, '_fetchRange').and.callFake(() => {\n        if (this._set == null) { this._set = new MutableQueryResultSet(); }\n        return Promise.resolve();\n      })\n    );\n\n    describe(\"when the query has an infinite range\", () => {\n      it(\"should call _fetchRange for the entire range\", () => {\n        const subscription = new QuerySubscription(Database.findAll(Thread));\n        subscription.update();\n        jasmine.clock().tick();\n        expect(subscription._fetchRange).toHaveBeenCalledWith(QueryRange.infinite(), {fetchEntireModels: true, version: 1});\n      });\n\n      it(\"should fetch full full models only when the previous set is empty\", () => {\n        const subscription = new QuerySubscription(Database.findAll(Thread));\n        subscription._set = new MutableQueryResultSet();\n        subscription._set.addModelsInRange([new Thread()], new QueryRange({start: 0, end: 1}));\n        subscription.update();\n        jasmine.clock().tick();\n        expect(subscription._fetchRange).toHaveBeenCalledWith(QueryRange.infinite(), {fetchEntireModels: false, version: 1});\n      });\n    });\n\n    describe(\"when the query has a range\", () => {\n      beforeEach(() => {\n        this.query = Database.findAll(Thread).limit(10);\n      });\n\n      describe(\"when we have no current range\", () =>\n        it(\"should call _fetchRange for the entire range and fetch full models\", () => {\n          const subscription = new QuerySubscription(this.query);\n          subscription._set = null;\n          subscription.update();\n          jasmine.clock().tick();\n          expect(subscription._fetchRange).toHaveBeenCalledWith(this.query.range(), {fetchEntireModels: true, version: 1});\n        })\n      );\n\n      describe(\"when we have a previous range\", () => {\n        it(\"should call _fetchRange with the missingRange\", () => {\n          const customRange = jasmine.createSpy('customRange1');\n          spyOn(QueryRange, 'rangesBySubtracting').and.returnValue([customRange]);\n          const subscription = new QuerySubscription(this.query);\n          subscription._set = new MutableQueryResultSet();\n          subscription._set.addModelsInRange([new Thread()], new QueryRange({start: 0, end: 1}));\n\n          jasmine.clock().tick();\n          QuerySubscription.prototype._fetchRange.calls.reset();\n          subscription._updateInFlight = false;\n          subscription.update();\n          jasmine.clock().tick();\n          expect(subscription._fetchRange.calls.count()).toBe(1);\n          expect(subscription._fetchRange.calls.first().args).toEqual([customRange, {fetchEntireModels: true, version: 1}]);\n        });\n\n        it(\"should call _fetchRange for the entire query range when the missing range encompasses more than one range\", () => {\n          const customRange1 = jasmine.createSpy('customRange1');\n          const customRange2 = jasmine.createSpy('customRange2');\n          spyOn(QueryRange, 'rangesBySubtracting').and.returnValue([customRange1, customRange2]);\n\n          const range = new QueryRange({start: 0, end: 1});\n          const subscription = new QuerySubscription(this.query);\n          subscription._set = new MutableQueryResultSet();\n          subscription._set.addModelsInRange([new Thread()], range);\n\n          jasmine.clock().tick();\n          QuerySubscription.prototype._fetchRange.calls.reset();\n          subscription._updateInFlight = false;\n          subscription.update();\n          jasmine.clock().tick();\n          expect(subscription._fetchRange.calls.count()).toBe(1);\n          expect(subscription._fetchRange.calls.first().args).toEqual([this.query.range(), {fetchEntireModels: true, version: 1}]);\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "__docId__": 680,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe177",
    "testId": 177,
    "memberof": "spec/query-subscription-spec.js",
    "testDepth": 0,
    "longname": "spec/query-subscription-spec.js~describe177",
    "access": null,
    "description": "QuerySubscription",
    "lineNumber": 8
  },
  {
    "__docId__": 681,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe178",
    "testId": 178,
    "memberof": "spec/query-subscription-spec.js~describe177",
    "testDepth": 1,
    "longname": "spec/query-subscription-spec.js~describe177.describe178",
    "access": null,
    "description": "constructor",
    "lineNumber": 17
  },
  {
    "__docId__": 682,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it179",
    "testId": 179,
    "memberof": "spec/query-subscription-spec.js~describe177.describe178",
    "testDepth": 2,
    "longname": "spec/query-subscription-spec.js~describe177.describe178.it179",
    "access": null,
    "description": "should finalize the query",
    "lineNumber": 19
  },
  {
    "__docId__": 683,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it180",
    "testId": 180,
    "memberof": "spec/query-subscription-spec.js~describe177.describe178",
    "testDepth": 2,
    "longname": "spec/query-subscription-spec.js~describe177.describe178.it180",
    "access": null,
    "description": "should throw an exception if the query is a count query, which cannot be observed",
    "lineNumber": 26
  },
  {
    "__docId__": 684,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it181",
    "testId": 181,
    "memberof": "spec/query-subscription-spec.js~describe177.describe178",
    "testDepth": 2,
    "longname": "spec/query-subscription-spec.js~describe177.describe178.it181",
    "access": null,
    "description": "should call `update` to initialize the result set",
    "lineNumber": 35
  },
  {
    "__docId__": 685,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe182",
    "testId": 182,
    "memberof": "spec/query-subscription-spec.js~describe177.describe178",
    "testDepth": 2,
    "longname": "spec/query-subscription-spec.js~describe177.describe178.describe182",
    "access": null,
    "description": "when initialModels are provided",
    "lineNumber": 43
  },
  {
    "__docId__": 686,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe183",
    "testId": 183,
    "memberof": "spec/query-subscription-spec.js~describe177",
    "testDepth": 1,
    "longname": "spec/query-subscription-spec.js~describe177.describe183",
    "access": null,
    "description": "query",
    "lineNumber": 56
  },
  {
    "__docId__": 687,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe184",
    "testId": 184,
    "memberof": "spec/query-subscription-spec.js~describe177",
    "testDepth": 1,
    "longname": "spec/query-subscription-spec.js~describe177.describe184",
    "access": null,
    "description": "addCallback",
    "lineNumber": 65
  },
  {
    "__docId__": 688,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe185",
    "testId": 185,
    "memberof": "spec/query-subscription-spec.js~describe177",
    "testDepth": 1,
    "longname": "spec/query-subscription-spec.js~describe177.describe185",
    "access": null,
    "description": "applyChangeRecord",
    "lineNumber": 80
  },
  {
    "__docId__": 689,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe186",
    "testId": 186,
    "memberof": "spec/query-subscription-spec.js~describe177.describe185",
    "testDepth": 2,
    "longname": "spec/query-subscription-spec.js~describe177.describe185.describe186",
    "access": null,
    "description": "scenarios",
    "lineNumber": 196
  },
  {
    "__docId__": 690,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it187",
    "testId": 187,
    "memberof": "spec/query-subscription-spec.js~describe177.describe185.describe186",
    "testDepth": 3,
    "longname": "spec/query-subscription-spec.js~describe177.describe185.describe186.it187",
    "access": null,
    "lineNumber": 199
  },
  {
    "__docId__": 691,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe188",
    "testId": 188,
    "memberof": "spec/query-subscription-spec.js~describe177",
    "testDepth": 1,
    "longname": "spec/query-subscription-spec.js~describe177.describe188",
    "access": null,
    "description": "update",
    "lineNumber": 231
  },
  {
    "__docId__": 692,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe189",
    "testId": 189,
    "memberof": "spec/query-subscription-spec.js~describe177.describe188",
    "testDepth": 2,
    "longname": "spec/query-subscription-spec.js~describe177.describe188.describe189",
    "access": null,
    "description": "when the query has an infinite range",
    "lineNumber": 239
  },
  {
    "__docId__": 693,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it190",
    "testId": 190,
    "memberof": "spec/query-subscription-spec.js~describe177.describe188.describe189",
    "testDepth": 3,
    "longname": "spec/query-subscription-spec.js~describe177.describe188.describe189.it190",
    "access": null,
    "description": "should call _fetchRange for the entire range",
    "lineNumber": 240
  },
  {
    "__docId__": 694,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it191",
    "testId": 191,
    "memberof": "spec/query-subscription-spec.js~describe177.describe188.describe189",
    "testDepth": 3,
    "longname": "spec/query-subscription-spec.js~describe177.describe188.describe189.it191",
    "access": null,
    "description": "should fetch full full models only when the previous set is empty",
    "lineNumber": 247
  },
  {
    "__docId__": 695,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe192",
    "testId": 192,
    "memberof": "spec/query-subscription-spec.js~describe177.describe188",
    "testDepth": 2,
    "longname": "spec/query-subscription-spec.js~describe177.describe188.describe192",
    "access": null,
    "description": "when the query has a range",
    "lineNumber": 257
  },
  {
    "__docId__": 696,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe193",
    "testId": 193,
    "memberof": "spec/query-subscription-spec.js~describe177.describe188.describe192",
    "testDepth": 3,
    "longname": "spec/query-subscription-spec.js~describe177.describe188.describe192.describe193",
    "access": null,
    "description": "when we have no current range",
    "lineNumber": 262
  },
  {
    "__docId__": 697,
    "kind": "testDescribe",
    "static": true,
    "variation": null,
    "name": "describe194",
    "testId": 194,
    "memberof": "spec/query-subscription-spec.js~describe177.describe188.describe192",
    "testDepth": 3,
    "longname": "spec/query-subscription-spec.js~describe177.describe188.describe192.describe194",
    "access": null,
    "description": "when we have a previous range",
    "lineNumber": 272
  },
  {
    "__docId__": 698,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it195",
    "testId": 195,
    "memberof": "spec/query-subscription-spec.js~describe177.describe188.describe192.describe194",
    "testDepth": 4,
    "longname": "spec/query-subscription-spec.js~describe177.describe188.describe192.describe194.it195",
    "access": null,
    "description": "should call _fetchRange with the missingRange",
    "lineNumber": 273
  },
  {
    "__docId__": 699,
    "kind": "testIt",
    "static": true,
    "variation": null,
    "name": "it196",
    "testId": 196,
    "memberof": "spec/query-subscription-spec.js~describe177.describe188.describe192.describe194",
    "testDepth": 4,
    "longname": "spec/query-subscription-spec.js~describe177.describe188.describe192.describe194.it196",
    "access": null,
    "description": "should call _fetchRange for the entire query range when the missing range encompasses more than one range",
    "lineNumber": 289
  }
]