1 line
5.4 KiB
Plaintext
1 line
5.4 KiB
Plaintext
{"version":3,"file":"async-replace.js","sources":["../src/directives/async-replace.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nimport {ChildPart, noChange} from '../lit-html.js';\nimport {\n AsyncDirective,\n directive,\n DirectiveParameters,\n} from '../async-directive.js';\nimport {Pauser, PseudoWeakRef, forAwaitOf} from './private-async-helpers.js';\n\ntype Mapper<T> = (v: T, index?: number) => unknown;\n\nexport class AsyncReplaceDirective extends AsyncDirective {\n private __value?: AsyncIterable<unknown>;\n private __weakThis = new PseudoWeakRef(this);\n private __pauser = new Pauser();\n\n // @ts-expect-error value not used, but we want a nice parameter for docs\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n render<T>(value: AsyncIterable<T>, _mapper?: Mapper<T>) {\n return noChange;\n }\n\n override update(\n _part: ChildPart,\n [value, mapper]: DirectiveParameters<this>\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 // If we've already set up this particular iterable, we don't need\n // to do anything.\n if (value === this.__value) {\n return;\n }\n this.__value = value;\n let i = 0;\n const {__weakThis: weakThis, __pauser: pauser} = this;\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 forAwaitOf(value, async (v: unknown) => {\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 // Check to make sure that value is the still the current value of\n // the part, and if not bail because a new value owns this part\n if (_this.__value !== value) {\n return false;\n }\n\n // As a convenience, because functional-programming-style\n // transforms of iterables and async iterables requires a library,\n // we accept a mapper function. This is especially convenient for\n // rendering a template for each item.\n if (mapper !== undefined) {\n v = mapper(v, i);\n }\n\n _this.commitValue(v, i);\n i++;\n }\n return true;\n });\n return noChange;\n }\n\n // Override point for AsyncAppend to append rather than replace\n protected commitValue(value: unknown, _index: number) {\n this.setValue(value);\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 * A directive that renders the items of an async iterable[1], replacing\n * previous values with new values, so that only one value is ever rendered\n * at a time. This directive may be used in any expression type.\n *\n * Async iterables are objects with a `[Symbol.asyncIterator]` method, which\n * returns an iterator who's `next()` method returns a Promise. When a new\n * value is available, the Promise resolves and the value is rendered to the\n * Part controlled by the directive. If another value other than this\n * directive has been set on the Part, the iterable will no longer be listened\n * to and new values won't be written to the Part.\n *\n * [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of\n *\n * @param value An async iterable\n * @param mapper An optional function that maps from (value, index) to another\n * value. Useful for generating templates for each item in the iterable.\n */\nexport const asyncReplace = directive(AsyncReplaceDirective);\n"],"names":["AsyncReplaceDirective","AsyncDirective","constructor","this","__weakThis","PseudoWeakRef","__pauser","Pauser","render","value","_mapper","noChange","update","_part","mapper","isConnected","disconnected","__value","i","weakThis","pauser","forAwaitOf","async","v","get","_this","deref","undefined","commitValue","_index","setValue","disconnect","pause","reconnected","reconnect","resume","asyncReplace","directive"],"mappings":";;;;;GAgBM,MAAOA,UAA8BC,EAA3CC,kCAEUC,KAAAC,KAAa,IAAIC,EAAcF,MAC/BA,KAAAG,KAAW,IAAIC,CA4ExB,CAxECC,OAAUC,EAAyBC,GACjC,OAAOC,CACR,CAEQC,OACPC,GACCJ,EAAOK,IASR,GALKX,KAAKY,aACRZ,KAAKa,eAIHP,IAAUN,KAAKc,KACjB,OAEFd,KAAKc,KAAUR,EACf,IAAIS,EAAI,EACR,MAAOd,KAAYe,EAAUb,KAAUc,GAAUjB,KAmCjD,OA9BAkB,EAAWZ,GAAOa,MAAOC,IAGvB,KAAOH,EAAOI,aACNJ,EAAOI,MAKf,MAAMC,EAAQN,EAASO,QACvB,QAAcC,IAAVF,EAAqB,CAGvB,GAAIA,EAAMR,OAAYR,EACpB,OAAO,OAOMkB,IAAXb,IACFS,EAAIT,EAAOS,EAAGL,IAGhBO,EAAMG,YAAYL,EAAGL,GACrBA,GACD,CACD,OAAO,CAAI,IAENP,CACR,CAGSiB,YAAYnB,EAAgBoB,GACpC1B,KAAK2B,SAASrB,EACf,CAEQO,eACPb,KAAKC,KAAW2B,aAChB5B,KAAKG,KAAS0B,OACf,CAEQC,cACP9B,KAAKC,KAAW8B,UAAU/B,MAC1BA,KAAKG,KAAS6B,QACf,QAqBUC,EAAeC,EAAUrC"} |