element-vir 10.2.2 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -200,36 +200,6 @@ export const MyWithAssignmentElement = defineElementNoInputs({
200
200
  });
201
201
  ```
202
202
 
203
- ## Rendering promises
204
-
205
- A handy directive is built in for rendering promises: `renderPromise`. See how it works below:
206
-
207
- <!-- example-link: src/readme-examples/my-async-render.element.ts -->
208
-
209
- ```TypeScript
210
- import {defineElementNoInputs, html, renderPromise} from 'element-vir';
211
-
212
- export const MyAsyncRenderElement = defineElementNoInputs({
213
- tagName: 'my-async-render',
214
- stateInit: {
215
- data: fetch('https://example.org'),
216
- },
217
- renderCallback: ({state}) => html`
218
- ${renderPromise(state.data, ({promise, error, resolved}) => {
219
- if (promise) {
220
- return 'Still loading...';
221
- } else if (resolved) {
222
- return html`
223
- Load done!
224
- `;
225
- } else {
226
- return `Load failed: ${error.message}`;
227
- }
228
- })}
229
- `,
230
- });
231
- ```
232
-
233
203
  ## Other callbacks
234
204
 
235
205
  There are two other callbacks you can define that are sort of similar to lifecycle callbacks. They are much simpler than lifecycle callbacks however.
@@ -624,6 +594,74 @@ export const MyWithRenderIfElement = defineElement<{shouldRender: boolean}>()({
624
594
  });
625
595
  ```
626
596
 
597
+ ### asyncState
598
+
599
+ Use the `renderAsyncState` directive in conjunction with the `asyncState` property definer to seamlessly render and update element state based on async values:
600
+
601
+ <!-- example-link: src/readme-examples/my-with-async-prop.element.ts -->
602
+
603
+ ```TypeScript
604
+ import {asyncState, defineElement, html, listen, renderAsyncState} from 'element-vir';
605
+
606
+ type EndpointData = number[];
607
+
608
+ async function loadSomething(endpoint: string): Promise<EndpointData> {
609
+ // load something from the network
610
+ const data = await (
611
+ await fetch(
612
+ [
613
+ '',
614
+ 'api',
615
+ endpoint,
616
+ ].join('/'),
617
+ )
618
+ ).json();
619
+ return data;
620
+ }
621
+
622
+ export const MyWithAsyncStateElement = defineElement<{endpoint: string}>()({
623
+ tagName: 'my-simple-with-render-if',
624
+ stateInit: {
625
+ data: asyncState<EndpointData>(),
626
+ },
627
+ renderCallback: ({inputs, state, updateState}) => {
628
+ /**
629
+ * This creates a promise which automatically updates the state.loadsLater prop once the
630
+ * promise resolves. It only creates a new promise if the "trigger" value changes.
631
+ */
632
+ updateState({
633
+ data: {
634
+ createPromise: () => loadSomething(inputs.endpoint),
635
+ trigger: inputs.endpoint,
636
+ },
637
+ });
638
+
639
+ return html`
640
+ Here's the data:
641
+ <br />
642
+ ${renderAsyncState(state.data, 'Loading...', (loadedData) => {
643
+ return html`
644
+ Got the data: ${loadedData}
645
+ `;
646
+ })}
647
+ <br />
648
+ <button
649
+ ${listen('click', () => {
650
+ updateState({
651
+ data: {
652
+ /** You can force asyncState to update by passing in forceUpdate: true. */
653
+ forceUpdate: true,
654
+ },
655
+ });
656
+ })}
657
+ >
658
+ Refresh
659
+ </button>
660
+ `;
661
+ },
662
+ });
663
+ ```
664
+
627
665
  ## Require all child custom elements to be declarative elements
628
666
 
629
667
  To require all child elements to be declarative elements defined by this package, call `requireAllCustomElementsToBeDeclarativeElements` anywhere in your app. This is a global setting so do not enable it unless you want it to be true _everywhere_ in your current run-time. This should not be used if you're using custom elements from other libraries (unless they happen to also use this package to define their custom elements).
@@ -1,6 +1,7 @@
1
1
  import { CSSResult } from 'lit';
2
2
  import { RequireNonVoidReturn } from '../augments/type';
3
3
  import { DeclarativeElementDefinitionOptions } from './definition-options';
4
+ import { MaybeAsyncStateToSync } from './properties/async-state';
4
5
  import { CssVarsInitMap } from './properties/css-vars';
5
6
  import { EventsInitMap } from './properties/element-events';
6
7
  import { PropertyInitMapBase } from './properties/element-properties';
@@ -8,7 +9,7 @@ import { HostClassesInitMap } from './properties/host-classes';
8
9
  import { StylesCallback } from './properties/styles';
9
10
  import { InitCallback, RenderCallback } from './render-callback';
10
11
  export type CustomElementTagName = `${string}-${string}`;
