Skip to content
This repository has been archived by the owner on Aug 25, 2022. It is now read-only.

Commit

Permalink
add asyncReplace directive
Browse files Browse the repository at this point in the history
  • Loading branch information
popeindustries committed Oct 10, 2019
1 parent 11165ee commit 0f0f5ab
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
9 changes: 9 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,15 @@ declare module '@popeindustres/lit-html-server/directives/async-append.js' {
) => (part: Part) => void;
}

declare module '@popeindustres/lit-html-server/directives/async-replace.js' {
import { Part } from '@popeindustries/lit-html-server';

export const asyncReplace: (
value: AsyncIterable<unknown>,
mapper?: ((v: unknown, index?: number | undefined) => unknown) | undefined
) => (part: Part) => void;
}

declare module '@popeindustres/lit-html-server/directives/cache.js' {
import { Part } from '@popeindustries/lit-html-server';

Expand Down
26 changes: 26 additions & 0 deletions src/directives/async-replace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @typedef Part { import('../parts.js').Part }
*/
import { directive, isNodePart } from '../index.js';

/**
* Render items of an AsyncIterable, replacing previous items as they are resolved.
* Not possible to render more than once in a server context, so only the first item is rendered.
*
* @type { (value: AsyncIterable<unknown>, mapper?: ((v: unknown, index?: number | undefined) => unknown) | undefined) => (part: Part) => void }
*/
export const asyncReplace = directive((value, mapper) => (part) => {
if (!isNodePart(part)) {
throw Error('The `asyncReplace` directive can only be used in text nodes');
}

part.setValue(
value.next().then(({ value }) => {
if (mapper !== undefined) {
value = mapper(value, 0);
}

return value;
})
);
});
14 changes: 14 additions & 0 deletions test/directives-test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { directive, html as h, renderToString as render } from '../index.mjs';
import { asyncAppend } from '../directives/async-append.mjs';
import { asyncReplace } from '../directives/async-replace.mjs';
import { cache } from '../directives/cache.mjs';
import { classMap } from '../directives/class-map.mjs';
import { createAsyncIterable } from './utils.js';
Expand All @@ -25,6 +26,19 @@ describe('directives', () => {
});
});

describe('asyncReplace', () => {
it('should render an AsyncIterable value', async () => {
const result = h`some ${asyncReplace(createAsyncIterable(['async', ' text']))}`;
expect(await render(result)).to.equal('some async');
});
it('should render a mapped AsyncIterable value', async () => {
const result = h`some ${asyncReplace(createAsyncIterable(['async', 'text']), (v, index) => {
return `${index}-${v.toUpperCase()}`;
})}`;
expect(await render(result)).to.equal('some 0-ASYNC');
});
});

describe('cache', () => {
it('should render a cached value', async () => {
const result = h`some ${cache('text')}`;
Expand Down

0 comments on commit 0f0f5ab

Please # to comment.