{"version":3,"file":"until.js","sources":["../../../src/directives/until.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nimport {Part, noChange} from '../lit-html.js';\nimport {isPrimitive} from '../directive-helpers.js';\nimport {directive, AsyncDirective} from '../async-directive.js';\nimport {Pauser, PseudoWeakRef} from './private-async-helpers.js';\n\nconst isPromise = (x: unknown) => {\n return !isPrimitive(x) && typeof (x as {then?: unknown}).then === 'function';\n};\n// Effectively infinity, but a SMI.\nconst _infinity = 0x3fffffff;\n\nexport class UntilDirective extends AsyncDirective {\n private __lastRenderedIndex: number = _infinity;\n private __values: unknown[] = [];\n private __weakThis = new PseudoWeakRef(this);\n private __pauser = new Pauser();\n\n render(...args: Array) {\n return args.find((x) => !isPromise(x)) ?? noChange;\n }\n\n override update(_part: Part, args: Array) {\n const previousValues = this.__values;\n let previousLength = previousValues.length;\n this.__values = args;\n\n const weakThis = this.__weakThis;\n const pauser = this.__pauser;\n\n // If our initial render occurs while disconnected, ensure that the pauser\n // and weakThis are in the disconnected state\n if (!this.isConnected) {\n this.disconnected();\n }\n\n for (let i = 0; i < args.length; i++) {\n // If we've rendered a higher-priority value already, stop.\n if (i > this.__lastRenderedIndex) {\n break;\n }\n\n const value = args[i];\n\n // Render non-Promise values immediately\n if (!isPromise(value)) {\n this.__lastRenderedIndex = i;\n // Since a lower-priority value will never overwrite a higher-priority\n // synchronous value, we can stop processing now.\n return value;\n }\n\n // If this is a Promise we've already handled, skip it.\n if (i < previousLength && value === previousValues[i]) {\n continue;\n }\n\n // We have a Promise that we haven't seen before, so priorities may have\n // changed. Forget what we rendered before.\n this.__lastRenderedIndex = _infinity;\n previousLength = 0;\n\n // Note, the callback avoids closing over `this` so that the directive\n // can be gc'ed before the promise resolves; instead `this` is retrieved\n // from `weakThis`, which can break the hard reference in the closure when\n // the directive disconnects\n Promise.resolve(value).then(async (result: unknown) => {\n // If we're disconnected, wait until we're (maybe) reconnected\n // The while loop here handles the case that the connection state\n // thrashes, causing the pauser to resume and then get re-paused\n while (pauser.get()) {\n await pauser.get();\n }\n // If the callback gets here and there is no `this`, it means that the\n // directive has been disconnected and garbage collected and we don't\n // need to do anything else\n const _this = weakThis.deref();\n if (_this !== undefined) {\n const index = _this.__values.indexOf(value);\n // If state.values doesn't contain the value, we've re-rendered without\n // the value, so don't render it. Then, only render if the value is\n // higher-priority than what's already been rendered.\n if (index > -1 && index < _this.__lastRenderedIndex) {\n _this.__lastRenderedIndex = index;\n _this.setValue(result);\n }\n }\n });\n }\n\n return noChange;\n }\n\n override disconnected() {\n this.__weakThis.disconnect();\n this.__pauser.pause();\n }\n\n override reconnected() {\n this.__weakThis.reconnect(this);\n this.__pauser.resume();\n }\n}\n\n/**\n * Renders one of a series of values, including Promises, to a Part.\n *\n * Values are rendered in priority order, with the first argument having the\n * highest priority and the last argument having the lowest priority. If a\n * value is a Promise, low-priority values will be rendered until it resolves.\n *\n * The priority of values can be used to create placeholder content for async\n * data. For example, a Promise with pending content can be the first,\n * highest-priority, argument, and a non_promise loading indicator template can\n * be used as the second, lower-priority, argument. The loading indicator will\n * render immediately, and the primary content will render when the Promise\n * resolves.\n *\n * Example:\n *\n * ```js\n * const content = fetch('./content.txt').then(r => r.text());\n * html`${until(content, html`Loading...`)}`\n * ```\n */\nexport const until = directive(UntilDirective);\n\n/**\n * The type of the class that powers this directive. Necessary for naming the\n * directive's return type.\n */\n// export type {UntilDirective};\n"],"names":[],"mappings":"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"}