11
- export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeysGeneric extends string, CssVarKeysGeneric extends string, RenderOutputGeneric> = {
12
+ export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitMaybeAsyncGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeysGeneric extends string, CssVarKeysGeneric extends string, RenderOutputGeneric> = {
12
13
  /**
13
14
  * HTML tag name. This should not be used directly, as interpolating it with the html tagged
14
15
  * template from this package is preferred.
@@ -17,7 +18,7 @@ export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName,
17
18
  /** Static styles. These should not and cannot change. */
18
19
  styles?: CSSResult | StylesCallback<HostClassKeysGeneric, CssVarKeysGeneric>;
19
20
  /** Element properties. (These can be thought of as "inputs".) */
20
- stateInit?: StateInitGeneric;
21
+ stateInit?: StateInitMaybeAsyncGeneric;
21
22
  /** Events that the element can dispatch. (These can be thought of as "outputs".) */
22
23
  events?: EventsInitGeneric;
23
24
  /**
@@ -25,7 +26,7 @@ export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName,
25
26
  * based on current instance state or inputs, or just undefined to indicate that the host class
26
27
  * will only be manually set.
27
28
  */
28
- hostClasses?: HostClassesInitMap<HostClassKeysGeneric, InputsGeneric, StateInitGeneric>;
29
+ hostClasses?: HostClassesInitMap<HostClassKeysGeneric, InputsGeneric, MaybeAsyncStateToSync<StateInitMaybeAsyncGeneric>>;
29
30
  /**
30
31
  * CSS Vars for the component. Keys of this object should be camelCased (or whatever your casing
31
32
  * convention is). They will be transformed, at runtime, to CSS vars with kebab-casing, to match
@@ -38,9 +39,9 @@ export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName,
38
39
  */
39
40
  cssVars?: CssVarsInitMap<CssVarKeysGeneric>;
40
41
  /** Called as part of the first renderCallback call, before the first renderCallback call. */
41
- initCallback?: InitCallback<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric, void>;
42
- renderCallback: RequireNonVoidReturn<RenderOutputGeneric, RenderCallback<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric, RenderOutputGeneric>>;
43
- cleanupCallback?: InitCallback<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric, void>;
42
+ initCallback?: InitCallback<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric, void>;
43
+ renderCallback: RequireNonVoidReturn<RenderOutputGeneric, RenderCallback<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric, RenderOutputGeneric>>;
44
+ cleanupCallback?: InitCallback<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric, void>;
44
45
  options?: Partial<DeclarativeElementDefinitionOptions> | undefined;
45
46
  };
46
47
  //# sourceMappingURL=declarative-element-init.d.ts.map
@@ -1,16 +1,17 @@
1
1
  import { RequiredAndNotNullBy, RequiredBy } from '@augment-vir/common';
2
2
  import { CSSResult, LitElement } from 'lit';
3
3
  import { CustomElementTagName, DeclarativeElementInit } from './declarative-element-init';
4
+ import { AsyncStateHandlerMap, MaybeAsyncStateToSync } from './properties/async-state';
4
5
  import { CssVarNameOrValueMap } from './properties/css-vars';
5
6
  import { EventDescriptorMap, EventsInitMap } from './properties/element-events';
6
7
  import { ElementPropertyDescriptorMap, PropertyInitMapBase } from './properties/element-properties';
7
8
  import { HostClassNamesMap } from './properties/host-classes';
8
9
  import { RenderCallback } from './render-callback';
9
- export type HostInstanceType<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string, RenderOutputGeneric> = RequiredAndNotNullBy<DeclarativeElement<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>, 'shadowRoot'>;
10
- export type DeclarativeElementDefinition<TagNameGeneric extends CustomElementTagName = any, InputsGeneric extends PropertyInitMapBase = any, StateInitGeneric extends PropertyInitMapBase = any, EventsInitGeneric extends EventsInitMap = any, HostClassKeys extends string = string, CssVarKeys extends string = string, RenderOutputGeneric = any> = (new () => HostInstanceType<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>) & StaticDeclarativeElementProperties<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric> & {
11
- instanceType: HostInstanceType<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
10
+ export type HostInstanceType<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitMaybeAsyncGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string, RenderOutputGeneric> = RequiredAndNotNullBy<DeclarativeElement<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>, 'shadowRoot'>;
11
+ export type DeclarativeElementDefinition<TagNameGeneric extends CustomElementTagName = any, InputsGeneric extends PropertyInitMapBase = any, StateInitMaybeAsyncGeneric extends PropertyInitMapBase = any, EventsInitGeneric extends EventsInitMap = any, HostClassKeys extends string = string, CssVarKeys extends string = string, RenderOutputGeneric = any> = (new () => HostInstanceType<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>) & StaticDeclarativeElementProperties<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric> & {
12
+ instanceType: HostInstanceType<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
12
13
  };
13
- export declare abstract class DeclarativeElement<TagNameGeneric extends CustomElementTagName = any, InputsGeneric extends PropertyInitMapBase = any, StateInitGeneric extends PropertyInitMapBase = any, EventsInitGeneric extends EventsInitMap = any, HostClassKeys extends string = string, CssVarKeys extends string = string, RenderOutputGeneric = any> extends LitElement {
14
+ export declare abstract class DeclarativeElement<TagNameGeneric extends CustomElementTagName = any, InputsGeneric extends PropertyInitMapBase = any, StateInitMaybeAsyncGeneric extends PropertyInitMapBase = any, EventsInitGeneric extends EventsInitMap = any, HostClassKeys extends string = string, CssVarKeys extends string = string, RenderOutputGeneric = any> extends LitElement {
14
15
  static readonly tagName: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string, unknown>['tagName'];
15
16
  static readonly styles: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string, unknown>['styles'];
16
17
  static readonly isStrictInstance: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string, unknown>['isStrictInstance'];
@@ -24,22 +25,23 @@ export declare abstract class DeclarativeElement<TagNameGeneric extends CustomEl
24
25
  static readonly cssVarNames: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string, unknown>['cssVarNames'];
25
26
  static readonly cssVarValues: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string, unknown>['cssVarValues'];
26
27
  abstract render(): unknown;
27
- abstract readonly instanceState: StateInitGeneric;
28
+ abstract readonly instanceState: MaybeAsyncStateToSync<StateInitMaybeAsyncGeneric>;
29
+ abstract readonly asyncStateHandlerMap: AsyncStateHandlerMap<StateInitMaybeAsyncGeneric>;
28
30
  abstract readonly instanceInputs: InputsGeneric;
29
31
  abstract assignInputs(inputs: InputsGeneric): void;
30
32
  abstract haveInputsBeenSet: boolean;
31
33
  abstract markInputsAsHavingBeenSet(): void;
32
- abstract readonly definition: DeclarativeElementDefinition<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
34
+ abstract readonly definition: DeclarativeElementDefinition<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
33
35
  }
34
- export interface StaticDeclarativeElementProperties<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string, RenderOutputGeneric> {
36
+ export interface StaticDeclarativeElementProperties<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitMaybeAsyncGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string, RenderOutputGeneric> {
35
37
  /** Pass through the render callback for direct unit testability */
36
- readonly renderCallback: RenderCallback<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
38
+ readonly renderCallback: RenderCallback<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
37
39
  events: EventDescriptorMap<EventsInitGeneric>;
38
- stateInit: ElementPropertyDescriptorMap<StateInitGeneric>;
39
- init: RequiredBy<DeclarativeElementInit<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>, 'stateInit' | 'events'>;
40
+ stateInit: ElementPropertyDescriptorMap<StateInitMaybeAsyncGeneric>;
41
+ init: RequiredBy<DeclarativeElementInit<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>, 'stateInit' | 'events'>;
40
42
  inputsType: InputsGeneric;
41
- stateType: StateInitGeneric;
42
- isStrictInstance: (element: unknown) => element is DeclarativeElement<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
43
+ stateType: MaybeAsyncStateToSync<StateInitMaybeAsyncGeneric>;
44
+ isStrictInstance: (element: unknown) => element is DeclarativeElement<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
43
45
  hostClasses: HostClassNamesMap<string, HostClassKeys>;
44
46
  cssVarNames: CssVarNameOrValueMap<CssVarKeys>;
45
47
  cssVarValues: CssVarNameOrValueMap<CssVarKeys>;
@@ -2,5 +2,5 @@ import { DeclarativeElementDefinition } from './declarative-element';
2
2
  import { CustomElementTagName, DeclarativeElementInit } from './declarative-element-init';
3
3
  import { EventsInitMap } from './properties/element-events';
4
4
  import { PropertyInitMapBase } from './properties/element-properties';
5
- export declare function defineElementNoInputs<TagNameGeneric extends CustomElementTagName = '-', InputsGeneric extends PropertyInitMapBase = {}, StateInitGeneric extends PropertyInitMapBase = {}, EventsInitGeneric extends EventsInitMap = {}, HostClassKeys extends string = '', CssVarKeys extends string = '', RenderOutputGeneric = any>(initInput: DeclarativeElementInit<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>): DeclarativeElementDefinition<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
5
+ export declare function defineElementNoInputs<TagNameGeneric extends CustomElementTagName = '-', InputsGeneric extends PropertyInitMapBase = {}, MaybeAsyncStateInitGeneric extends PropertyInitMapBase = {}, EventsInitGeneric extends EventsInitMap = {}, HostClassKeys extends string = '', CssVarKeys extends string = '', RenderOutputGeneric = any>(initInput: DeclarativeElementInit<TagNameGeneric, InputsGeneric, MaybeAsyncStateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>): DeclarativeElementDefinition<TagNameGeneric, InputsGeneric, MaybeAsyncStateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
6
6
  //# sourceMappingURL=define-element-no-inputs.d.ts.map
@@ -11,6 +11,7 @@ import { IgnoreInputsNotBeenSetBeforeRenderWarningSymbol, defaultDeclarativeElem
11
11
  import { assign } from './directives/assign.directive';
12
12
  import { hasDeclarativeElementParent } from './has-declarative-element-parent';
13
13
  import { assignInputs, markInputsAsHavingBeenSet } from './properties/assign-inputs';
14
+ import { toAsyncStateHandlerMap } from './properties/async-state';
14
15
  import { createCssVarNamesMap, createCssVarValuesMap } from './properties/css-vars';
15
16
  import { createEventDescriptorMap } from './properties/element-events';
16
17
  import { createElementUpdaterProxy } from './properties/element-updater-proxy';
@@ -108,12 +109,24 @@ export function defineElementNoInputs(initInput) {
108
109
  this.haveInputsBeenSet = false;
109
110
  // this is set below in Object.defineProperties
110
111
  this.definition = {};
112
+ this.asyncStateHandlerMap = toAsyncStateHandlerMap(initInput.stateInit);
111
113
  this.instanceInputs = createElementUpdaterProxy(this, false);
112
114
  this.instanceState = createElementUpdaterProxy(this, true);
113
- const stateInit = initInput.stateInit || {};
115
+ const stateInit = initInput.stateInit ||
116
+ {};
114
117
  getObjectTypedKeys(stateInit).forEach((stateKey) => {
115
118
  property()(this, stateKey);
116
- this.instanceState[stateKey] = stateInit[stateKey];
119
+ const asyncStateClassInstance = this.asyncStateHandlerMap[stateKey];
120
+ if (asyncStateClassInstance) {
121
+ this.instanceState[stateKey] = asyncStateClassInstance.getValue();
122
+ asyncStateClassInstance.addSettleListener(() => {
123
+ this[stateKey] =
124
+ asyncStateClassInstance.getValue();
125
+ });
126
+ }
127
+ else {
128
+ this.instanceState[stateKey] = stateInit[stateKey];
129
+ }
117
130
  });
118
131
  this.definition = anonymousClass;
119
132
  }
@@ -0,0 +1,7 @@
1
+ import { UnPromise } from '@augment-vir/common';
2
+ import { AsyncState } from '../properties/async-state';
3
+ export declare function renderAsyncState<T, FallbackResult, ResolutionRenderResult = never, ErrorRenderResult = never>(asyncState: AsyncState<T>, fallback: FallbackResult, resolutionRender: (resolved: UnPromise<T>) => ResolutionRenderResult, errorRender: (error: Error) => ErrorRenderResult): FallbackResult | ResolutionRenderResult | ErrorRenderResult;
4
+ export declare function renderAsyncState<T, FallbackResult, ResolutionRenderResult = never, ErrorRenderResult = never>(asyncState: AsyncState<T>, fallback: FallbackResult, resolutionRender: (resolved: UnPromise<T>) => ResolutionRenderResult, errorRender?: undefined): FallbackResult | ResolutionRenderResult | string;
5
+ export declare function renderAsyncState<T, FallbackResult, ResolutionRenderResult = never, ErrorRenderResult = never>(asyncState: AsyncState<T>, fallback: FallbackResult, resolutionRender: undefined, errorRender: (error: Error) => ErrorRenderResult): FallbackResult | UnPromise<T> | ErrorRenderResult;
6
+ export declare function renderAsyncState<T, FallbackResult, ResolutionRenderResult = never, ErrorRenderResult = never>(asyncState: AsyncState<T>, fallback: FallbackResult, resolutionRender?: undefined, errorRender?: undefined): FallbackResult | UnPromise<T> | string;
7
+ //# sourceMappingURL=render-async-state.directive.d.ts.map
@@ -0,0 +1,22 @@
1
+ import { extractErrorMessage, isPromiseLike } from '@augment-vir/common';
2
+ // full function type
3
+ export function renderAsyncState(asyncState,
4
+ /** This value will be rendered if the async state has not settled yet. */
5
+ fallback, resolutionRender, errorRender) {
6
+ if (asyncState instanceof Error) {
7
+ const errorResult = errorRender
8
+ ? errorRender(asyncState)
9
+ : extractErrorMessage(asyncState);
10
+ return errorResult;
11
+ }
12
+ else if (isPromiseLike(asyncState)) {
13
+ const fallbackResult = fallback;
14
+ return fallbackResult;
15
+ }
16
+ else {
17
+ const resolutionResult = resolutionRender
18
+ ? resolutionRender(asyncState)
19
+ : asyncState;
20
+ return resolutionResult;
21
+ }
22
+ }
@@ -0,0 +1,49 @@
1
+ import { JsonCompatibleValue, UnPromise } from '@augment-vir/common';
2
+ import { Promisable } from 'type-fest';
3
+ import { PickAndBlockOthers } from '../../augments/type';
4
+ import { PropertyInitMapBase } from './element-properties';
5
+ export type AsyncState<ValueGeneric> = Error | Promisable<UnPromise<ValueGeneric>>;
6
+ export declare function isRenderReady<T>(asyncStateInput: AsyncState<T>): asyncStateInput is UnPromise<T>;
7
+ type AllSetValueProperties<ValueGeneric> = {
8
+ /** Set a new value directly without using any promises. */
9
+ resolvedValue: UnPromise<ValueGeneric>;
10
+ createPromise: () => Promise<UnPromise<ValueGeneric>>;
11
+ /**
12
+ * When trigger changes (according to deep equality checking through JSON stringify), the
13
+ * createPromise callback will be called and the element's state will be updated again.
14
+ * Otherwise, the createPromise callback will only be called the first time.
15
+ *
16
+ * Set this to undefined to disabled automatic updating. Meaning, createPromise will only be
17
+ * called the first time.
18
+ */
19
+ trigger: JsonCompatibleValue;
20
+ newPromise: Promise<UnPromise<ValueGeneric>>;
21
+ /** Clear the current value and trigger createPromise to get called again on the next render. */
22
+ forceUpdate: true;
23
+ };
24
+ export type AsyncStateSetValue<ValueGeneric> = PickAndBlockOthers<AllSetValueProperties<ValueGeneric>, 'createPromise' | 'trigger'> | PickAndBlockOthers<AllSetValueProperties<ValueGeneric>, 'newPromise'> | PickAndBlockOthers<AllSetValueProperties<ValueGeneric>, 'forceUpdate'> | PickAndBlockOthers<AllSetValueProperties<ValueGeneric>, 'resolvedValue'>;
25
+ export type MaybeAsyncStateToSync<PropertyMapInit extends PropertyInitMapBase> = {
26
+ [Prop in keyof PropertyMapInit]: PropertyMapInit[Prop] extends AsyncStateHandler<infer ValueGeneric> | AsyncStateInit<infer ValueGeneric> ? AsyncState<ValueGeneric> : PropertyMapInit[Prop];
27
+ };
28
+ export type AsyncStateInputs<PropertyMapInit extends PropertyInitMapBase> = {
29
+ [Prop in keyof PropertyMapInit]: PropertyMapInit[Prop] extends AsyncStateHandler<infer ValueGeneric> | AsyncStateInit<infer ValueGeneric> ? AsyncStateSetValue<ValueGeneric> : PropertyMapInit[Prop];
30
+ };
31
+ export type AsyncStateHandlerMap<OriginalObjectGeneric extends PropertyInitMapBase> = Partial<Record<keyof OriginalObjectGeneric, AsyncStateHandler<any>>>;
32
+ export declare function toAsyncStateHandlerMap(propertyInitMap?: PropertyInitMapBase | undefined): AsyncStateHandlerMap<PropertyInitMapBase>;
33
+ export declare class AsyncStateHandler<ValueGeneric> {
34
+ #private;
35
+ readonly asyncMarkerSymbol: symbol;
36
+ constructor(initialValue: Promise<UnPromise<ValueGeneric>> | undefined);
37
+ setValue(setInputs: AsyncStateSetValue<ValueGeneric>): void;
38
+ getValue(): AsyncState<ValueGeneric>;
39
+ addSettleListener(callback: () => void): void;
40
+ removeSettleListener(callback: (value: AsyncState<ValueGeneric>) => void): void;
41
+ }
42
+ export declare class AsyncStateInit<ValueGeneric> {
43
+ readonly initialValue?: Promise<UnPromise<ValueGeneric>> | undefined;
44
+ constructor(initialValue?: Promise<UnPromise<ValueGeneric>> | undefined);
45
+ readonly asyncMarkerSymbol: symbol;
46
+ }
47
+ export declare function asyncState<ValueGeneric>(initialValue?: Promise<UnPromise<ValueGeneric>> | undefined): AsyncStateInit<ValueGeneric>;
48
+ export {};
49
+ //# sourceMappingURL=async-state.d.ts.map
@@ -0,0 +1,158 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
7
+ if (kind === "m") throw new TypeError("Private method is not writable");
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
+ };
12
+ var _AsyncStateHandler_instances, _AsyncStateHandler_lastTrigger, _AsyncStateHandler_resolutionValue, _AsyncStateHandler_rejectionError, _AsyncStateHandler_listeners, _AsyncStateHandler_lastSetPromise, _AsyncStateHandler_waitingForValuePromise, _AsyncStateHandler_fireListeners, _AsyncStateHandler_setPromise, _AsyncStateHandler_resolveValue;
13
+ import { areJsonEqual, createDeferredPromiseWrapper, ensureError, filterObject, isPromiseLike, mapObjectValues, } from '@augment-vir/common';
14
+ const asyncMarkerSymbol = Symbol('element-vir-async-state-marker');
15
+ export function isRenderReady(asyncStateInput) {
16
+ if (asyncStateInput instanceof Error) {
17
+ return false;
18
+ }
19
+ else if (isPromiseLike(asyncStateInput)) {
20
+ return false;
21
+ }
22
+ else {
23
+ return true;
24
+ }
25
+ }
26
+ export function toAsyncStateHandlerMap(propertyInitMap) {
27
+ if (!propertyInitMap) {
28
+ return {};
29
+ }
30
+ const asyncStateInit = filterObject(propertyInitMap, (key, value) => {
31
+ return value instanceof AsyncStateInit;
32
+ });
33
+ const asyncStateHandlers = mapObjectValues(asyncStateInit, (key, value) => {
34
+ return new AsyncStateHandler(value.initialValue);
35
+ });
36
+ return asyncStateHandlers;
37
+ }
38
+ const notSetSymbol = Symbol('not set');
39
+ export class AsyncStateHandler {
40
+ constructor(initialValue) {
41
+ _AsyncStateHandler_instances.add(this);
42
+ _AsyncStateHandler_lastTrigger.set(this, notSetSymbol);
43
+ _AsyncStateHandler_resolutionValue.set(this, void 0);
44
+ _AsyncStateHandler_rejectionError.set(this, void 0);
45
+ _AsyncStateHandler_listeners.set(this, []);
46
+ _AsyncStateHandler_lastSetPromise.set(this, void 0);
47
+ _AsyncStateHandler_waitingForValuePromise.set(this, createDeferredPromiseWrapper());
48
+ this.asyncMarkerSymbol = asyncMarkerSymbol;
49
+ if (initialValue) {
50
+ this.setValue({ newPromise: initialValue });
51
+ }
52
+ }
53
+ setValue(setInputs) {
54
+ if ('createPromise' in setInputs) {
55
+ if (__classPrivateFieldGet(this, _AsyncStateHandler_lastTrigger, "f") === notSetSymbol ||
56
+ !areJsonEqual(setInputs.trigger, __classPrivateFieldGet(this, _AsyncStateHandler_lastTrigger, "f"))) {
57
+ __classPrivateFieldSet(this, _AsyncStateHandler_lastTrigger, setInputs.trigger, "f");
58
+ const newValue = setInputs.createPromise();
59
+ __classPrivateFieldGet(this, _AsyncStateHandler_instances, "m", _AsyncStateHandler_setPromise).call(this, newValue);
60
+ }
61
+ }
62
+ else if ('newPromise' in setInputs) {
63
+ __classPrivateFieldGet(this, _AsyncStateHandler_lastTrigger, "f") === notSetSymbol;
64
+ __classPrivateFieldGet(this, _AsyncStateHandler_instances, "m", _AsyncStateHandler_setPromise).call(this, setInputs.newPromise);
65
+ // force a re-render
66
+ __classPrivateFieldGet(this, _AsyncStateHandler_instances, "m", _AsyncStateHandler_fireListeners).call(this);
67
+ }
68
+ else if ('resolvedValue' in setInputs) {
69
+ __classPrivateFieldGet(this, _AsyncStateHandler_instances, "m", _AsyncStateHandler_resolveValue).call(this, setInputs.resolvedValue);
70
+ }
71
+ else {
72
+ if (setInputs.forceUpdate) {
73
+ __classPrivateFieldSet(this, _AsyncStateHandler_lastTrigger, notSetSymbol, "f");
74
+ __classPrivateFieldSet(this, _AsyncStateHandler_resolutionValue, undefined, "f");
75
+ if (!__classPrivateFieldGet(this, _AsyncStateHandler_waitingForValuePromise, "f").isSettled()) {
76
+ __classPrivateFieldGet(this, _AsyncStateHandler_waitingForValuePromise, "f").reject('Canceled by force update');
77
+ }
78
+ __classPrivateFieldSet(this, _AsyncStateHandler_waitingForValuePromise, createDeferredPromiseWrapper(), "f");
79
+ // force a re-render
80
+ __classPrivateFieldGet(this, _AsyncStateHandler_instances, "m", _AsyncStateHandler_fireListeners).call(this);
81
+ }
82
+ }
83
+ }
84
+ getValue() {
85
+ if (__classPrivateFieldGet(this, _AsyncStateHandler_waitingForValuePromise, "f").isSettled()) {
86
+ if (__classPrivateFieldGet(this, _AsyncStateHandler_rejectionError, "f")) {
87
+ return __classPrivateFieldGet(this, _AsyncStateHandler_rejectionError, "f");
88
+ }
89
+ else
90
+ return __classPrivateFieldGet(this, _AsyncStateHandler_resolutionValue, "f");
91
+ }
92
+ else {
93
+ return __classPrivateFieldGet(this, _AsyncStateHandler_waitingForValuePromise, "f").promise;
94
+ }
95
+ }
96
+ addSettleListener(callback) {
97
+ __classPrivateFieldGet(this, _AsyncStateHandler_listeners, "f").push(callback);
98
+ }
99
+ removeSettleListener(callback) {
100
+ __classPrivateFieldSet(this, _AsyncStateHandler_listeners, __classPrivateFieldGet(this, _AsyncStateHandler_listeners, "f").filter((listener) => listener !== callback), "f");
101
+ }
102
+ }
103
+ _AsyncStateHandler_lastTrigger = new WeakMap(), _AsyncStateHandler_resolutionValue = new WeakMap(), _AsyncStateHandler_rejectionError = new WeakMap(), _AsyncStateHandler_listeners = new WeakMap(), _AsyncStateHandler_lastSetPromise = new WeakMap(), _AsyncStateHandler_waitingForValuePromise = new WeakMap(), _AsyncStateHandler_instances = new WeakSet(), _AsyncStateHandler_fireListeners = function _AsyncStateHandler_fireListeners() {
104
+ __classPrivateFieldGet(this, _AsyncStateHandler_listeners, "f").forEach((listener) => {
105
+ listener();
106
+ });
107
+ }, _AsyncStateHandler_setPromise = function _AsyncStateHandler_setPromise(newPromise) {
108
+ if (newPromise === __classPrivateFieldGet(this, _AsyncStateHandler_lastSetPromise, "f")) {
109
+ // abort setting the promise if we already have set this promise
110
+ return;
111
+ }
112
+ __classPrivateFieldSet(this, _AsyncStateHandler_resolutionValue, undefined, "f");
113
+ __classPrivateFieldSet(this, _AsyncStateHandler_rejectionError, undefined, "f");
114
+ __classPrivateFieldSet(this, _AsyncStateHandler_lastSetPromise, newPromise, "f");
115
+ if (__classPrivateFieldGet(this, _AsyncStateHandler_waitingForValuePromise, "f").isSettled()) {
116
+ __classPrivateFieldSet(this, _AsyncStateHandler_waitingForValuePromise, createDeferredPromiseWrapper(), "f");
117
+ }
118
+ newPromise
119
+ .then((value) => {
120
+ // make sure we're still actually waiting for this promise
121
+ if (__classPrivateFieldGet(this, _AsyncStateHandler_lastSetPromise, "f") === newPromise) {
122
+ __classPrivateFieldGet(this, _AsyncStateHandler_instances, "m", _AsyncStateHandler_resolveValue).call(this, value);
123
+ }
124
+ })
125
+ .catch((reason) => {
126
+ // make sure we're still actually waiting for this promise
127
+ if (__classPrivateFieldGet(this, _AsyncStateHandler_lastSetPromise, "f") === newPromise) {
128
+ __classPrivateFieldSet(this, _AsyncStateHandler_rejectionError, ensureError(reason), "f");
129
+ __classPrivateFieldGet(this, _AsyncStateHandler_waitingForValuePromise, "f").promise.catch(() => {
130
+ /**
131
+ * Don't actually do anything, we just want to make sure the error is
132
+ * handled so it doesn't throw errors in the browser.
133
+ */
134
+ });
135
+ __classPrivateFieldGet(this, _AsyncStateHandler_waitingForValuePromise, "f").reject(reason);
136
+ __classPrivateFieldGet(this, _AsyncStateHandler_instances, "m", _AsyncStateHandler_fireListeners).call(this);
137
+ }
138
+ });
139
+ }, _AsyncStateHandler_resolveValue = function _AsyncStateHandler_resolveValue(value) {
140
+ if (value !== __classPrivateFieldGet(this, _AsyncStateHandler_resolutionValue, "f")) {
141
+ __classPrivateFieldSet(this, _AsyncStateHandler_rejectionError, undefined, "f");
142
+ __classPrivateFieldSet(this, _AsyncStateHandler_resolutionValue, value, "f");
143
+ if (__classPrivateFieldGet(this, _AsyncStateHandler_waitingForValuePromise, "f").isSettled()) {
144
+ __classPrivateFieldSet(this, _AsyncStateHandler_waitingForValuePromise, createDeferredPromiseWrapper(), "f");
145
+ }
146
+ __classPrivateFieldGet(this, _AsyncStateHandler_waitingForValuePromise, "f").resolve(value);
147
+ __classPrivateFieldGet(this, _AsyncStateHandler_instances, "m", _AsyncStateHandler_fireListeners).call(this);
148
+ }
149
+ };
150
+ export class AsyncStateInit {
151
+ constructor(initialValue) {
152
+ this.initialValue = initialValue;
153
+ this.asyncMarkerSymbol = asyncMarkerSymbol;
154
+ }
155
+ }
156
+ export function asyncState(initialValue) {
157
+ return new AsyncStateInit(initialValue);
158
+ }
@@ -17,7 +17,13 @@ export function createElementUpdaterProxy(element, verifyExists) {
17
17
  if (verifyExists) {
18
18
  assertValidPropertyName(propertyName, element, element.tagName);
19
19
  }
20
- return elementAsProps[propertyName];
20
+ const asyncState = element.asyncStateHandlerMap[propertyName];
21
+ if (asyncState) {
22
+ return asyncState.getValue();
23
+ }
24
+ else {
25
+ return elementAsProps[propertyName];
26
+ }
21
27
  }
22
28
  const propsProxy = new Proxy({}, {
23
29
  get: valueGetter,
@@ -31,7 +37,13 @@ export function createElementUpdaterProxy(element, verifyExists) {
31
37
  * "getOwnPropertyDescriptor".
32
38
  */
33
39
  target[propertyName] = undefined;
34
- elementAsProps[propertyName] = newValue;
40
+ const asyncState = element.asyncStateHandlerMap[propertyName];
41
+ if (asyncState) {
42
+ asyncState.setValue(newValue);
43
+ }
44
+ else {
45
+ elementAsProps[propertyName] = newValue;
46
+ }
35
47
  return true;
36
48
  },
37
49
  ownKeys: (target) => {
@@ -1,13 +1,14 @@
1
1
  import { TypedEvent } from '../typed-event/typed-event';
2
2
  import { DeclarativeElement, HostInstanceType } from './declarative-element';
3
3
  import { CustomElementTagName } from './declarative-element-init';
4
+ import { AsyncStateInputs, MaybeAsyncStateToSync } from './properties/async-state';
4
5
  import { EventDescriptorMap, EventInitMapEventDetailExtractor, EventsInitMap } from './properties/element-events';
5
6
  import { PropertyInitMapBase } from './properties/element-properties';
6
7
  export type RenderCallback<TagNameGeneric extends CustomElementTagName = any, InputsGeneric extends PropertyInitMapBase = any, StateGeneric extends PropertyInitMapBase = any, EventsInitGeneric extends EventsInitMap = any, HostClassKeys extends string = any, CssVarKeys extends string = any, RenderOutputGeneric = any> = (params: RenderParams<TagNameGeneric, InputsGeneric, StateGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>) => RenderOutputGeneric;
7
8
  export type InitCallback<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string, RenderOutputGeneric> = (params: RenderParams<TagNameGeneric, InputsGeneric, StateGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>) => void;
8
- export type UpdateStateCallback<StateGeneric extends PropertyInitMapBase> = (newState: Partial<StateGeneric>) => void;
9
+ export type UpdateStateCallback<StateGeneric extends PropertyInitMapBase> = (newState: Partial<AsyncStateInputs<StateGeneric>>) => void;
9
10
  export type RenderParams<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string, RenderOutputGeneric> = {
10
- state: Readonly<StateInitGeneric>;
11
+ state: Readonly<MaybeAsyncStateToSync<StateInitGeneric>>;
11
12
  updateState: UpdateStateCallback<StateInitGeneric>;
12
13
  events: EventDescriptorMap<EventsInitGeneric>;
13
14
  host: HostInstanceType<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
@@ -3,7 +3,13 @@ export function createRenderParams(element, eventsMap) {
3
3
  function updateState(newStatePartial) {
4
4
  getObjectTypedKeys(newStatePartial).forEach((stateKey) => {
5
5
  const newValue = newStatePartial[stateKey];
6
- element.instanceState[stateKey] = newValue;
6
+ const asyncState = element.asyncStateHandlerMap[stateKey];
7
+ if (asyncState) {
8
+ asyncState.setValue(newValue);
9
+ }
10
+ else {
11
+ element.instanceState[stateKey] = newValue;
12
+ }
7
13
  });
8
14
  }
9
15
  const renderParams = {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- export * from '@electrovir/cached-promise';
2
1
  export * from './built-in-lit-directives';
3
2
  export * from './declarative-element/declarative-element';
4
3
  export * from './declarative-element/declarative-element-init';
@@ -11,8 +10,9 @@ export * from './declarative-element/directives/directive-helpers';
11
10
  export * from './declarative-element/directives/listen.directive';
12
11
  export * from './declarative-element/directives/on-dom-created.directive';
13
12
  export * from './declarative-element/directives/on-resize.directive';
13
+ export * from './declarative-element/directives/render-async-state.directive';
14
14
  export * from './declarative-element/directives/render-if.directive';
15
- export * from './declarative-element/directives/render-promise.directive';
15
+ export * from './declarative-element/properties/async-state';
16
16
  export * from './declarative-element/properties/css-vars';
17
17
  export * from './declarative-element/properties/element-events';
18
18
  export * from './declarative-element/properties/element-properties';
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
- export * from '@electrovir/cached-promise';
2
1
  export * from './built-in-lit-directives';
3
2
  export * from './declarative-element/declarative-element';
4
3
  export * from './declarative-element/declarative-element-init';
@@ -10,8 +9,9 @@ export * from './declarative-element/directives/directive-helpers';
10
9
  export * from './declarative-element/directives/listen.directive';
11
10
  export * from './declarative-element/directives/on-dom-created.directive';
12
11
  export * from './declarative-element/directives/on-resize.directive';
12
+ export * from './declarative-element/directives/render-async-state.directive';
13
13
  export * from './declarative-element/directives/render-if.directive';
14
- export * from './declarative-element/directives/render-promise.directive';
14
+ export * from './declarative-element/properties/async-state';
15
15
  export * from './declarative-element/properties/css-vars';
16
16
  export * from './declarative-element/properties/element-events';
17
17
  export * from './declarative-element/properties/element-properties';
@@ -1,8 +1,8 @@
1
1
  import { CSSResultGroup } from 'lit';
2
- import { DeclarativeElementDefinition } from '../../declarative-element/declarative-element';
2
+ import { ConstructorWithTagName } from '../has-static-tag-name';
3
3
  export type CssTemplateTransform = {
4
4
  templateStrings: TemplateStringsArray;
5
5
  valueIndexDeletions: number[];
6
6
  };
7
- export declare function transformCssTemplate(inputTemplateStrings: TemplateStringsArray, inputValues: (number | CSSResultGroup | DeclarativeElementDefinition)[]): CssTemplateTransform;
7
+ export declare function transformCssTemplate(inputTemplateStrings: TemplateStringsArray, inputValues: (number | CSSResultGroup | ConstructorWithTagName)[]): CssTemplateTransform;
8
8
  //# sourceMappingURL=css-transform.d.ts.map
@@ -1,4 +1,4 @@
1
1
  import { CSSResult, CSSResultGroup } from 'lit';
2
- import { DeclarativeElementDefinition } from '../../declarative-element/declarative-element';
3
- export declare function css(inputTemplateStrings: TemplateStringsArray, ...inputValues: (number | CSSResultGroup | DeclarativeElementDefinition)[]): CSSResult;
2
+ import { ConstructorWithTagName } from '../has-static-tag-name';
3
+ export declare function css(inputTemplateStrings: TemplateStringsArray, ...inputValues: (number | CSSResultGroup | ConstructorWithTagName)[]): CSSResult;
4
4
  //# sourceMappingURL=vir-css.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "element-vir",
3
- "version": "10.2.2",
3
+ "version": "11.0.0",
4
4
  "keywords": [
5
5
  "custom",
6
6
  "web",
@@ -41,7 +41,6 @@
41
41
  "dependencies": {
42
42
  "@augment-vir/browser": "^13.2.1",
43
43
  "@augment-vir/common": "^13.2.1",
44
- "@electrovir/cached-promise": "^0.0.1",
45
44
  "lit": "2.7.0"
46
45
  },
47
46
  "devDependencies": {
@@ -70,7 +69,7 @@
70
69
  "prettier-plugin-sort-json": "^1.0.0",
71
70
  "prettier-plugin-toml": "^0.3.1",
72
71
  "ts-node": "^10.9.1",
73
- "type-fest": "^3.7.0",
72
+ "type-fest": "^3.7.1",
74
73
  "typescript": "^5.0.2",
75
74
  "virmator": "^6.2.2",
76
75
  "vite": "^4.2.1"
@@ -1,16 +0,0 @@
1
- import { CachedPromise, GetCachedPromiseInput } from '@electrovir/cached-promise';
2
- import { RequireExactlyOne } from 'type-fest';
3
- import { RequireNonVoidReturn } from '../../augments/type';
4
- export type RenderPromiseInput<ValueType> = RequireExactlyOne<{
5
- promise: Promise<ValueType>;
6
- resolved: ValueType;
7
- error: Error;
8
- }>;
9
- export type RenderPromiseRenderer<ValueType, RenderOutput> = RequireNonVoidReturn<RenderOutput, (input: RenderPromiseInput<ValueType>) => RenderOutput>;
10
- export declare function renderPromise<ValueType, RenderOutput>(maybePromise: Promise<ValueType> | ValueType, renderer: RenderPromiseRenderer<ValueType, RenderOutput>): RenderOutput | import("lit-html/directive").DirectiveResult<typeof import("lit-html/directives/until").UntilDirective>;
11
- export type RenderCachedPromiseInputs<ValueType, RenderOutput> = {
12
- cachedPromise: CachedPromise<ValueType>;
13
- render: RenderPromiseRenderer<ValueType, RenderOutput>;
14
- } & GetCachedPromiseInput<ValueType>;
15
- export declare function renderCachedPromise<ValueType, RenderOutput>({ cachedPromise, render, triggers, createPromise, }: RenderCachedPromiseInputs<ValueType, RenderOutput>): import("lit-html/directive").DirectiveResult<typeof import("lit-html/directives/until").UntilDirective> | RenderOutput;
16
- //# sourceMappingURL=render-promise.directive.d.ts.map
@@ -1,30 +0,0 @@
1
- import { ensureError } from '@augment-vir/common';
2
- import { until } from 'lit/directives/until.js';
3
- export function renderPromise(maybePromise, renderer) {
4
- if (typeof renderer === 'string') {
5
- throw new Error(`Cannot pass string renderer`);
6
- }
7
- if (maybePromise instanceof Promise) {
8
- return until(maybePromise
9
- .catch((error) => {
10
- return ensureError(error);
11
- })
12
- .then((resolved) => {
13
- if (resolved instanceof Error) {
14
- return renderer({ error: resolved });
15
- }
16
- else {
17
- return renderer({ resolved });
18
- }
19
- }), renderer({ promise: maybePromise }));
20
- }
21
- else {
22
- return renderer({ resolved: maybePromise });
23
- }
24
- }
25
- export function renderCachedPromise({ cachedPromise, render, triggers, createPromise, }) {
26
- return renderPromise(cachedPromise.get({
27
- createPromise,
28
- triggers,
29
- }), render);
30
- }