element-vir 9.2.2 → 10.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.
Files changed (29) hide show
  1. package/README.md +30 -68
  2. package/dist/built-in-lit-directives.d.ts +21 -0
  3. package/dist/built-in-lit-directives.js +20 -0
  4. package/dist/declarative-element/declarative-element-init.d.ts +6 -7
  5. package/dist/declarative-element/declarative-element.d.ts +12 -14
  6. package/dist/declarative-element/define-element-no-inputs.d.ts +1 -1
  7. package/dist/declarative-element/define-element-no-inputs.js +37 -38
  8. package/dist/declarative-element/directives/assign.directive.d.ts +2 -2
  9. package/dist/declarative-element/directives/listen.directive.js +1 -1
  10. package/dist/declarative-element/directives/on-resize.directive.js +1 -2
  11. package/dist/declarative-element/directives/render-if.directive.d.ts +1 -1
  12. package/dist/declarative-element/directives/render-if.directive.js +1 -0
  13. package/dist/declarative-element/directives/render-promise.directive.d.ts +15 -0
  14. package/dist/declarative-element/directives/render-promise.directive.js +27 -0
  15. package/dist/declarative-element/properties/element-updater-proxy.js +2 -14
  16. package/dist/declarative-element/properties/styles.d.ts +1 -1
  17. package/dist/declarative-element/render-callback.d.ts +2 -3
  18. package/dist/declarative-element/render-callback.js +1 -7
  19. package/dist/declarative-element/wrap-define-element.js +2 -3
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +2 -2
  22. package/dist/template-transforms/nested-mapped-templates.js +3 -5
  23. package/dist/template-transforms/transform-template.js +3 -4
  24. package/dist/template-transforms/vir-html/html-transform.js +1 -1
  25. package/package.json +15 -13
  26. package/dist/declarative-element/directives/render-async-state.directive.d.ts +0 -7
  27. package/dist/declarative-element/directives/render-async-state.directive.js +0 -22
  28. package/dist/declarative-element/properties/async-state.d.ts +0 -49
  29. package/dist/declarative-element/properties/async-state.js +0 -158
package/README.md CHANGED
@@ -200,6 +200,36 @@ 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
+
203
233
  ## Other callbacks
204
234
 
205
235
  There are two other callbacks you can define that are sort of similar to lifecycle callbacks. They are much simpler than lifecycle callbacks however.
@@ -594,74 +624,6 @@ export const MyWithRenderIfElement = defineElement<{shouldRender: boolean}>()({
594
624
  });
