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 +68 -30
- package/dist/declarative-element/declarative-element-init.d.ts +7 -6
- package/dist/declarative-element/declarative-element.d.ts +14 -12
- package/dist/declarative-element/define-element-no-inputs.d.ts +1 -1
- package/dist/declarative-element/define-element-no-inputs.js +15 -2
- package/dist/declarative-element/directives/render-async-state.directive.d.ts +7 -0
- package/dist/declarative-element/directives/render-async-state.directive.js +22 -0
- package/dist/declarative-element/properties/async-state.d.ts +49 -0
- package/dist/declarative-element/properties/async-state.js +158 -0
- package/dist/declarative-element/properties/element-updater-proxy.js +14 -2
- package/dist/declarative-element/render-callback.d.ts +3 -2
- package/dist/declarative-element/render-callback.js +7 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/template-transforms/vir-css/css-transform.d.ts +2 -2
- package/dist/template-transforms/vir-css/vir-css.d.ts +2 -2
- package/package.json +2 -3
- package/dist/declarative-element/directives/render-promise.directive.d.ts +0 -16
- package/dist/declarative-element/directives/render-promise.directive.js +0 -30
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,
|
|
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?:
|
|
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,
|
|
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,
|
|
42
|
-
renderCallback: RequireNonVoidReturn<RenderOutputGeneric, RenderCallback<TagNameGeneric, InputsGeneric,
|
|
43
|
-
cleanupCallback?: InitCallback<TagNameGeneric, InputsGeneric,
|
|
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,
|
|
10
|
-
export type DeclarativeElementDefinition<TagNameGeneric extends CustomElementTagName = any, InputsGeneric extends PropertyInitMapBase = any,
|
|
11
|
-
instanceType: HostInstanceType<TagNameGeneric, InputsGeneric,
|
|
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,
|
|
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:
|
|
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,
|
|
34
|
+
abstract readonly definition: DeclarativeElementDefinition<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
|
|
33
35
|
}
|
|
34
|
-
export interface StaticDeclarativeElementProperties<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase,
|
|
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,
|
|
38
|
+
readonly renderCallback: RenderCallback<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
|
|
37
39
|
events: EventDescriptorMap<EventsInitGeneric>;
|
|
38
|
-
stateInit: ElementPropertyDescriptorMap<
|
|
39
|
-
init: RequiredBy<DeclarativeElementInit<TagNameGeneric, InputsGeneric,
|
|
40
|
+
stateInit: ElementPropertyDescriptorMap<StateInitMaybeAsyncGeneric>;
|
|
41
|
+
init: RequiredBy<DeclarativeElementInit<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>, 'stateInit' | 'events'>;
|
|
40
42
|
inputsType: InputsGeneric;
|
|
41
|
-
stateType:
|
|
42
|
-
isStrictInstance: (element: unknown) => element is DeclarativeElement<TagNameGeneric, InputsGeneric,
|
|
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 = {},
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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/
|
|
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/
|
|
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 {
|
|
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 |
|
|
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 {
|
|
3
|
-
export declare function css(inputTemplateStrings: TemplateStringsArray, ...inputValues: (number | CSSResultGroup |
|
|
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": "
|
|
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.
|
|
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
|
-
}
|