{"version":3,"file":"guard.js","sources":["../../../src/directives/guard.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nimport {noChange, Part} from '../lit-html.js';\nimport {\n  directive,\n  Directive,\n  DirectiveParameters,\n  DirectiveResult,\n} from '../directive.js';\n\n// A sentinel that indicates guard() hasn't rendered anything yet\nconst initialValue = {};\n\nclass GuardDirective<T> extends Directive {\n  private _previousValue: unknown = initialValue;\n\n  render(_value: unknown, f: () => T): T {\n    return f();\n  }\n\n  override update(_part: Part, [value, f]: DirectiveParameters<this>) {\n    if (Array.isArray(value)) {\n      // Dirty-check arrays by item\n      if (\n        Array.isArray(this._previousValue) &&\n        this._previousValue.length === value.length &&\n        value.every((v, i) => v === (this._previousValue as Array<unknown>)[i])\n      ) {\n        return noChange;\n      }\n    } else if (this._previousValue === value) {\n      // Dirty-check non-arrays by identity\n      return noChange;\n    }\n\n    // Copy the value if it's an array so that if it's mutated we don't forget\n    // what the previous values were.\n    this._previousValue = Array.isArray(value) ? Array.from(value) : value;\n    const r = this.render(value, f);\n    return r;\n  }\n}\n\ninterface Guard {\n  <T>(vals: unknown[], f: () => T): DirectiveResult<typeof GuardDirective<T>>;\n}\n\n/**\n * Prevents re-render of a template function until a single value or an array of\n * values changes.\n *\n * Values are checked against previous values with strict equality (`===`), and\n * so the check won't detect nested property changes inside objects or arrays.\n * Arrays values have each item checked against the previous value at the same\n * index with strict equality. Nested arrays are also checked only by strict\n * equality.\n *\n * Example:\n *\n * ```js\n * html`\n *   <div>\n *     ${guard([user.id, company.id], () => html`...`)}\n *   </div>\n * `\n * ```\n *\n * In this case, the template only rerenders if either `user.id` or `company.id`\n * changes.\n *\n * guard() is useful with immutable data patterns, by preventing expensive work\n * until data updates.\n *\n * Example:\n *\n * ```js\n * html`\n *   <div>\n *     ${guard([immutableItems], () => immutableItems.map(i => html`${i}`))}\n *   </div>\n * `\n * ```\n *\n * In this case, items are mapped over only when the array reference changes.\n *\n * @param value the value to check before re-rendering\n * @param f the template function\n */\nexport const guard: Guard = directive(GuardDirective);\n\n/**\n * The type of the class that powers this directive. Necessary for naming the\n * directive's return type.\n */\nexport type {GuardDirective};\n"],"names":[],"mappings":";;;AAAA;;;;AAIG;AAUH;AACA,MAAM,YAAY,GAAG,EAAE;AAEvB,MAAM,cAAkB,SAAQ,SAAS,CAAA;AAAzC,IAAA,WAAA,GAAA;;QACU,IAAA,CAAA,cAAc,GAAY,YAAY;IA2BhD;IAzBE,MAAM,CAAC,MAAe,EAAE,CAAU,EAAA;QAChC,OAAO,CAAC,EAAE;IACZ;AAES,IAAA,MAAM,CAAC,KAAW,EAAE,CAAC,KAAK,EAAE,CAAC,CAA4B,EAAA;AAChE,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;;AAExB,YAAA,IACE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC;AAClC,gBAAA,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;gBAC3C,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAM,IAAI,CAAC,cAAiC,CAAC,CAAC,CAAC,CAAC,EACvE;AACA,gBAAA,OAAO,QAAQ;YACjB;QACF;AAAO,aAAA,IAAI,IAAI,CAAC,cAAc,KAAK,KAAK,EAAE;;AAExC,YAAA,OAAO,QAAQ;QACjB;;;QAIA,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK;QACtE,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;AAC/B,QAAA,OAAO,CAAC;IACV;AACD;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCG;MACU,KAAK,GAAU,SAAS,CAAC,cAAc;;;;"}