595
625
  ```
596
626
 
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
-
665
627
  ## Require all child custom elements to be declarative elements
666
628
 
667
629
  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).
@@ -0,0 +1,21 @@
1
+ export * from 'lit/directives/async-append.js';
2
+ export * from 'lit/directives/async-replace.js';
3
+ export * from 'lit/directives/cache.js';
4
+ export * from 'lit/directives/choose.js';
5
+ export * from 'lit/directives/class-map.js';
6
+ export * from 'lit/directives/guard.js';
7
+ export * from 'lit/directives/if-defined.js';
8
+ export * from 'lit/directives/join.js';
9
+ export * from 'lit/directives/keyed.js';
10
+ export * from 'lit/directives/live.js';
11
+ export * from 'lit/directives/map.js';
12
+ export * from 'lit/directives/range.js';
13
+ export * from 'lit/directives/ref.js';
14
+ export * from 'lit/directives/repeat.js';
15
+ export * from 'lit/directives/style-map.js';
16
+ export * from 'lit/directives/template-content.js';
17
+ export * from 'lit/directives/unsafe-html.js';
18
+ export * from 'lit/directives/unsafe-svg.js';
19
+ export * from 'lit/directives/until.js';
20
+ export * from 'lit/directives/when.js';
21
+ //# sourceMappingURL=built-in-lit-directives.d.ts.map
@@ -0,0 +1,20 @@
1
+ export * from 'lit/directives/async-append.js';
2
+ export * from 'lit/directives/async-replace.js';
3
+ export * from 'lit/directives/cache.js';
4
+ export * from 'lit/directives/choose.js';
5
+ export * from 'lit/directives/class-map.js';
6
+ export * from 'lit/directives/guard.js';
7
+ export * from 'lit/directives/if-defined.js';
8
+ export * from 'lit/directives/join.js';
9
+ export * from 'lit/directives/keyed.js';
10
+ export * from 'lit/directives/live.js';
11
+ export * from 'lit/directives/map.js';
12
+ export * from 'lit/directives/range.js';
13
+ export * from 'lit/directives/ref.js';
14
+ export * from 'lit/directives/repeat.js';
15
+ export * from 'lit/directives/style-map.js';
16
+ export * from 'lit/directives/template-content.js';
17
+ export * from 'lit/directives/unsafe-html.js';
18
+ export * from 'lit/directives/unsafe-svg.js';
19
+ export * from 'lit/directives/until.js';
20
+ export * from 'lit/directives/when.js';
@@ -1,6 +1,5 @@
1
1
  import { CSSResult } from 'lit';
2
2
  import { DeclarativeElementDefinitionOptions } from './definition-options';
3
- import { MaybeAsyncStateToSync } from './properties/async-state';
4
3
  import { CssVarsInitMap } from './properties/css-vars';
5
4
  import { EventsInitMap } from './properties/element-events';
6
5
  import { PropertyInitMapBase } from './properties/element-properties';
@@ -8,7 +7,7 @@ import { HostClassesInitMap } from './properties/host-classes';
8
7
  import { StylesCallback } from './properties/styles';
9
8
  import { InitCallback, RenderCallback } from './render-callback';
10
9
  export type CustomElementTagName = `${string}-${string}`;
11
- export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitMaybeAsyncGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeysGeneric extends string, CssVarKeysGeneric extends string> = {
10
+ export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeysGeneric extends string, CssVarKeysGeneric extends string> = {
12
11
  /**
13
12
  * HTML tag name. This should not be used directly, as interpolating it with the html tagged
14
13
  * template from this package is preferred.
@@ -17,7 +16,7 @@ export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName,
17
16
  /** Static styles. These should not and cannot change. */
18
17
  styles?: CSSResult | StylesCallback<HostClassKeysGeneric, CssVarKeysGeneric>;
19
18
  /** Element properties. (These can be thought of as "inputs".) */
20
- stateInit?: StateInitMaybeAsyncGeneric;
19
+ stateInit?: StateInitGeneric;
21
20
  /** Events that the element can dispatch. (These can be thought of as "outputs".) */
22
21
  events?: EventsInitGeneric;
23
22
  /**
@@ -25,7 +24,7 @@ export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName,
25
24
  * based on current instance state or inputs, or just undefined to indicate that the host class
26
25
  * will only be manually set.
27
26
  */
28
- hostClasses?: HostClassesInitMap<HostClassKeysGeneric, InputsGeneric, MaybeAsyncStateToSync<StateInitMaybeAsyncGeneric>>;
27
+ hostClasses?: HostClassesInitMap<HostClassKeysGeneric, InputsGeneric, StateInitGeneric>;
29
28
  /**
30
29
  * CSS Vars for the component. Keys of this object should be camelCased (or whatever your casing
31
30
  * convention is). They will be transformed, at runtime, to CSS vars with kebab-casing, to match
@@ -38,9 +37,9 @@ export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName,
38
37
  */
39
38
  cssVars?: CssVarsInitMap<CssVarKeysGeneric>;
40
39
  /** Called as part of the first renderCallback call, before the first renderCallback call. */
41
- initCallback?: InitCallback<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric>;
42
- renderCallback: RenderCallback<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric>;
43
- cleanupCallback?: InitCallback<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric>;
40
+ initCallback?: InitCallback<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric>;
41
+ renderCallback: RenderCallback<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric>;
42
+ cleanupCallback?: InitCallback<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric>;
44
43
  options?: Partial<DeclarativeElementDefinitionOptions> | undefined;
45
44
  };
46
45
  //# sourceMappingURL=declarative-element-init.d.ts.map
@@ -1,17 +1,16 @@
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';
5
4
  import { CssVarNameOrValueMap } from './properties/css-vars';
6
5
  import { EventDescriptorMap, EventsInitMap } from './properties/element-events';
7
6
  import { ElementPropertyDescriptorMap, PropertyInitMapBase } from './properties/element-properties';
8
7
  import { HostClassNamesMap } from './properties/host-classes';
9
8
  import { RenderCallback, RenderOutput } from './render-callback';
10
- export type HostInstanceType<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitMaybeAsyncGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string> = RequiredAndNotNullBy<DeclarativeElement<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>, '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> = (new () => HostInstanceType<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>) & StaticDeclarativeElementProperties<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys> & {
12
- instanceType: HostInstanceType<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
9
+ export type HostInstanceType<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string> = RequiredAndNotNullBy<DeclarativeElement<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>, '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> = (new () => HostInstanceType<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>) & StaticDeclarativeElementProperties<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys> & {
11
+ instanceType: HostInstanceType<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
13
12
  };
14
- export declare abstract class DeclarativeElement<TagNameGeneric extends CustomElementTagName = CustomElementTagName, InputsGeneric extends PropertyInitMapBase = any, StateInitMaybeAsyncGeneric extends PropertyInitMapBase = any, EventsInitGeneric extends EventsInitMap = any, HostClassKeys extends string = string, CssVarKeys extends string = string> extends LitElement {
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> extends LitElement {
15
14
  static readonly tagName: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string>['tagName'];
16
15
  static readonly styles: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string>['styles'];
17
16
  static readonly isStrictInstance: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string>['isStrictInstance'];
@@ -25,23 +24,22 @@ export declare abstract class DeclarativeElement<TagNameGeneric extends CustomEl
25
24
  static readonly cssVarNames: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string>['cssVarNames'];
26
25
  static readonly cssVarValues: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string>['cssVarValues'];
27
26
  abstract render(): RenderOutput;
28
- abstract readonly instanceState: MaybeAsyncStateToSync<StateInitMaybeAsyncGeneric>;
29
- abstract readonly asyncStateHandlerMap: AsyncStateHandlerMap<StateInitMaybeAsyncGeneric>;
27
+ abstract readonly instanceState: StateInitGeneric;
30
28
  abstract readonly instanceInputs: InputsGeneric;
31
29
  abstract assignInputs(inputs: InputsGeneric): void;
32
30
  abstract readonly haveInputsBeenSet: boolean;
33
31
  abstract markInputsAsHavingBeenSet(): void;
34
- abstract readonly definition: DeclarativeElementDefinition<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
32
+ abstract readonly definition: DeclarativeElementDefinition<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
35
33
  }
36
- export interface StaticDeclarativeElementProperties<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitMaybeAsyncGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string> {
34
+ export interface StaticDeclarativeElementProperties<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string> {
37
35
  /** Pass through the render callback for direct unit testability */
38
- readonly renderCallback: RenderCallback<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
36
+ readonly renderCallback: RenderCallback<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
39
37
  events: EventDescriptorMap<EventsInitGeneric>;
40
- stateInit: ElementPropertyDescriptorMap<StateInitMaybeAsyncGeneric>;
41
- init: RequiredBy<DeclarativeElementInit<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>, 'stateInit' | 'events'>;
38
+ stateInit: ElementPropertyDescriptorMap<StateInitGeneric>;
39
+ init: RequiredBy<DeclarativeElementInit<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>, 'stateInit' | 'events'>;
42
40
  inputsType: InputsGeneric;
43
- stateType: MaybeAsyncStateToSync<StateInitMaybeAsyncGeneric>;
44
- isStrictInstance: (element: unknown) => element is DeclarativeElement<TagNameGeneric, InputsGeneric, StateInitMaybeAsyncGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
41
+ stateType: StateInitGeneric;
42
+ isStrictInstance: (element: unknown) => element is DeclarativeElement<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
45
43
  hostClasses: HostClassNamesMap<string, HostClassKeys>;
46
44
  cssVarNames: CssVarNameOrValueMap<CssVarKeys>;
47
45
  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 = {}, MaybeAsyncStateInitGeneric extends PropertyInitMapBase = {}, EventsInitGeneric extends EventsInitMap = {}, HostClassKeys extends string = '', CssVarKeys extends string = ''>(initInput: DeclarativeElementInit<TagNameGeneric, InputsGeneric, MaybeAsyncStateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>): DeclarativeElementDefinition<TagNameGeneric, InputsGeneric, MaybeAsyncStateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
5
+ export declare function defineElementNoInputs<TagNameGeneric extends CustomElementTagName = '-', InputsGeneric extends PropertyInitMapBase = {}, StateInitGeneric extends PropertyInitMapBase = {}, EventsInitGeneric extends EventsInitMap = {}, HostClassKeys extends string = '', CssVarKeys extends string = ''>(initInput: DeclarativeElementInit<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>): DeclarativeElementDefinition<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
6
6
  //# sourceMappingURL=define-element-no-inputs.d.ts.map
@@ -1,12 +1,15 @@
1
- import { getObjectTypedKeys, kebabCaseToCamelCase } from '@augment-vir/common';
1
+ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
2
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
3
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
4
+ };
5
+ import { ensureError, getObjectTypedKeys, kebabCaseToCamelCase } from '@augment-vir/common';
2
6
  import { css } from 'lit';
3
7
  import { property } from 'lit/decorators.js';
4
8
  import { DeclarativeElementMarkerSymbol } from '../declarative-element-marker-symbol';
5
9
  import { DeclarativeElement, } from './declarative-element';
6
- import { defaultDeclarativeElementDefinitionOptions, IgnoreInputsNotBeenSetBeforeRenderWarningSymbol, } from './definition-options';
10
+ import { IgnoreInputsNotBeenSetBeforeRenderWarningSymbol, defaultDeclarativeElementDefinitionOptions, } from './definition-options';
7
11
  import { assign } from './directives/assign.directive';
8
12
  import { hasDeclarativeElementParent } from './has-declarative-element-parent';
9
- import { toAsyncStateHandlerMap } from './properties/async-state';
10
13
  import { createCssVarNamesMap, createCssVarValuesMap } from './properties/css-vars';
11
14
  import { createEventDescriptorMap } from './properties/element-events';
12
15
  import { createElementUpdaterProxy } from './properties/element-updater-proxy';
@@ -46,29 +49,36 @@ export function defineElementNoInputs(initInput) {
46
49
  }
47
50
  }
48
51
  render() {
49
- if (
50
- // This ignores elements at the root of a page, as they can't receive inputs from
51
- // other elements (cause they have no custom element ancestors).
52
- hasDeclarativeElementParent(this) &&
53
- !this.haveInputsBeenSet &&
54
- !elementOptions[IgnoreInputsNotBeenSetBeforeRenderWarningSymbol]) {
55
- console.warn(this, `${initInput.tagName} got rendered before its input object was set. This was most likely caused by forgetting to use the "${assign.name}" directive on it. If no inputs are intended, use "${defineElementNoInputs.name}" to define ${initInput.tagName}.`);
52
+ try {
53
+ if (
54
+ // This ignores elements at the root of a page, as they can't receive inputs from
55
+ // other elements (cause they have no custom element ancestors).
56
+ hasDeclarativeElementParent(this) &&
57
+ !this.haveInputsBeenSet &&
58
+ !elementOptions[IgnoreInputsNotBeenSetBeforeRenderWarningSymbol]) {
59
+ console.warn(this, `${initInput.tagName} got rendered before its input object was set. This was most likely caused by forgetting to use the "${assign.name}" directive on it. If no inputs are intended, use "${defineElementNoInputs.name}" to define ${initInput.tagName}.`);
60
+ }
61
+ this.hasRendered = true;
62
+ const renderParams = this.createRenderParams();
63
+ if (!this.initCalled && initInput.initCallback) {
64
+ this.initCalled = true;
65
+ initInput.initCallback(renderParams);
66
+ }
67
+ const renderResult = initInput.renderCallback(renderParams);
68
+ applyHostClasses({
69
+ host: renderParams.host,
70
+ hostClassesInit: initInput.hostClasses,
71
+ hostClassNames,
72
+ state: renderParams.state,
73
+ inputs: renderParams.inputs,
74
+ });
75
+ return renderResult;
56
76
  }
57
- this.hasRendered = true;
58
- const renderParams = this.createRenderParams();
59
- if (!this.initCalled && initInput.initCallback) {
60
- this.initCalled = true;
61
- initInput.initCallback(renderParams);
77
+ catch (caught) {
78
+ const error = ensureError(caught);
79
+ error.message = `Failed to render '${initInput.tagName}': ${error.message}`;
80
+ throw error;
62
81
  }
63
- const renderResult = initInput.renderCallback(renderParams);
64
- applyHostClasses({
65
- host: renderParams.host,
66
- hostClassesInit: initInput.hostClasses,
67
- hostClassNames,
68
- state: renderParams.state,
69
- inputs: renderParams.inputs,
70
- });
71
- return renderResult;
72
82
  }
73
83
  connectedCallback() {
74
84
  super.connectedCallback();
@@ -100,28 +110,17 @@ export function defineElementNoInputs(initInput) {
100
110
  this.haveInputsBeenSet = false;
101
111
  // this is set below in Object.defineProperties
102
112
  this.definition = {};
103
- this.asyncStateHandlerMap = toAsyncStateHandlerMap(initInput.stateInit);
104
113
  this.instanceInputs = createElementUpdaterProxy(this, false);
105
114
  this.instanceState = createElementUpdaterProxy(this, true);
106
- const stateInit = initInput.stateInit ||
107
- {};
115
+ const stateInit = initInput.stateInit || {};
108
116
  getObjectTypedKeys(stateInit).forEach((stateKey) => {
109
117
  property()(this, stateKey);
110
- const asyncStateClassInstance = this.asyncStateHandlerMap[stateKey];
111
- if (asyncStateClassInstance) {
112
- this.instanceState[stateKey] = asyncStateClassInstance.getValue();
113
- asyncStateClassInstance.addSettleListener(() => {
114
- this[stateKey] =
115
- asyncStateClassInstance.getValue();
116
- });
117
- }
118
- else {
119
- this.instanceState[stateKey] = stateInit[stateKey];
120
- }
118
+ this.instanceState[stateKey] = stateInit[stateKey];
121
119
  });
122
120
  this.definition = anonymousClass;
123
121
  }
124
122
  },
123
+ __setFunctionName(_a, "anonymousClass"),
125
124
  _a.tagName = initInput.tagName,
126
125
  _a.styles = calculatedStyles,
127
126
  // this gets set below in Object.defineProperties
@@ -3,8 +3,8 @@ import { DeclarativeElement, DeclarativeElementDefinition } from '../declarative
3
3
  /** Assign an object matching an element's inputs to its inputs. */
4
4
  export declare function assign<DeclarativeElementGeneric extends DeclarativeElementDefinition>(declarativeElement: DeclarativeElementGeneric, inputsObject: DeclarativeElementGeneric['inputsType']): import("lit-html/directive").DirectiveResult<{
5
5
  new (partInfo: PartInfo): {
6
- readonly element: DeclarativeElement<`${string}-${string}`, any, any, any, string, string>;
7
- render(elementDefinition: DeclarativeElementDefinition<any, any, any, any, string, string>, inputsObject: Record<PropertyKey, unknown>): symbol;
6
+ readonly element: DeclarativeElement<any, any, any, any, string, string>;
7
+ render(elementDefinition: DeclarativeElementDefinition, inputsObject: Record<PropertyKey, unknown>): symbol;
8
8
  readonly _$isConnected: boolean;
9
9
  update(_part: import("lit-html").Part, props: unknown[]): unknown;
10
10
  };
@@ -24,7 +24,7 @@ const listenDirective = directive(class extends Directive {
24
24
  return {
25
25
  eventType,
26
26
  callback,
27
- listener: (event) => { var _a; return (_a = this.lastListenerMetaData) === null || _a === void 0 ? void 0 : _a.callback(event); },
27
+ listener: (event) => this.lastListenerMetaData?.callback(event),
28
28
  };
29
29
  }
30
30
  render(eventTypeInput, callback) {
@@ -8,13 +8,12 @@ export const onResize = directive(class extends Directive {
8
8
  assertIsElementPartInfo(partInfo, directiveName);
9
9
  }
10
10
  fireCallback(entries) {
11
- var _a;
12
11
  const resizeEntry = entries[0];
13
12
  if (!resizeEntry) {
14
13
  console.error(entries);
15
14
  throw new Error(`${directiveName} observation triggered but the first entry was empty.`);
16
15
  }
17
- (_a = this.callback) === null || _a === void 0 ? void 0 : _a.call(this, { target: resizeEntry.target, contentRect: resizeEntry.contentRect });
16
+ this.callback?.({ target: resizeEntry.target, contentRect: resizeEntry.contentRect });
18
17
  }
19
18
  update(partInfo, [callback]) {
20
19
  assertIsElementPartInfo(partInfo, directiveName);
@@ -1,2 +1,2 @@
1
- export declare function renderIf(condition: boolean, ifTrue: unknown, ifFalse?: unknown): unknown;
1
+ export declare function renderIf<TrueCondition = unknown, FalseCondition = undefined>(condition: boolean, ifTrue: TrueCondition, ifFalse?: FalseCondition): TrueCondition | FalseCondition;
2
2
  //# sourceMappingURL=render-if.directive.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import { when } from 'lit/directives/when.js';
2
+ const notSetSymbol = Symbol('not set');
2
3
  export function renderIf(condition, ifTrue, ifFalse) {
3
4
  return when(condition, () => ifTrue, () => ifFalse);
4
5
  }
@@ -0,0 +1,15 @@
1
+ import { CachedPromise, GetCachedPromiseInput } from '@electrovir/cached-promise';
2
+ import { RequireExactlyOne } from 'type-fest';
3
+ import { RenderOutput } from '../render-callback';
4
+ export type RenderPromiseInput<T> = RequireExactlyOne<{
5
+ promise: Promise<T>;
6
+ resolved: T;
7
+ error: Error;
8
+ }>;
9
+ export declare function renderPromise<T>(maybePromise: Promise<T> | T, renderer: (input: RenderPromiseInput<T>) => RenderOutput): import("lit-html/directive").DirectiveResult<typeof import("lit-html/directives/until").UntilDirective> | null | undefined;
10
+ export type RenderCachedPromiseInputs<T> = {
11
+ cachedPromise: CachedPromise<T>;
12
+ render: (input: RenderPromiseInput<T>) => RenderOutput;
13
+ } & GetCachedPromiseInput<T>;
14
+ export declare function renderCachedPromise<T>({ cachedPromise, render, triggers, createPromise, }: RenderCachedPromiseInputs<T>): import("lit-html/directive").DirectiveResult<typeof import("lit-html/directives/until").UntilDirective> | null | undefined;
15
+ //# sourceMappingURL=render-promise.directive.d.ts.map
@@ -0,0 +1,27 @@
1
+ import { ensureError } from '@augment-vir/common';
2
+ import { until } from 'lit/directives/until.js';
3
+ export function renderPromise(maybePromise, renderer) {
4
+ if (maybePromise instanceof Promise) {
5
+ return until(maybePromise
6
+ .catch((error) => {
7
+ return ensureError(error);
8
+ })
9
+ .then((resolved) => {
10
+ if (resolved instanceof Error) {
11
+ return renderer({ error: resolved });
12
+ }
13
+ else {
14
+ return renderer({ resolved });
15
+ }
16
+ }), renderer({ promise: maybePromise }));
17
+ }
18
+ else {
19
+ return renderer({ resolved: maybePromise });
20
+ }
21
+ }
22
+ export function renderCachedPromise({ cachedPromise, render, triggers, createPromise, }) {
23
+ return renderPromise(cachedPromise.get({
24
+ createPromise,
25
+ triggers,
26
+ }), render);
27
+ }
@@ -17,13 +17,7 @@ export function createElementUpdaterProxy(element, verifyExists) {
17
17
  if (verifyExists) {
18
18
  assertValidPropertyName(propertyName, element, element.tagName);
19
19
  }
20
- const asyncState = element.asyncStateHandlerMap[propertyName];
21
- if (asyncState) {
22
- return asyncState.getValue();
23
- }
24
- else {
25
- return elementAsProps[propertyName];
26
- }
20
+ return elementAsProps[propertyName];
27
21
  }
28
22
  const propsProxy = new Proxy({}, {
29
23
  get: valueGetter,
@@ -37,13 +31,7 @@ export function createElementUpdaterProxy(element, verifyExists) {
37
31
  * "getOwnPropertyDescriptor".
38
32
  */
39
33
  target[propertyName] = undefined;
40
- const asyncState = element.asyncStateHandlerMap[propertyName];
41
- if (asyncState) {
42
- asyncState.setValue(newValue);
43
- }
44
- else {
45
- elementAsProps[propertyName] = newValue;
46
- }
34
+ elementAsProps[propertyName] = newValue;
47
35
  return true;
48
36
  },
49
37
  ownKeys: (target) => {
@@ -1,7 +1,7 @@
1
1
  import { CSSResult } from 'lit';
2
2
  import { CssVarNameOrValueMap } from './css-vars';
3
3
  import { PropertyInitMapBase } from './element-properties';
4
- import { HostClassesInitMap, HostClassNamesMap } from './host-classes';
4
+ import { HostClassNamesMap, HostClassesInitMap } from './host-classes';
5
5
  export type StylesCallbackInput<HostClassKeys extends string, CssVarKeys extends string> = {
6
6
  hostClassSelectors: Record<HostClassKeys, CSSResult>;
7
7
  hostClassNames: Record<HostClassKeys, CSSResult>;
@@ -3,15 +3,14 @@ import { Primitive } from 'type-fest';
3
3
  import { TypedEvent } from '../typed-event/typed-event';
4
4
  import { DeclarativeElement, HostInstanceType } from './declarative-element';
5
5
  import { CustomElementTagName } from './declarative-element-init';
6
- import { AsyncStateInputs, MaybeAsyncStateToSync } from './properties/async-state';
7
6
  import { EventDescriptorMap, EventInitMapEventDetailExtractor, EventsInitMap } from './properties/element-events';
8
7
  import { PropertyInitMapBase } from './properties/element-properties';
9
8
  export type RenderOutput = TemplateResult | Primitive | ReadonlyArray<TemplateResult> | ReadonlyArray<Primitive>;
10
9
  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> = (params: RenderParams<TagNameGeneric, InputsGeneric, StateGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>) => RenderOutput;
11
10
  export type InitCallback<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string> = (params: RenderParams<TagNameGeneric, InputsGeneric, StateGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>) => void;
12
- export type UpdateStateCallback<StateGeneric extends PropertyInitMapBase> = (newState: Partial<AsyncStateInputs<StateGeneric>>) => void;
11
+ export type UpdateStateCallback<StateGeneric extends PropertyInitMapBase> = (newState: Partial<StateGeneric>) => void;
13
12
  export type RenderParams<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string> = {
14
- state: Readonly<MaybeAsyncStateToSync<StateInitGeneric>>;
13
+ state: Readonly<StateInitGeneric>;
15
14
  updateState: UpdateStateCallback<StateInitGeneric>;
16
15
  events: EventDescriptorMap<EventsInitGeneric>;
17
16
  host: HostInstanceType<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
@@ -3,13 +3,7 @@ export function createRenderParams(element, eventsMap) {
3
3
  function updateState(newStatePartial) {
4
4
  getObjectTypedKeys(newStatePartial).forEach((stateKey) => {
5
5
  const newValue = newStatePartial[stateKey];
6
- const asyncState = element.asyncStateHandlerMap[stateKey];
7
- if (asyncState) {
8
- asyncState.setValue(newValue);
9
- }
10
- else {
11
- element.instanceState[stateKey] = newValue;
12
- }
6
+ element.instanceState[stateKey] = newValue;
13
7
  });
14
8
  }
15
9
  const renderParams = {
@@ -1,9 +1,8 @@
1
1
  import { defineElement, defineElementNoInputs, } from '..';
2
2
  export function wrapDefineElement(options) {
3
- var _a, _b;
4
3
  const { assertInputs, transformInputs } = {
5
- assertInputs: (_a = options === null || options === void 0 ? void 0 : options.assertInputs) !== null && _a !== void 0 ? _a : (() => { }),
6
- transformInputs: (_b = options === null || options === void 0 ? void 0 : options.transformInputs) !== null && _b !== void 0 ? _b : ((inputs) => inputs),
4
+ assertInputs: options?.assertInputs ?? (() => { }),
5
+ transformInputs: options?.transformInputs ?? ((inputs) => inputs),
7
6
  };
8
7
  return {
9
8
  defineElement: () => {
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './built-in-lit-directives';
1
2
  export * from './declarative-element/declarative-element';
2
3
  export * from './declarative-element/declarative-element-init';
3
4
  export * from './declarative-element/define-element';
@@ -9,9 +10,8 @@ export * from './declarative-element/directives/directive-helpers';
9
10
  export * from './declarative-element/directives/listen.directive';
10
11
  export * from './declarative-element/directives/on-dom-created.directive';
11
12
  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/properties/async-state';
14
+ export * from './declarative-element/directives/render-promise.directive';
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';
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './built-in-lit-directives';
1
2
  export * from './declarative-element/declarative-element';
2
3
  export * from './declarative-element/declarative-element-init';
3
4
  export * from './declarative-element/define-element';
@@ -8,9 +9,8 @@ export * from './declarative-element/directives/directive-helpers';
8
9
  export * from './declarative-element/directives/listen.directive';
9
10
  export * from './declarative-element/directives/on-dom-created.directive';
10
11
  export * from './declarative-element/directives/on-resize.directive';
11
- export * from './declarative-element/directives/render-async-state.directive';
12
12
  export * from './declarative-element/directives/render-if.directive';
13
- export * from './declarative-element/properties/async-state';
13
+ export * from './declarative-element/directives/render-promise.directive';
14
14
  export * from './declarative-element/properties/css-vars';
15
15
  export * from './declarative-element/properties/element-events';
16
16
  export * from './declarative-element/properties/element-properties';
@@ -20,13 +20,12 @@ function extractElementKeys(values) {
20
20
  */
21
21
  const transformedTemplateStrings = new WeakMap();
22
22
  export function getAlreadyMappedTemplate(templateStringsKey, values) {
23
- var _a;
24
23
  const elementKeys = extractElementKeys(values);
25
24
  const nestedValue = getNestedValues(transformedTemplateStrings, [
26
25
  templateStringsKey,
27
26
  ...elementKeys,
28
27
  ]);
29
- return (_a = nestedValue.value) === null || _a === void 0 ? void 0 : _a.template;
28
+ return nestedValue.value?.template;
30
29
  }
31
30
  export function setMappedTemplate(templateStringsKey, values, valueToSet) {
32
31
  const elementKeys = extractElementKeys(values);
@@ -75,12 +74,11 @@ function getCurrentKeyAndValue(map, keys, index) {
75
74
  return { currentKey, currentTemplateAndNested, reason: `key and value exists` };
76
75
  }
77
76
  function setNestedValues(map, keys, valueToSet, index = 0) {
78
- var _a;
79
77
  const { currentTemplateAndNested, currentKey, reason } = getCurrentKeyAndValue(map, keys, index);
80
78
  if (!currentKey) {
81
79
  return { result: false, reason };
82
80
  }
83
- const nestedAndTemplate = currentTemplateAndNested !== null && currentTemplateAndNested !== void 0 ? currentTemplateAndNested : { nested: undefined, template: undefined };
81
+ const nestedAndTemplate = currentTemplateAndNested ?? { nested: undefined, template: undefined };
84
82
  if (!currentTemplateAndNested) {
85
83
  map.set(currentKey, nestedAndTemplate);
86
84
  }
@@ -88,7 +86,7 @@ function setNestedValues(map, keys, valueToSet, index = 0) {
88
86
  nestedAndTemplate.template = valueToSet;
89
87
  return { result: true, reason: `set value at end of keys array` };
90
88
  }
91
- const nestedWeakMap = (_a = nestedAndTemplate.nested) !== null && _a !== void 0 ? _a : new WeakMap();
89
+ const nestedWeakMap = nestedAndTemplate.nested ?? new WeakMap();
92
90
  if (!nestedAndTemplate.nested) {
93
91
  nestedAndTemplate.nested = nestedWeakMap;
94
92
  }
@@ -30,7 +30,7 @@ function extractElementValues(values) {
30
30
  }
31
31
  export function getTransformedTemplate(templateStringsKey, values, fallbackTransform) {
32
32
  const alreadyTransformedTemplateStrings = getAlreadyMappedTemplate(templateStringsKey, values);
33
- const templateTransform = alreadyTransformedTemplateStrings !== null && alreadyTransformedTemplateStrings !== void 0 ? alreadyTransformedTemplateStrings : fallbackTransform();
33
+ const templateTransform = alreadyTransformedTemplateStrings ?? fallbackTransform();
34
34
  if (!alreadyTransformedTemplateStrings) {
35
35
  const result = setMappedTemplate(templateStringsKey, values, templateTransform);
36
36
  if (!result.result) {
@@ -48,7 +48,6 @@ export function transformTemplate(inputTemplateStrings, inputValues, checksAndTr
48
48
  const newRaws = [];
49
49
  const valueDeletions = [];
50
50
  inputTemplateStrings.forEach((currentTemplateString, index) => {
51
- var _a;
52
51
  const lastNewStringsIndex = newStrings.length - 1;
53
52
  const lastNewString = newStrings[lastNewStringsIndex];
54
53
  const currentValueIndex = index - 1;
@@ -56,9 +55,9 @@ export function transformTemplate(inputTemplateStrings, inputValues, checksAndTr
56
55
  let validTransform;
57
56
  assertValidString && assertValidString(currentTemplateString);
58
57
  if (typeof lastNewString === 'string') {
59
- validTransform = (_a = checksAndTransforms.find((checkAndTransform) => {
58
+ validTransform = checksAndTransforms.find((checkAndTransform) => {
60
59
  return checkAndTransform.check(lastNewString, currentTemplateString, currentValue);
61
- })) === null || _a === void 0 ? void 0 : _a.transform;
60
+ })?.transform;
62
61
  if (validTransform) {
63
62
  newStrings[lastNewStringsIndex] =
64
63
  lastNewString + validTransform(currentValue) + currentTemplateString;
@@ -5,7 +5,7 @@ import { makeCheckTransform, transformTemplate, } from '../transform-template';
5
5
  const htmlChecksAndTransforms = [
6
6
  makeCheckTransform('tag name interpolation', (lastNewString, currentLitString, currentValue) => {
7
7
  const shouldHaveTagNameHere = (lastNewString.trim().endsWith('<') && !!currentLitString.match(/^[\s\n>]/)) ||
8
- ((lastNewString === null || lastNewString === void 0 ? void 0 : lastNewString.trim().endsWith('</')) && currentLitString.trim().startsWith('>'));
8
+ (lastNewString?.trim().endsWith('</') && currentLitString.trim().startsWith('>'));
9
9
  const staticTagName = hasStaticTagName(currentValue);
10
10
  if (shouldHaveTagNameHere && !staticTagName) {
11
11
  console.error({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "element-vir",
3
- "version": "9.2.2",
3
+ "version": "10.0.0",
4
4
  "keywords": [
5
5
  "custom",
6
6
  "web",
@@ -39,27 +39,29 @@
39
39
  "test:types": "tsc --noEmit"
40
40
  },
41
41
  "dependencies": {
42
- "@augment-vir/browser": "^12.11.2",
43
- "@augment-vir/common": "^12.11.2",
44
- "lit": "2.6.1"
42
+ "@augment-vir/browser": "^13.2.1",
43
+ "@augment-vir/common": "^13.2.1",
44
+ "@electrovir/cached-promise": "^0.0.1",
45
+ "lit": "2.7.0"
45
46
  },
46
47
  "devDependencies": {
47
- "@augment-vir/browser-testing": "^12.11.2",
48
- "@augment-vir/node-js": "^12.11.2",
48
+ "@augment-vir/browser-testing": "^13.2.1",
49
+ "@augment-vir/node-js": "^13.2.1",
49
50
  "@istanbuljs/nyc-config-typescript": "^1.0.2",
50
51
  "@open-wc/testing": "^3.1.7",
51
52
  "@types/mocha": "^10.0.1",
52
- "@web/dev-server-esbuild": "^0.3.3",
53
+ "@web/dev-server-esbuild": "^0.3.4",
53
54
  "@web/test-runner": "^0.15.1",
54
55
  "@web/test-runner-commands": "^0.6.5",
55
56
  "@web/test-runner-playwright": "^0.9.0",
57
+ "@web/test-runner-visual-regression": "^0.7.0",
56
58
  "ansi-colors": "^4.1.3",
57
- "cspell": "^6.26.3",
59
+ "cspell": "^6.31.1",
58
60
  "istanbul-smart-text-reporter": "^1.1.1",
59
61
  "markdown-code-example-inserter": "^0.3.0",
60
62
  "mocha-spec-reporter-with-file-names": "^0.0.3",
61
63
  "nyc": "^15.1.0",
62
- "prettier": "^2.8.4",
64
+ "prettier": "^2.8.7",
63
65
  "prettier-plugin-interpolated-html-tags": "^0.0.3",
64
66
  "prettier-plugin-jsdoc": "^0.4.2",
65
67
  "prettier-plugin-multiline-arrays": "^1.1.3",
@@ -68,9 +70,9 @@
68
70
  "prettier-plugin-sort-json": "^1.0.0",
69
71
  "prettier-plugin-toml": "^0.3.1",
70
72
  "ts-node": "^10.9.1",
71
- "type-fest": "^3.6.0",
72
- "typescript": "^4.9.5",
73
- "virmator": "^5.5.0",
74
- "vite": "^4.1.4"
73
+ "type-fest": "^3.7.0",
74
+ "typescript": "^5.0.2",
75
+ "virmator": "^6.2.2",
76
+ "vite": "^4.2.1"
75
77
  }
76
78
  }
@@ -1,7 +0,0 @@
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
@@ -1,22 +0,0 @@
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
- }
@@ -1,49 +0,0 @@
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
@@ -1,158 +0,0 @@
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
- }