element-vir 12.3.1 → 12.4.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 +1 -1
- package/dist/declarative-element/declarative-element-init.d.ts +7 -7
- package/dist/declarative-element/declarative-element.d.ts +17 -17
- package/dist/declarative-element/define-element-no-inputs.d.ts +1 -1
- package/dist/declarative-element/define-element-no-inputs.js +1 -1
- package/dist/declarative-element/directives/assign.directive.d.ts +2 -1
- package/dist/declarative-element/directives/is-render-ready.directive.d.ts +3 -0
- package/dist/declarative-element/directives/is-render-ready.directive.js +12 -0
- package/dist/declarative-element/properties/async-state.d.ts +12 -22
- package/dist/declarative-element/properties/async-state.js +92 -87
- package/dist/declarative-element/properties/element-updater-proxy.js +25 -27
- package/dist/declarative-element/properties/observable-property/create-observable-property.d.ts +2 -0
- package/dist/declarative-element/properties/observable-property/create-observable-property.js +41 -0
- package/dist/declarative-element/properties/observable-property/observable-property-handler.d.ts +34 -0
- package/dist/declarative-element/properties/observable-property/observable-property-handler.js +6 -0
- package/dist/declarative-element/render-callback.d.ts +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -219,7 +219,7 @@ export const MyWithAssignmentCleanupCallbackElement = defineElementNoInputs({
|
|
|
219
219
|
},
|
|
220
220
|
initCallback: ({updateState}) => {
|
|
221
221
|
updateState({
|
|
222
|
-
intervalId: window.setInterval(() => console.
|
|
222
|
+
intervalId: window.setInterval(() => console.info('hi'), 1000),
|
|
223
223
|
});
|
|
224
224
|
},
|
|
225
225
|
renderCallback: () => html`
|
|
@@ -1,15 +1,15 @@
|
|
|
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';
|
|
5
4
|
import { CssVarsInitMap } from './properties/css-vars';
|
|
6
5
|
import { EventsInitMap } from './properties/element-events';
|
|
7
6
|
import { PropertyInitMapBase } from './properties/element-properties';
|
|
8
7
|
import { HostClassesInitMap } from './properties/host-classes';
|
|
8
|
+
import { FlattenObservablePropertyGetters } from './properties/observable-property/observable-property-handler';
|
|
9
9
|
import { StylesCallback } from './properties/styles';
|
|
10
10
|
import { InitCallback, RenderCallback } from './render-callback';
|
|
11
11
|
export type CustomElementTagName = `${string}-${string}`;
|
|
12
|
-
export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase,
|
|
12
|
+
export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeysGeneric extends string, CssVarKeysGeneric extends string, RenderOutputGeneric> = {
|
|
13
13
|
/**
|
|
14
14
|
* HTML tag name. This should not be used directly, as interpolating it with the html tagged
|
|
15
15
|
* template from this package is preferred.
|
|
@@ -18,7 +18,7 @@ export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName,
|
|
|
18
18
|
/** Static styles. These should not and cannot change. */
|
|
19
19
|
styles?: CSSResult | StylesCallback<HostClassKeysGeneric, CssVarKeysGeneric>;
|
|
20
20
|
/** Element properties. (These can be thought of as "inputs".) */
|
|
21
|
-
stateInit?:
|
|
21
|
+
stateInit?: StateInitGeneric;
|
|
22
22
|
/** Events that the element can dispatch. (These can be thought of as "outputs".) */
|
|
23
23
|
events?: EventsInitGeneric;
|
|
24
24
|
/**
|
|
@@ -26,7 +26,7 @@ export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName,
|
|
|
26
26
|
* based on current instance state or inputs, or just undefined to indicate that the host class
|
|
27
27
|
* will only be manually set.
|
|
28
28
|
*/
|
|
29
|
-
hostClasses?: HostClassesInitMap<HostClassKeysGeneric, InputsGeneric
|
|
29
|
+
hostClasses?: HostClassesInitMap<HostClassKeysGeneric, FlattenObservablePropertyGetters<InputsGeneric>, FlattenObservablePropertyGetters<StateInitGeneric>>;
|
|
30
30
|
/**
|
|
31
31
|
* CSS Vars for the component. Keys of this object should be camelCased (or whatever your casing
|
|
32
32
|
* convention is). They will be transformed, at runtime, to CSS vars with kebab-casing, to match
|
|
@@ -39,8 +39,8 @@ export type DeclarativeElementInit<TagNameGeneric extends CustomElementTagName,
|
|
|
39
39
|
*/
|
|
40
40
|
cssVars?: CssVarsInitMap<CssVarKeysGeneric>;
|
|
41
41
|
/** Called as part of the first renderCallback call, before the first renderCallback call. */
|
|
42
|
-
initCallback?: InitCallback<TagNameGeneric, InputsGeneric,
|
|
43
|
-
renderCallback: RequireNonVoidReturn<RenderOutputGeneric, RenderCallback<TagNameGeneric, InputsGeneric,
|
|
44
|
-
cleanupCallback?: InitCallback<TagNameGeneric, InputsGeneric,
|
|
42
|
+
initCallback?: InitCallback<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric>;
|
|
43
|
+
renderCallback: RequireNonVoidReturn<RenderOutputGeneric, RenderCallback<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric, RenderOutputGeneric>>;
|
|
44
|
+
cleanupCallback?: InitCallback<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeysGeneric, CssVarKeysGeneric>;
|
|
45
45
|
options?: Partial<DeclarativeElementDefinitionOptions> | undefined;
|
|
46
46
|
};
|
|
@@ -1,17 +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';
|
|
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';
|
|
8
|
+
import { AllowObservablePropertySetter, FlattenObservablePropertyGetters, ObservablePropertyHandlerMap } from './properties/observable-property/observable-property-handler';
|
|
9
9
|
import { RenderCallback, RenderParams } from './render-callback';
|
|
10
|
-
export type HostInstanceType<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase,
|
|
11
|
-
export type DeclarativeElementDefinition<TagNameGeneric extends CustomElementTagName = any, InputsGeneric extends PropertyInitMapBase = any,
|
|
12
|
-
instanceType: HostInstanceType<TagNameGeneric, InputsGeneric,
|
|
10
|
+
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, any>, 'shadowRoot'>;
|
|
11
|
+
export type DeclarativeElementDefinition<TagNameGeneric extends CustomElementTagName = any, InputsGeneric extends PropertyInitMapBase = any, StateInitGeneric extends PropertyInitMapBase = any, EventsInitGeneric extends EventsInitMap = any, HostClassKeys extends string = string, CssVarKeys extends string = string, RenderOutputGeneric = any> = (new () => HostInstanceType<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>) & StaticDeclarativeElementProperties<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric> & {
|
|
12
|
+
instanceType: HostInstanceType<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
|
|
13
13
|
};
|
|
14
|
-
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, StateInitGeneric extends PropertyInitMapBase = any, EventsInitGeneric extends EventsInitMap = any, HostClassKeys extends string = string, CssVarKeys extends string = string, RenderOutputGeneric = any> extends LitElement {
|
|
15
15
|
static readonly tagName: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string, unknown>['tagName'];
|
|
16
16
|
static readonly styles: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string, unknown>['styles'];
|
|
17
17
|
static readonly isStrictInstance: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string, unknown>['isStrictInstance'];
|
|
@@ -24,25 +24,25 @@ export declare abstract class DeclarativeElement<TagNameGeneric extends CustomEl
|
|
|
24
24
|
static readonly hostClasses: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string, unknown>['hostClasses'];
|
|
25
25
|
static readonly cssVarNames: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string, unknown>['cssVarNames'];
|
|
26
26
|
static readonly cssVarValues: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, string, string, unknown>['cssVarValues'];
|
|
27
|
-
abstract lastRenderedProps: Pick<RenderParams<any, InputsGeneric,
|
|
27
|
+
abstract lastRenderedProps: Pick<RenderParams<any, InputsGeneric, StateInitGeneric, any, any, any>, 'inputs' | 'state'>;
|
|
28
28
|
abstract render(): unknown;
|
|
29
|
-
abstract readonly instanceState:
|
|
30
|
-
abstract readonly
|
|
31
|
-
abstract readonly instanceInputs: InputsGeneric
|
|
29
|
+
abstract readonly instanceState: FlattenObservablePropertyGetters<StateInitGeneric>;
|
|
30
|
+
abstract readonly observablePropertyHandlerMap: ObservablePropertyHandlerMap<StateInitGeneric>;
|
|
31
|
+
abstract readonly instanceInputs: FlattenObservablePropertyGetters<InputsGeneric>;
|
|
32
32
|
abstract assignInputs(inputs: {} extends Required<InputsGeneric> ? never : Partial<InputsGeneric>): void;
|
|
33
33
|
abstract haveInputsBeenSet: boolean;
|
|
34
34
|
abstract markInputsAsHavingBeenSet(): void;
|
|
35
|
-
abstract readonly definition: DeclarativeElementDefinition<TagNameGeneric, InputsGeneric,
|
|
35
|
+
abstract readonly definition: DeclarativeElementDefinition<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
|
|
36
36
|
}
|
|
37
|
-
export interface StaticDeclarativeElementProperties<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase,
|
|
37
|
+
export interface StaticDeclarativeElementProperties<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string, RenderOutputGeneric> {
|
|
38
38
|
/** Pass through the render callback for direct unit testability */
|
|
39
|
-
readonly renderCallback: RenderCallback<TagNameGeneric, InputsGeneric,
|
|
39
|
+
readonly renderCallback: RenderCallback<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
|
|
40
40
|
events: EventDescriptorMap<EventsInitGeneric>;
|
|
41
|
-
stateInit: ElementPropertyDescriptorMap<
|
|
42
|
-
init: RequiredBy<DeclarativeElementInit<TagNameGeneric, InputsGeneric,
|
|
43
|
-
inputsType: InputsGeneric
|
|
44
|
-
stateType:
|
|
45
|
-
isStrictInstance: (element: unknown) => element is DeclarativeElement<TagNameGeneric, InputsGeneric,
|
|
41
|
+
stateInit: ElementPropertyDescriptorMap<StateInitGeneric>;
|
|
42
|
+
init: RequiredBy<DeclarativeElementInit<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>, 'stateInit' | 'events'>;
|
|
43
|
+
inputsType: AllowObservablePropertySetter<InputsGeneric>;
|
|
44
|
+
stateType: FlattenObservablePropertyGetters<StateInitGeneric>;
|
|
45
|
+
isStrictInstance: (element: unknown) => element is DeclarativeElement<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
|
|
46
46
|
hostClasses: HostClassNamesMap<string, HostClassKeys>;
|
|
47
47
|
cssVarNames: CssVarNameOrValueMap<CssVarKeys>;
|
|
48
48
|
cssVarValues: CssVarNameOrValueMap<CssVarKeys>;
|
|
@@ -2,4 +2,4 @@ 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 = {}, StateInitGeneric extends PropertyInitMapBase = {}, EventsInitGeneric extends EventsInitMap = {}, HostClassKeys extends string = '', CssVarKeys extends string = '', RenderOutputGeneric = any>(initInput: DeclarativeElementInit<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>): DeclarativeElementDefinition<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>;
|
|
@@ -113,7 +113,7 @@ export function defineElementNoInputs(initInput) {
|
|
|
113
113
|
this.haveInputsBeenSet = false;
|
|
114
114
|
// this is set below in Object.defineProperties
|
|
115
115
|
this.definition = {};
|
|
116
|
-
this.
|
|
116
|
+
this.observablePropertyHandlerMap = {};
|
|
117
117
|
this.instanceInputs = createElementUpdaterProxy(this, false);
|
|
118
118
|
this.instanceState = createElementUpdaterProxy(this, true);
|
|
119
119
|
const stateInit = initInput.stateInit ||
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { DirectiveResult } from 'lit/directive.js';
|
|
2
2
|
import { PropertyInitMapBase } from '../properties/element-properties';
|
|
3
|
+
import { AllowObservablePropertySetter } from '../properties/observable-property/observable-property-handler';
|
|
3
4
|
export type ElementDefinitionWithInputsType<InputsType extends PropertyInitMapBase = PropertyInitMapBase> = {
|
|
4
|
-
inputsType: InputsType
|
|
5
|
+
inputsType: AllowObservablePropertySetter<InputsType>;
|
|
5
6
|
};
|
|
6
7
|
/** Assign an object matching an element's inputs to its inputs. */
|
|
7
8
|
export declare function assign<DeclarativeElementGeneric extends ElementDefinitionWithInputsType>(declarativeElement: DeclarativeElementGeneric, inputsObject: {} extends Required<DeclarativeElementGeneric['inputsType']> ? never : DeclarativeElementGeneric['inputsType']): DirectiveResult;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { isPromiseLike } from '@augment-vir/common';
|
|
2
|
+
export function isRenderReady(asyncStateInput) {
|
|
3
|
+
if (asyncStateInput instanceof Error) {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
else if (isPromiseLike(asyncStateInput)) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { JsonCompatibleValue, UnPromise } from '@augment-vir/common';
|
|
2
2
|
import { PickAndBlockOthers } from '../../augments/type';
|
|
3
|
-
import {
|
|
3
|
+
import { ObservablePropertyHandler, observablePropertyHandlerMarkerKey, ObservablePropertyListener } from './observable-property/observable-property-handler';
|
|
4
4
|
export type AsyncState<ValueGeneric> = Error | UnPromise<ValueGeneric> | Promise<UnPromise<ValueGeneric>>;
|
|
5
5
|
declare const notSetSymbol: unique symbol;
|
|
6
|
-
export declare function isRenderReady<T>(asyncStateInput: AsyncState<T>): asyncStateInput is UnPromise<T>;
|
|
7
6
|
type AllSetValueProperties<ValueGeneric> = {
|
|
8
7
|
/** Set a new value directly without using any promises. */
|
|
9
8
|
resolvedValue: UnPromise<ValueGeneric>;
|
|
@@ -22,28 +21,19 @@ type AllSetValueProperties<ValueGeneric> = {
|
|
|
22
21
|
forceUpdate: true;
|
|
23
22
|
};
|
|
24
23
|
export type AsyncStateSetValue<ValueGeneric> = PickAndBlockOthers<AllSetValueProperties<ValueGeneric>, 'createPromise' | 'trigger'> | PickAndBlockOthers<AllSetValueProperties<ValueGeneric>, 'newPromise'> | PickAndBlockOthers<AllSetValueProperties<ValueGeneric>, 'forceUpdate'> | PickAndBlockOthers<AllSetValueProperties<ValueGeneric>, 'resolvedValue'>;
|
|
25
|
-
export
|
|
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 type AsyncStateHandlerListener<ValueGeneric> = (handler: AsyncStateHandler<ValueGeneric>) => void;
|
|
33
|
-
export declare class AsyncStateHandler<ValueGeneric> {
|
|
24
|
+
export declare class AsyncObservablePropertyHandler<ValueGeneric> implements asyncObservablePropertyHandler<ValueGeneric> {
|
|
34
25
|
#private;
|
|
35
|
-
|
|
36
|
-
constructor(initialValue: Promise<UnPromise<ValueGeneric>> | UnPromise<ValueGeneric> | ValueGeneric | typeof notSetSymbol
|
|
37
|
-
resetValue(rawValue: Promise<UnPromise<ValueGeneric>> | UnPromise<ValueGeneric> | ValueGeneric | typeof notSetSymbol
|
|
26
|
+
[observablePropertyHandlerMarkerKey]: true;
|
|
27
|
+
constructor(initialValue: Promise<UnPromise<ValueGeneric>> | UnPromise<ValueGeneric> | ValueGeneric | typeof notSetSymbol);
|
|
28
|
+
resetValue(rawValue: Promise<UnPromise<ValueGeneric>> | UnPromise<ValueGeneric> | ValueGeneric | typeof notSetSymbol): void;
|
|
38
29
|
setValue(setInputs: AsyncStateSetValue<ValueGeneric>): void;
|
|
39
30
|
getValue(): AsyncState<ValueGeneric>;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
constructor(initialValue: Promise<UnPromise<ValueGeneric>> | UnPromise<ValueGeneric> | ValueGeneric | typeof notSetSymbol);
|
|
46
|
-
readonly asyncMarkerSymbol: symbol;
|
|
31
|
+
addListener(fireImmediately: boolean, listener: ObservablePropertyListener<AsyncState<ValueGeneric>>): void;
|
|
32
|
+
addMultipleListeners(listeners: ReadonlySet<ObservablePropertyListener<AsyncState<ValueGeneric>>>): void;
|
|
33
|
+
getAllListeners(): Set<ObservablePropertyListener<AsyncState<ValueGeneric>>>;
|
|
34
|
+
removeListener(listener: ObservablePropertyListener<AsyncState<ValueGeneric>>): boolean;
|
|
35
|
+
removeAllListeners(): number;
|
|
47
36
|
}
|
|
48
|
-
export
|
|
37
|
+
export type asyncObservablePropertyHandler<ValueGeneric> = ObservablePropertyHandler<AsyncStateSetValue<ValueGeneric>, AsyncState<ValueGeneric>>;
|
|
38
|
+
export declare function asyncState<ValueGeneric>(...args: [Promise<UnPromise<ValueGeneric>> | UnPromise<ValueGeneric> | ValueGeneric] | []): AsyncObservablePropertyHandler<ValueGeneric>;
|
|
49
39
|
export {};
|
|
@@ -9,39 +9,24 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
9
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
10
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
11
|
};
|
|
12
|
-
var
|
|
13
|
-
import { areJsonEqual, createDeferredPromiseWrapper, ensureError, isLengthAtLeast,
|
|
14
|
-
|
|
12
|
+
var _AsyncObservablePropertyHandler_instances, _AsyncObservablePropertyHandler_lastTrigger, _AsyncObservablePropertyHandler_resolutionValue, _AsyncObservablePropertyHandler_rejectionError, _AsyncObservablePropertyHandler_listeners, _AsyncObservablePropertyHandler_lastSetPromise, _AsyncObservablePropertyHandler_waitingForValuePromise, _AsyncObservablePropertyHandler_fireListeners, _AsyncObservablePropertyHandler_setPromise, _AsyncObservablePropertyHandler_resolveValue, _AsyncObservablePropertyHandler_resetWaitingForValuePromise, _a;
|
|
13
|
+
import { areJsonEqual, createDeferredPromiseWrapper, ensureError, isLengthAtLeast, } from '@augment-vir/common';
|
|
14
|
+
import { observablePropertyHandlerMarkerKey, } from './observable-property/observable-property-handler';
|
|
15
15
|
const notSetSymbol = Symbol('not set');
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
export class AsyncStateHandler {
|
|
28
|
-
constructor(initialValue, listener) {
|
|
29
|
-
_AsyncStateHandler_instances.add(this);
|
|
30
|
-
_AsyncStateHandler_lastTrigger.set(this, notSetSymbol);
|
|
31
|
-
_AsyncStateHandler_resolutionValue.set(this, notSetSymbol);
|
|
32
|
-
_AsyncStateHandler_rejectionError.set(this, notSetSymbol);
|
|
33
|
-
_AsyncStateHandler_listeners.set(this, []);
|
|
34
|
-
_AsyncStateHandler_lastSetPromise.set(this, void 0);
|
|
35
|
-
_AsyncStateHandler_waitingForValuePromise.set(this, createDeferredPromiseWrapper());
|
|
36
|
-
this.asyncMarkerSymbol = asyncMarkerSymbol;
|
|
37
|
-
this.addSettleListener(listener);
|
|
16
|
+
export class AsyncObservablePropertyHandler {
|
|
17
|
+
constructor(initialValue) {
|
|
18
|
+
_AsyncObservablePropertyHandler_instances.add(this);
|
|
19
|
+
_AsyncObservablePropertyHandler_lastTrigger.set(this, notSetSymbol);
|
|
20
|
+
_AsyncObservablePropertyHandler_resolutionValue.set(this, notSetSymbol);
|
|
21
|
+
_AsyncObservablePropertyHandler_rejectionError.set(this, notSetSymbol);
|
|
22
|
+
_AsyncObservablePropertyHandler_listeners.set(this, new Set());
|
|
23
|
+
_AsyncObservablePropertyHandler_lastSetPromise.set(this, void 0);
|
|
24
|
+
_AsyncObservablePropertyHandler_waitingForValuePromise.set(this, createDeferredPromiseWrapper());
|
|
25
|
+
this[_a] = true;
|
|
38
26
|
this.resetValue(initialValue);
|
|
39
27
|
}
|
|
40
28
|
resetValue(rawValue) {
|
|
41
|
-
|
|
42
|
-
rawValue = rawValue.initialValue;
|
|
43
|
-
}
|
|
44
|
-
__classPrivateFieldGet(this, _AsyncStateHandler_instances, "m", _AsyncStateHandler_resetWaitingForValuePromise).call(this);
|
|
29
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_resetWaitingForValuePromise).call(this);
|
|
45
30
|
if (rawValue !== notSetSymbol) {
|
|
46
31
|
if (rawValue instanceof Promise) {
|
|
47
32
|
this.setValue({ newPromise: rawValue });
|
|
@@ -53,115 +38,135 @@ export class AsyncStateHandler {
|
|
|
53
38
|
}
|
|
54
39
|
setValue(setInputs) {
|
|
55
40
|
if ('createPromise' in setInputs) {
|
|
56
|
-
if (__classPrivateFieldGet(this,
|
|
57
|
-
!areJsonEqual(setInputs.trigger, __classPrivateFieldGet(this,
|
|
58
|
-
__classPrivateFieldSet(this,
|
|
41
|
+
if (__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_lastTrigger, "f") === notSetSymbol ||
|
|
42
|
+
!areJsonEqual(setInputs.trigger, __classPrivateFieldGet(this, _AsyncObservablePropertyHandler_lastTrigger, "f"))) {
|
|
43
|
+
__classPrivateFieldSet(this, _AsyncObservablePropertyHandler_lastTrigger, setInputs.trigger, "f");
|
|
59
44
|
const newValue = setInputs.createPromise();
|
|
60
|
-
__classPrivateFieldGet(this,
|
|
45
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_setPromise).call(this, newValue);
|
|
46
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_fireListeners).call(this);
|
|
61
47
|
}
|
|
62
48
|
}
|
|
63
49
|
else if ('newPromise' in setInputs) {
|
|
64
|
-
__classPrivateFieldGet(this,
|
|
65
|
-
__classPrivateFieldGet(this,
|
|
50
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_lastTrigger, "f") === notSetSymbol;
|
|
51
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_setPromise).call(this, setInputs.newPromise);
|
|
66
52
|
// force a re-render
|
|
67
|
-
__classPrivateFieldGet(this,
|
|
53
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_fireListeners).call(this);
|
|
68
54
|
}
|
|
69
55
|
else if ('resolvedValue' in setInputs) {
|
|
70
|
-
__classPrivateFieldGet(this,
|
|
56
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_resolveValue).call(this, setInputs.resolvedValue);
|
|
71
57
|
}
|
|
72
58
|
else if ('forceUpdate' in setInputs) {
|
|
73
|
-
__classPrivateFieldSet(this,
|
|
74
|
-
__classPrivateFieldSet(this,
|
|
75
|
-
if (!__classPrivateFieldGet(this,
|
|
76
|
-
__classPrivateFieldGet(this,
|
|
59
|
+
__classPrivateFieldSet(this, _AsyncObservablePropertyHandler_lastTrigger, notSetSymbol, "f");
|
|
60
|
+
__classPrivateFieldSet(this, _AsyncObservablePropertyHandler_resolutionValue, notSetSymbol, "f");
|
|
61
|
+
if (!__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_waitingForValuePromise, "f").isSettled()) {
|
|
62
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_waitingForValuePromise, "f").reject('Canceled by force update');
|
|
77
63
|
}
|
|
78
|
-
__classPrivateFieldGet(this,
|
|
64
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_resetWaitingForValuePromise).call(this);
|
|
79
65
|
// force a re-render
|
|
80
|
-
__classPrivateFieldGet(this,
|
|
66
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_fireListeners).call(this);
|
|
81
67
|
}
|
|
82
68
|
else {
|
|
83
69
|
this.resetValue(setInputs);
|
|
84
70
|
}
|
|
85
71
|
}
|
|
86
72
|
getValue() {
|
|
87
|
-
if (__classPrivateFieldGet(this,
|
|
88
|
-
if (__classPrivateFieldGet(this,
|
|
89
|
-
return __classPrivateFieldGet(this,
|
|
73
|
+
if (__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_waitingForValuePromise, "f").isSettled()) {
|
|
74
|
+
if (__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_rejectionError, "f") !== notSetSymbol) {
|
|
75
|
+
return __classPrivateFieldGet(this, _AsyncObservablePropertyHandler_rejectionError, "f");
|
|
90
76
|
}
|
|
91
|
-
else if (__classPrivateFieldGet(this,
|
|
77
|
+
else if (__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_resolutionValue, "f") === notSetSymbol) {
|
|
92
78
|
throw new Error('Promise says it has settled but resolution value was not set!');
|
|
93
79
|
}
|
|
94
80
|
else {
|
|
95
|
-
return __classPrivateFieldGet(this,
|
|
81
|
+
return __classPrivateFieldGet(this, _AsyncObservablePropertyHandler_resolutionValue, "f");
|
|
96
82
|
}
|
|
97
83
|
}
|
|
98
84
|
else {
|
|
99
|
-
return __classPrivateFieldGet(this,
|
|
85
|
+
return __classPrivateFieldGet(this, _AsyncObservablePropertyHandler_waitingForValuePromise, "f").promise;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
addListener(fireImmediately, listener) {
|
|
89
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_listeners, "f").add(listener);
|
|
90
|
+
if (fireImmediately) {
|
|
91
|
+
listener(this.getValue());
|
|
100
92
|
}
|
|
101
93
|
}
|
|
102
|
-
|
|
103
|
-
__classPrivateFieldGet(this,
|
|
94
|
+
addMultipleListeners(listeners) {
|
|
95
|
+
listeners.forEach((listener) => __classPrivateFieldGet(this, _AsyncObservablePropertyHandler_listeners, "f").add(listener));
|
|
104
96
|
}
|
|
105
|
-
|
|
106
|
-
|
|
97
|
+
getAllListeners() {
|
|
98
|
+
return __classPrivateFieldGet(this, _AsyncObservablePropertyHandler_listeners, "f");
|
|
99
|
+
}
|
|
100
|
+
removeListener(listener) {
|
|
101
|
+
if (__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_listeners, "f").has(listener)) {
|
|
102
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_listeners, "f").delete(listener);
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
removeAllListeners() {
|
|
110
|
+
const count = __classPrivateFieldGet(this, _AsyncObservablePropertyHandler_listeners, "f").size;
|
|
111
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_listeners, "f").clear();
|
|
112
|
+
return count;
|
|
107
113
|
}
|
|
108
114
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
115
|
+
_AsyncObservablePropertyHandler_lastTrigger = new WeakMap(), _AsyncObservablePropertyHandler_resolutionValue = new WeakMap(), _AsyncObservablePropertyHandler_rejectionError = new WeakMap(), _AsyncObservablePropertyHandler_listeners = new WeakMap(), _AsyncObservablePropertyHandler_lastSetPromise = new WeakMap(), _AsyncObservablePropertyHandler_waitingForValuePromise = new WeakMap(), _AsyncObservablePropertyHandler_instances = new WeakSet(), _a = observablePropertyHandlerMarkerKey, _AsyncObservablePropertyHandler_fireListeners = function _AsyncObservablePropertyHandler_fireListeners() {
|
|
116
|
+
const value = this.getValue();
|
|
117
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_listeners, "f").forEach((listener) => {
|
|
118
|
+
listener(value);
|
|
112
119
|
});
|
|
113
|
-
},
|
|
114
|
-
if (newPromise === __classPrivateFieldGet(this,
|
|
120
|
+
}, _AsyncObservablePropertyHandler_setPromise = function _AsyncObservablePropertyHandler_setPromise(newPromise) {
|
|
121
|
+
if (newPromise === __classPrivateFieldGet(this, _AsyncObservablePropertyHandler_lastSetPromise, "f")) {
|
|
115
122
|
// abort setting the promise if we already have set this promise
|
|
116
123
|
return;
|
|
117
124
|
}
|
|
118
|
-
__classPrivateFieldSet(this,
|
|
119
|
-
__classPrivateFieldSet(this,
|
|
120
|
-
__classPrivateFieldSet(this,
|
|
121
|
-
if (__classPrivateFieldGet(this,
|
|
122
|
-
__classPrivateFieldGet(this,
|
|
125
|
+
__classPrivateFieldSet(this, _AsyncObservablePropertyHandler_resolutionValue, notSetSymbol, "f");
|
|
126
|
+
__classPrivateFieldSet(this, _AsyncObservablePropertyHandler_rejectionError, notSetSymbol, "f");
|
|
127
|
+
__classPrivateFieldSet(this, _AsyncObservablePropertyHandler_lastSetPromise, newPromise, "f");
|
|
128
|
+
if (__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_waitingForValuePromise, "f").isSettled()) {
|
|
129
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_resetWaitingForValuePromise).call(this);
|
|
123
130
|
}
|
|
124
131
|
newPromise
|
|
125
132
|
.then((value) => {
|
|
126
133
|
// make sure we're still actually waiting for this promise
|
|
127
|
-
if (__classPrivateFieldGet(this,
|
|
128
|
-
__classPrivateFieldGet(this,
|
|
134
|
+
if (__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_lastSetPromise, "f") === newPromise) {
|
|
135
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_resolveValue).call(this, value);
|
|
129
136
|
}
|
|
130
137
|
})
|
|
131
138
|
.catch((reason) => {
|
|
132
139
|
// make sure we're still actually waiting for this promise
|
|
133
|
-
if (__classPrivateFieldGet(this,
|
|
134
|
-
__classPrivateFieldSet(this,
|
|
135
|
-
__classPrivateFieldGet(this,
|
|
140
|
+
if (__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_lastSetPromise, "f") === newPromise) {
|
|
141
|
+
__classPrivateFieldSet(this, _AsyncObservablePropertyHandler_rejectionError, ensureError(reason), "f");
|
|
142
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_waitingForValuePromise, "f").promise.catch(() => {
|
|
136
143
|
/**
|
|
137
144
|
* Don't actually do anything, we just want to make sure the error is
|
|
138
145
|
* handled so it doesn't throw errors in the browser.
|
|
139
146
|
*/
|
|
140
147
|
});
|
|
141
|
-
__classPrivateFieldGet(this,
|
|
142
|
-
__classPrivateFieldGet(this,
|
|
148
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_waitingForValuePromise, "f").reject(reason);
|
|
149
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_fireListeners).call(this);
|
|
143
150
|
}
|
|
144
151
|
});
|
|
145
|
-
},
|
|
146
|
-
if (value !== __classPrivateFieldGet(this,
|
|
147
|
-
__classPrivateFieldSet(this,
|
|
148
|
-
__classPrivateFieldSet(this,
|
|
149
|
-
if (__classPrivateFieldGet(this,
|
|
150
|
-
__classPrivateFieldGet(this,
|
|
152
|
+
}, _AsyncObservablePropertyHandler_resolveValue = function _AsyncObservablePropertyHandler_resolveValue(value) {
|
|
153
|
+
if (value !== __classPrivateFieldGet(this, _AsyncObservablePropertyHandler_resolutionValue, "f")) {
|
|
154
|
+
__classPrivateFieldSet(this, _AsyncObservablePropertyHandler_rejectionError, notSetSymbol, "f");
|
|
155
|
+
__classPrivateFieldSet(this, _AsyncObservablePropertyHandler_resolutionValue, value, "f");
|
|
156
|
+
if (__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_waitingForValuePromise, "f").isSettled()) {
|
|
157
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_resetWaitingForValuePromise).call(this);
|
|
151
158
|
}
|
|
152
|
-
__classPrivateFieldGet(this,
|
|
153
|
-
__classPrivateFieldGet(this,
|
|
159
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_waitingForValuePromise, "f").resolve(value);
|
|
160
|
+
__classPrivateFieldGet(this, _AsyncObservablePropertyHandler_instances, "m", _AsyncObservablePropertyHandler_fireListeners).call(this);
|
|
154
161
|
}
|
|
155
|
-
},
|
|
156
|
-
__classPrivateFieldSet(this,
|
|
162
|
+
}, _AsyncObservablePropertyHandler_resetWaitingForValuePromise = function _AsyncObservablePropertyHandler_resetWaitingForValuePromise() {
|
|
163
|
+
__classPrivateFieldSet(this, _AsyncObservablePropertyHandler_waitingForValuePromise, createDeferredPromiseWrapper(), "f");
|
|
157
164
|
};
|
|
158
|
-
export class AsyncStateInit {
|
|
159
|
-
constructor(initialValue) {
|
|
160
|
-
this.initialValue = initialValue;
|
|
161
|
-
this.asyncMarkerSymbol = asyncMarkerSymbol;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
165
|
export function asyncState(...args) {
|
|
166
|
+
/**
|
|
167
|
+
* Distinguish between an explicitly passed value of undefined or simply a lack of any arguments
|
|
168
|
+
* at all.
|
|
169
|
+
*/
|
|
165
170
|
const initValue = isLengthAtLeast(args, 1) ? args[0] : notSetSymbol;
|
|
166
|
-
return new
|
|
171
|
+
return new AsyncObservablePropertyHandler(initValue);
|
|
167
172
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isObservablePropertyHandler } from './observable-property/observable-property-handler';
|
|
2
2
|
function assertValidPropertyName(propKey, element, elementTagName) {
|
|
3
3
|
if (typeof propKey !== 'string' && typeof propKey !== 'number' && typeof propKey !== 'symbol') {
|
|
4
4
|
throw new Error(`Property name must be a string, got type '${typeof propKey}' from: '${String(propKey)}' for '${elementTagName.toLowerCase()}'`);
|
|
@@ -18,13 +18,7 @@ export function createElementUpdaterProxy(element, verifyExists) {
|
|
|
18
18
|
if (verifyExists) {
|
|
19
19
|
assertValidPropertyName(propertyKey, element, element.tagName);
|
|
20
20
|
}
|
|
21
|
-
|
|
22
|
-
if (asyncState) {
|
|
23
|
-
return asyncState.getValue();
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
return elementAsProps[propertyKey];
|
|
27
|
-
}
|
|
21
|
+
return elementAsProps[propertyKey];
|
|
28
22
|
}
|
|
29
23
|
const propsProxy = new Proxy({}, {
|
|
30
24
|
get: valueGetter,
|
|
@@ -32,33 +26,37 @@ export function createElementUpdaterProxy(element, verifyExists) {
|
|
|
32
26
|
if (verifyExists) {
|
|
33
27
|
assertValidPropertyName(propertyKey, element, element.tagName);
|
|
34
28
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
29
|
+
const existingObservablePropertyHandler = element.observablePropertyHandlerMap[propertyKey];
|
|
30
|
+
function setValueOnElement(value) {
|
|
31
|
+
/**
|
|
32
|
+
* We need to at least set the property on target so we can detect it in "ownKeys"
|
|
33
|
+
* and "getOwnPropertyDescriptor". We don't need duplicates of the values stored in
|
|
34
|
+
* target but doing so makes console logging more effective it actually works).
|
|
35
|
+
*/
|
|
36
|
+
target[propertyKey] = value;
|
|
37
|
+
elementAsProps[propertyKey] = value;
|
|
38
|
+
}
|
|
39
|
+
/** If we're creating a new observable property */
|
|
40
|
+
if (isObservablePropertyHandler(newValue)) {
|
|
41
|
+
if (existingObservablePropertyHandler &&
|
|
42
|
+
newValue !== existingObservablePropertyHandler) {
|
|
43
|
+
newValue.addMultipleListeners(existingObservablePropertyHandler.getAllListeners());
|
|
44
|
+
/** Remove listeners from old property handlers so they can be garbage collected. */
|
|
45
|
+
existingObservablePropertyHandler.removeAllListeners();
|
|
46
46
|
}
|
|
47
47
|
else {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
element[propertyKey] =
|
|
51
|
-
handler.getValue();
|
|
48
|
+
newValue.addListener(true, (newObservableValue) => {
|
|
49
|
+
setValueOnElement(newObservableValue);
|
|
52
50
|
});
|
|
53
|
-
element.asyncStateHandlerMap[propertyKey] = newHandler;
|
|
54
51
|
}
|
|
52
|
+
element.observablePropertyHandlerMap[propertyKey] = newValue;
|
|
55
53
|
}
|
|
56
54
|
else {
|
|
57
|
-
if (
|
|
58
|
-
|
|
55
|
+
if (existingObservablePropertyHandler) {
|
|
56
|
+
existingObservablePropertyHandler.setValue(newValue);
|
|
59
57
|
}
|
|
60
58
|
else {
|
|
61
|
-
|
|
59
|
+
setValueOnElement(newValue);
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
return true;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { observablePropertyHandlerMarkerKey, } from './observable-property-handler';
|
|
2
|
+
export function createObservableProperty(initValue) {
|
|
3
|
+
const listeners = new Set();
|
|
4
|
+
let value = initValue;
|
|
5
|
+
function fireListeners() {
|
|
6
|
+
listeners.forEach((listener) => listener(value));
|
|
7
|
+
}
|
|
8
|
+
const propertyHandler = {
|
|
9
|
+
[observablePropertyHandlerMarkerKey]: true,
|
|
10
|
+
setValue(newValue) {
|
|
11
|
+
if (value !== newValue) {
|
|
12
|
+
value = newValue;
|
|
13
|
+
fireListeners();
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
getValue() {
|
|
17
|
+
return value;
|
|
18
|
+
},
|
|
19
|
+
addListener(fireImmediately, listener) {
|
|
20
|
+
listeners.add(listener);
|
|
21
|
+
if (fireImmediately) {
|
|
22
|
+
listener(value);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
removeListener(listener) {
|
|
26
|
+
return listeners.delete(listener);
|
|
27
|
+
},
|
|
28
|
+
removeAllListeners() {
|
|
29
|
+
const size = listeners.size;
|
|
30
|
+
listeners.clear();
|
|
31
|
+
return size;
|
|
32
|
+
},
|
|
33
|
+
getAllListeners() {
|
|
34
|
+
return listeners;
|
|
35
|
+
},
|
|
36
|
+
addMultipleListeners(newListeners) {
|
|
37
|
+
newListeners.forEach((listener) => listeners.add(listener));
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
return propertyHandler;
|
|
41
|
+
}
|
package/dist/declarative-element/properties/observable-property/observable-property-handler.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { PropertyInitMapBase } from '../element-properties';
|
|
2
|
+
export declare const observablePropertyHandlerMarkerKey: "_is_element_vir_observable_property_handler";
|
|
3
|
+
export type ObservablePropertyListener<T> = (value: T) => void;
|
|
4
|
+
export type ObservablePropertyHandlerMap<OriginalPropertyMap extends PropertyInitMapBase> = Partial<Record<keyof OriginalPropertyMap, ObservablePropertyHandler<any, any>>>;
|
|
5
|
+
export type AllowObservablePropertySetter<OriginalPropertyMap extends PropertyInitMapBase> = {
|
|
6
|
+
[Prop in keyof OriginalPropertyMap]: OriginalPropertyMap[Prop] | ObservablePropertyHandler<any, Required<OriginalPropertyMap>[Prop]>;
|
|
7
|
+
};
|
|
8
|
+
export type FlattenObservablePropertyGetters<OriginalPropertyMap extends PropertyInitMapBase> = {
|
|
9
|
+
[Prop in keyof OriginalPropertyMap]: OriginalPropertyMap[Prop] extends ObservablePropertyHandler<infer SetValue, infer GetValue> ? GetValue : OriginalPropertyMap[Prop];
|
|
10
|
+
};
|
|
11
|
+
export type FlattenObservablePropertySetters<OriginalPropertyMap extends PropertyInitMapBase> = {
|
|
12
|
+
[Prop in keyof OriginalPropertyMap]: OriginalPropertyMap[Prop] extends ObservablePropertyHandler<infer SetValue, infer GetValue> ? SetValue : OriginalPropertyMap[Prop];
|
|
13
|
+
};
|
|
14
|
+
export type ObservablePropertyHandler<SetValue, GetValue> = {
|
|
15
|
+
[observablePropertyHandlerMarkerKey]: true;
|
|
16
|
+
setValue(input: SetValue): void;
|
|
17
|
+
getValue(): GetValue;
|
|
18
|
+
/** Add the given listener. */
|
|
19
|
+
addListener(fireImmediately: boolean, listener: ObservablePropertyListener<GetValue>): void;
|
|
20
|
+
/**
|
|
21
|
+
* Remove the given listener by reference. If the listener indeed existed and was removed, this
|
|
22
|
+
* function will return true. Otherwise, it returns false.
|
|
23
|
+
*/
|
|
24
|
+
removeListener(listener: ObservablePropertyListener<GetValue>): boolean;
|
|
25
|
+
/** Remove all previously added listeners. Returns the number of listeners removed. */
|
|
26
|
+
removeAllListeners(): number;
|
|
27
|
+
/**
|
|
28
|
+
* Get all currently attached listeners. This is used to attach listeners when a new handler
|
|
29
|
+
* needs to replace the current handler.
|
|
30
|
+
*/
|
|
31
|
+
getAllListeners(): ReadonlySet<ObservablePropertyListener<GetValue>>;
|
|
32
|
+
addMultipleListeners(listeners: ReadonlySet<ObservablePropertyListener<GetValue>>): void;
|
|
33
|
+
};
|
|
34
|
+
export declare function isObservablePropertyHandler(input: unknown): input is ObservablePropertyHandler<any, any>;
|
package/dist/declarative-element/properties/observable-property/observable-property-handler.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { typedHasProperty } from '@augment-vir/common';
|
|
2
|
+
export const observablePropertyHandlerMarkerKey = '_is_element_vir_observable_property_handler';
|
|
3
|
+
export function isObservablePropertyHandler(input) {
|
|
4
|
+
return (typedHasProperty(input, observablePropertyHandlerMarkerKey) &&
|
|
5
|
+
input[observablePropertyHandlerMarkerKey] === true);
|
|
6
|
+
}
|
|
@@ -1,18 +1,18 @@
|
|
|
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';
|
|
5
4
|
import { EventDescriptorMap, EventInitMapEventDetailExtractor, EventsInitMap } from './properties/element-events';
|
|
6
5
|
import { PropertyInitMapBase } from './properties/element-properties';
|
|
6
|
+
import { FlattenObservablePropertyGetters, FlattenObservablePropertySetters } from './properties/observable-property/observable-property-handler';
|
|
7
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;
|
|
8
8
|
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;
|
|
9
|
-
export type UpdateStateCallback<StateGeneric extends PropertyInitMapBase> = (newState: Partial<
|
|
9
|
+
export type UpdateStateCallback<StateGeneric extends PropertyInitMapBase> = (newState: Partial<FlattenObservablePropertySetters<StateGeneric>>) => void;
|
|
10
10
|
export type RenderParams<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string> = {
|
|
11
|
-
state: Readonly<
|
|
11
|
+
state: Readonly<FlattenObservablePropertyGetters<StateInitGeneric>>;
|
|
12
12
|
updateState: UpdateStateCallback<StateInitGeneric>;
|
|
13
13
|
events: EventDescriptorMap<EventsInitGeneric>;
|
|
14
14
|
host: HostInstanceType<TagNameGeneric, InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
|
|
15
15
|
dispatch: <EventTypeNameGeneric extends keyof EventsInitGeneric>(event: TypedEvent<EventTypeNameGeneric extends string ? EventTypeNameGeneric : never, EventInitMapEventDetailExtractor<EventTypeNameGeneric, EventsInitGeneric>> | Event) => boolean;
|
|
16
|
-
inputs: InputsGeneric
|
|
16
|
+
inputs: Readonly<FlattenObservablePropertyGetters<InputsGeneric>>;
|
|
17
17
|
};
|
|
18
18
|
export declare function createRenderParams<TagNameGeneric extends CustomElementTagName, InputsGeneric extends PropertyInitMapBase, StateGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string, RenderOutputGeneric>(element: DeclarativeElement<TagNameGeneric, InputsGeneric, StateGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys, RenderOutputGeneric>, eventsMap: EventDescriptorMap<EventsInitGeneric>): RenderParams<TagNameGeneric, InputsGeneric, StateGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export type { DeclarativeElementDefinitionOptions } from './declarative-element/
|
|
|
8
8
|
export * from './declarative-element/directives/assign-with-clean-up.directive';
|
|
9
9
|
export * from './declarative-element/directives/assign.directive';
|
|
10
10
|
export * from './declarative-element/directives/directive-helpers';
|
|
11
|
+
export * from './declarative-element/directives/is-render-ready.directive';
|
|
11
12
|
export * from './declarative-element/directives/listen.directive';
|
|
12
13
|
export * from './declarative-element/directives/on-dom-created.directive';
|
|
13
14
|
export * from './declarative-element/directives/on-resize.directive';
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export * from './declarative-element/define-element-no-inputs';
|
|
|
7
7
|
export * from './declarative-element/directives/assign-with-clean-up.directive';
|
|
8
8
|
export * from './declarative-element/directives/assign.directive';
|
|
9
9
|
export * from './declarative-element/directives/directive-helpers';
|
|
10
|
+
export * from './declarative-element/directives/is-render-ready.directive';
|
|
10
11
|
export * from './declarative-element/directives/listen.directive';
|
|
11
12
|
export * from './declarative-element/directives/on-dom-created.directive';
|
|
12
13
|
export * from './declarative-element/directives/on-resize.directive';
|