@zcomponent/core 0.0.12 → 0.0.13
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/lib/behavior.d.ts +9 -23
- package/lib/behavior.js +9 -51
- package/lib/component.d.ts +29 -21
- package/lib/component.js +31 -51
- package/lib/entity.d.ts +102 -0
- package/lib/entity.js +121 -0
- package/lib/types.d.ts +1 -0
- package/lib/types.js +12 -0
- package/package.json +1 -1
package/lib/behavior.d.ts
CHANGED
|
@@ -1,36 +1,22 @@
|
|
|
1
|
-
import { Component
|
|
1
|
+
import { Component } from './component';
|
|
2
2
|
import { ContextManager } from './context';
|
|
3
|
-
import {
|
|
4
|
-
import { Observable } from './observable';
|
|
5
|
-
import { ZComponent } from './zcomponent';
|
|
3
|
+
import { Entity } from './entity';
|
|
6
4
|
export type BehaviorConstructor<BehaviorType = Behavior, K extends Component = Component> = BehaviorType extends Behavior<K> ? new (contextManager: ContextManager, instance: K, ...args: any[]) => BehaviorType : never;
|
|
7
5
|
export type ConstructorPropsOfBehavior<BehaviorType> = BehaviorType extends Behavior<infer R> ? R : never;
|
|
8
6
|
export type BehaviorConstructorProps = {
|
|
9
7
|
[id: string]: unknown;
|
|
10
8
|
};
|
|
11
|
-
export declare class Behavior<InstanceType extends Component = Component> {
|
|
9
|
+
export declare class Behavior<InstanceType extends Component = Component> extends Entity {
|
|
12
10
|
protected readonly contextManager: ContextManager;
|
|
13
11
|
readonly instance: InstanceType;
|
|
14
|
-
private static callSuperDispose;
|
|
15
|
-
onDispose: Event<[]>;
|
|
16
|
-
private _registered;
|
|
17
|
-
private _zcomponent;
|
|
18
|
-
constructor(contextManager: ContextManager, instance: InstanceType);
|
|
19
|
-
getZComponentInstance<T extends ZComponent = ZComponent>(type?: ConstructorForComponent<T>): T;
|
|
20
|
-
private _updateEnabledResolved;
|
|
21
12
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* @
|
|
25
|
-
* @
|
|
13
|
+
* Constructs this behavior
|
|
14
|
+
*
|
|
15
|
+
* @param contextManager The current ContextManager
|
|
16
|
+
* @param instance The instance of the component that this behavior is attached to
|
|
26
17
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
|
|
30
|
-
register<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
|
|
31
|
-
unregister<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
|
|
32
|
-
unregister<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
|
|
33
|
-
dispose(): never;
|
|
18
|
+
constructor(contextManager: ContextManager, instance: InstanceType);
|
|
19
|
+
private _updateEnabledResolved;
|
|
34
20
|
}
|
|
35
21
|
export declare function shouldBehaviorRunAtDesignTime(b: BehaviorConstructor): boolean;
|
|
36
22
|
export declare function registerBehaviorRunAtDesignTime(b: BehaviorConstructor): Set<new (contextManager: ContextManager, instance: Component<any, import("./component").ConstructorProps>, ...args: any[]) => Behavior<Component<any, import("./component").ConstructorProps>>>;
|
package/lib/behavior.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { Entity } from './entity';
|
|
2
|
+
export class Behavior extends Entity {
|
|
3
|
+
/**
|
|
4
|
+
* Constructs this behavior
|
|
5
|
+
*
|
|
6
|
+
* @param contextManager The current ContextManager
|
|
7
|
+
* @param instance The instance of the component that this behavior is attached to
|
|
8
|
+
*/
|
|
5
9
|
constructor(contextManager, instance) {
|
|
10
|
+
super();
|
|
6
11
|
this.contextManager = contextManager;
|
|
7
12
|
this.instance = instance;
|
|
8
|
-
this.onDispose = new Event();
|
|
9
|
-
this._registered = [];
|
|
10
13
|
this._updateEnabledResolved = () => {
|
|
11
14
|
let newValue = this.enabled.value;
|
|
12
15
|
if (this.instance.enabledResolved?.value === false)
|
|
@@ -15,55 +18,10 @@ export class Behavior {
|
|
|
15
18
|
this.enabledResolved.value = newValue;
|
|
16
19
|
}
|
|
17
20
|
};
|
|
18
|
-
/**
|
|
19
|
-
* @zprop
|
|
20
|
-
* @zdefault true
|
|
21
|
-
* @zgroup Behavior
|
|
22
|
-
* @zgrouppriority 10
|
|
23
|
-
*/
|
|
24
|
-
this.enabled = new Observable(true);
|
|
25
|
-
this.enabledResolved = new Observable(true);
|
|
26
|
-
this._zcomponent = getCurrentZComponentConstruction();
|
|
27
21
|
this.register(this.enabled, this._updateEnabledResolved);
|
|
28
22
|
this.register(instance.enabledResolved, this._updateEnabledResolved);
|
|
29
23
|
}
|
|
30
|
-
getZComponentInstance(type) {
|
|
31
|
-
if (this._zcomponent === undefined)
|
|
32
|
-
throw new Error("getZComponentInstance called in behavior that's not part of a ZComponent");
|
|
33
|
-
if (!type)
|
|
34
|
-
return this._zcomponent;
|
|
35
|
-
if (this._zcomponent instanceof type)
|
|
36
|
-
return this._zcomponent;
|
|
37
|
-
throw new Error("getZComponentInstance called in behavior passing wrong kind of ZComponent");
|
|
38
|
-
}
|
|
39
|
-
register(e, fn) {
|
|
40
|
-
if (e instanceof Event)
|
|
41
|
-
e.bindfn(fn);
|
|
42
|
-
else if (e instanceof Observable)
|
|
43
|
-
e.withValue(fn);
|
|
44
|
-
this._registered.push([e, fn]);
|
|
45
|
-
}
|
|
46
|
-
unregister(e, fn) {
|
|
47
|
-
if (e instanceof Event)
|
|
48
|
-
e.unbindfn(fn);
|
|
49
|
-
else if (e instanceof Observable)
|
|
50
|
-
e.removeWithValue(fn);
|
|
51
|
-
this._registered = this._registered.filter(entry => (entry[0] !== e || entry[1] !== fn));
|
|
52
|
-
}
|
|
53
|
-
dispose() {
|
|
54
|
-
for (const entry of this._registered) {
|
|
55
|
-
if (entry[0] instanceof Event)
|
|
56
|
-
entry[0].unbindfn(entry[1]);
|
|
57
|
-
else if (entry[0] instanceof Observable)
|
|
58
|
-
entry[0].removeWithValue(entry[1]);
|
|
59
|
-
}
|
|
60
|
-
this._registered = [];
|
|
61
|
-
this.onDispose.emit();
|
|
62
|
-
this.onDispose.clear();
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
24
|
}
|
|
66
|
-
Behavior.callSuperDispose = Symbol('Calling super.dispose() is mandatory');
|
|
67
25
|
const behaviorsToRunAtDesignTime = new Set();
|
|
68
26
|
export function shouldBehaviorRunAtDesignTime(b) {
|
|
69
27
|
return behaviorsToRunAtDesignTime.has(b);
|
package/lib/component.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ContextManager } from './context';
|
|
2
|
-
import {
|
|
2
|
+
import { Entity } from './entity';
|
|
3
3
|
import { Observable } from './observable';
|
|
4
|
-
import { ZComponent } from './zcomponent';
|
|
5
4
|
export type ConstructorPropsOfComponent<ComponentType> = ComponentType extends Component<any, infer R> ? R : never;
|
|
6
5
|
export type ComponentConstructor<ConstructorPropsType extends ConstructorProps, ComponentType extends Component> = new (props: ConstructorPropsType, contextManager: ContextManager) => ComponentType;
|
|
7
6
|
export type ConstructorForComponent<ComponentType extends Component = Component> = new (contextManager: ContextManager, props: ComponentType extends Component<any, infer PropsType> ? PropsType : never) => ComponentType;
|
|
@@ -15,45 +14,54 @@ export interface ConstructorProps {
|
|
|
15
14
|
[id: string]: any;
|
|
16
15
|
children?: ComponentChildren;
|
|
17
16
|
}
|
|
18
|
-
export declare class Component<ElementType = any, ConstructorPropsType extends ConstructorProps = ConstructorProps> {
|
|
17
|
+
export declare class Component<ElementType = any, ConstructorPropsType extends ConstructorProps = ConstructorProps> extends Entity {
|
|
19
18
|
readonly contextManager: ContextManager;
|
|
20
19
|
protected constructorProps?: ConstructorPropsType | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* The raw element(s) that this component exposes
|
|
22
|
+
*/
|
|
21
23
|
element?: ElementType;
|
|
22
|
-
readonly onDispose: Event<[]>;
|
|
23
24
|
readonly children: Component[];
|
|
24
25
|
parent?: Component;
|
|
25
|
-
disposed: boolean;
|
|
26
|
-
private _registered;
|
|
27
|
-
private _zcomponent;
|
|
28
26
|
constructor(contextManager: ContextManager, constructorProps?: ConstructorPropsType | undefined);
|
|
29
27
|
constructChildren(children: ComponentChildren, contextManager?: ContextManager): void;
|
|
30
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Adds the supplied component instance as a child of this component, removing it from any existing parent.
|
|
30
|
+
*
|
|
31
|
+
* @param c The component instance to add
|
|
32
|
+
*/
|
|
31
33
|
appendChild(c: Component): void;
|
|
34
|
+
/**
|
|
35
|
+
* Removes the supplied component instance from the list of children.
|
|
36
|
+
* @param c The component to remove
|
|
37
|
+
*/
|
|
32
38
|
removeChild(c: Component): void;
|
|
39
|
+
/**
|
|
40
|
+
* Removes this component from its parent component.
|
|
41
|
+
*/
|
|
33
42
|
remove(): void;
|
|
34
|
-
get elementsResolved(): any[];
|
|
35
43
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* @group Behavior
|
|
40
|
-
* @zgrouppriority 10
|
|
44
|
+
* An array of the elements that this component instance exposes. In the case that this component
|
|
45
|
+
* does not expose any elements of its own, this will be an array of the elements
|
|
46
|
+
* exposed by this component's children.
|
|
41
47
|
*/
|
|
42
|
-
|
|
43
|
-
enabledResolved: Observable<boolean, never>;
|
|
48
|
+
get elementsResolved(): any[];
|
|
44
49
|
/**
|
|
50
|
+
* An array of string 'tags' assocated with this component.
|
|
51
|
+
*
|
|
52
|
+
* The `getComponentsByTag(mgr, tag)` function can be used to get an array of components
|
|
53
|
+
* with the supplied tag.
|
|
54
|
+
*
|
|
55
|
+
* By default, tags are scoped to the ZComponent instance that a component is constructed by.
|
|
56
|
+
* Tags that begin with `global:` are scoped to the experience as a whole.
|
|
57
|
+
*
|
|
45
58
|
* @zprop
|
|
46
59
|
* @zgroup Other
|
|
47
60
|
* @group Other
|
|
48
61
|
* @zgrouppriority 0
|
|
49
62
|
*/
|
|
50
63
|
tags: Observable<string[], never>;
|
|
51
|
-
protected register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
|
|
52
|
-
protected register<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
|
|
53
|
-
protected unregister<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
|
|
54
|
-
protected unregister<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
|
|
55
64
|
private _updateEnabledResolved;
|
|
56
65
|
private _updateTags;
|
|
57
66
|
dispose(): never;
|
|
58
|
-
private static callSuperDispose;
|
|
59
67
|
}
|
package/lib/component.js
CHANGED
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
import { TagContext } from './contexts/tagcontext';
|
|
2
|
-
import {
|
|
2
|
+
import { Entity } from './entity';
|
|
3
3
|
import { Observable } from './observable';
|
|
4
|
-
|
|
5
|
-
export class Component {
|
|
4
|
+
export class Component extends Entity {
|
|
6
5
|
constructor(contextManager, constructorProps) {
|
|
6
|
+
super();
|
|
7
7
|
this.contextManager = contextManager;
|
|
8
8
|
this.constructorProps = constructorProps;
|
|
9
|
-
this.onDispose = new Event();
|
|
10
9
|
this.children = [];
|
|
11
|
-
this.disposed = false;
|
|
12
|
-
this._registered = [];
|
|
13
|
-
/**
|
|
14
|
-
* @zprop
|
|
15
|
-
* @zdefault true
|
|
16
|
-
* @zgroup Behavior
|
|
17
|
-
* @group Behavior
|
|
18
|
-
* @zgrouppriority 10
|
|
19
|
-
*/
|
|
20
|
-
this.enabled = new Observable(true);
|
|
21
|
-
this.enabledResolved = new Observable(true);
|
|
22
10
|
/**
|
|
11
|
+
* An array of string 'tags' assocated with this component.
|
|
12
|
+
*
|
|
13
|
+
* The `getComponentsByTag(mgr, tag)` function can be used to get an array of components
|
|
14
|
+
* with the supplied tag.
|
|
15
|
+
*
|
|
16
|
+
* By default, tags are scoped to the ZComponent instance that a component is constructed by.
|
|
17
|
+
* Tags that begin with `global:` are scoped to the experience as a whole.
|
|
18
|
+
*
|
|
23
19
|
* @zprop
|
|
24
20
|
* @zgroup Other
|
|
25
21
|
* @group Other
|
|
@@ -40,7 +36,6 @@ export class Component {
|
|
|
40
36
|
const context = this.contextManager.get(TagContext);
|
|
41
37
|
context.registerComponent(this, this.tags.value);
|
|
42
38
|
};
|
|
43
|
-
this._zcomponent = getCurrentZComponentConstruction();
|
|
44
39
|
this.constructChildren(constructorProps?.children ?? []);
|
|
45
40
|
this.register(this.enabled, this._updateEnabledResolved);
|
|
46
41
|
this.register(this.tags, this._updateTags);
|
|
@@ -59,29 +54,39 @@ export class Component {
|
|
|
59
54
|
}
|
|
60
55
|
}
|
|
61
56
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (this._zcomponent instanceof type)
|
|
68
|
-
return this._zcomponent;
|
|
69
|
-
throw new Error("getZComponentInstance called in component passing wrong kind of ZComponent");
|
|
70
|
-
}
|
|
57
|
+
/**
|
|
58
|
+
* Adds the supplied component instance as a child of this component, removing it from any existing parent.
|
|
59
|
+
*
|
|
60
|
+
* @param c The component instance to add
|
|
61
|
+
*/
|
|
71
62
|
appendChild(c) {
|
|
72
63
|
c.remove();
|
|
73
64
|
this.children.push(c);
|
|
74
65
|
c.parent = this;
|
|
75
66
|
c._updateEnabledResolved();
|
|
76
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Removes the supplied component instance from the list of children.
|
|
70
|
+
* @param c The component to remove
|
|
71
|
+
*/
|
|
77
72
|
removeChild(c) {
|
|
78
73
|
const indx = this.children.indexOf(c);
|
|
79
74
|
if (indx >= 0)
|
|
80
75
|
this.children.splice(indx, 1);
|
|
76
|
+
if (c.parent === this)
|
|
77
|
+
delete c.parent;
|
|
81
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Removes this component from its parent component.
|
|
81
|
+
*/
|
|
82
82
|
remove() {
|
|
83
83
|
this.parent?.removeChild(this);
|
|
84
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* An array of the elements that this component instance exposes. In the case that this component
|
|
87
|
+
* does not expose any elements of its own, this will be an array of the elements
|
|
88
|
+
* exposed by this component's children.
|
|
89
|
+
*/
|
|
85
90
|
get elementsResolved() {
|
|
86
91
|
if (this.element !== undefined) {
|
|
87
92
|
if (Array.isArray(this.element))
|
|
@@ -94,22 +99,7 @@ export class Component {
|
|
|
94
99
|
}
|
|
95
100
|
return ret;
|
|
96
101
|
}
|
|
97
|
-
register(e, fn) {
|
|
98
|
-
if (e instanceof Event)
|
|
99
|
-
e.bindfn(fn);
|
|
100
|
-
else if (e instanceof Observable)
|
|
101
|
-
e.withValue(fn);
|
|
102
|
-
this._registered.push([e, fn]);
|
|
103
|
-
}
|
|
104
|
-
unregister(e, fn) {
|
|
105
|
-
if (e instanceof Event)
|
|
106
|
-
e.unbindfn(fn);
|
|
107
|
-
else if (e instanceof Observable)
|
|
108
|
-
e.removeWithValue(fn);
|
|
109
|
-
this._registered = this._registered.filter(entry => (entry[0] !== e || entry[1] !== fn));
|
|
110
|
-
}
|
|
111
102
|
dispose() {
|
|
112
|
-
this.disposed = true;
|
|
113
103
|
for (const child of this.children) {
|
|
114
104
|
try {
|
|
115
105
|
child.dispose();
|
|
@@ -117,17 +107,7 @@ export class Component {
|
|
|
117
107
|
catch (err) { }
|
|
118
108
|
}
|
|
119
109
|
this.children.length = 0;
|
|
120
|
-
for (const entry of this._registered) {
|
|
121
|
-
if (entry[0] instanceof Event)
|
|
122
|
-
entry[0].unbindfn(entry[1]);
|
|
123
|
-
else if (entry[0] instanceof Observable)
|
|
124
|
-
entry[0].removeWithValue(entry[1]);
|
|
125
|
-
}
|
|
126
|
-
this._registered = [];
|
|
127
|
-
this.onDispose.emit();
|
|
128
|
-
this.onDispose.clear();
|
|
129
110
|
this.contextManager.get(TagContext).unregisterComponent(this);
|
|
130
|
-
return
|
|
111
|
+
return super.dispose();
|
|
131
112
|
}
|
|
132
113
|
}
|
|
133
|
-
Component.callSuperDispose = Symbol('Calling super.dispose() is mandatory');
|
package/lib/entity.d.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { ConstructorForComponent } from "./component";
|
|
2
|
+
import { Event } from "./event";
|
|
3
|
+
import { Observable } from "./observable";
|
|
4
|
+
import { ZComponent } from "./zcomponent";
|
|
5
|
+
export declare class Entity {
|
|
6
|
+
private _registered;
|
|
7
|
+
private _zcomponent;
|
|
8
|
+
private _disposed;
|
|
9
|
+
/**
|
|
10
|
+
* An event that is fired as the last act of this entity being destroyed.
|
|
11
|
+
*/
|
|
12
|
+
readonly onDispose: Event<[]>;
|
|
13
|
+
constructor();
|
|
14
|
+
get disposed(): boolean;
|
|
15
|
+
private set disposed(value);
|
|
16
|
+
/**
|
|
17
|
+
* If `false`, this entity and its children will no longer participate in the experience.
|
|
18
|
+
*
|
|
19
|
+
* Note - to read this value, you may wish to use `enabledResolved` which will be `false` if
|
|
20
|
+
* this entity, or any of its parents, have `enabled` set to false.
|
|
21
|
+
*
|
|
22
|
+
* The precise implications of `enabled` being false will vary between entities,
|
|
23
|
+
* but in general disabled entities:
|
|
24
|
+
* - should not emit any events,
|
|
25
|
+
* - should not take any action, e.g. navigate the user to a different page,
|
|
26
|
+
* - should not perform any network communication,
|
|
27
|
+
* - should not make changes to other behaviors or components in the experience,
|
|
28
|
+
* - should minimise any runtime performance cost (e.g. detach from any frame handlers).
|
|
29
|
+
*
|
|
30
|
+
* @zprop
|
|
31
|
+
* @zdefault true
|
|
32
|
+
* @zgroup Behavior
|
|
33
|
+
* @zgrouppriority 10
|
|
34
|
+
*/
|
|
35
|
+
enabled: Observable<boolean, never>;
|
|
36
|
+
/**
|
|
37
|
+
* This will have value `false` if this entity, or any of its parents, have `enabled` set to `false`.
|
|
38
|
+
*
|
|
39
|
+
* To change the `enabled` status of this entity, use the `enabled` property instead.
|
|
40
|
+
*
|
|
41
|
+
* The precise implications of `enabled` being false will vary between entities,
|
|
42
|
+
* but in general disabled entities:
|
|
43
|
+
* - should not emit any events,
|
|
44
|
+
* - should not take any action, e.g. navigate the user to a different page,
|
|
45
|
+
* - should not perform any network communication,
|
|
46
|
+
* - should not make changes to other behaviors or components in the experience,
|
|
47
|
+
* - should minimise any runtime performance cost.
|
|
48
|
+
*
|
|
49
|
+
* Disabled entities will typically remain visible (if they have a visible appearance).
|
|
50
|
+
*/
|
|
51
|
+
enabledResolved: Observable<boolean, never>;
|
|
52
|
+
/**
|
|
53
|
+
* Get the instance of the ZComponent that constructed this entity.
|
|
54
|
+
*
|
|
55
|
+
* If you pass the class of a ZComponent as the `type` parameter, this function will ensure that it
|
|
56
|
+
* returns an instance of that ZComponent. If this component or behavior was constructed by a different
|
|
57
|
+
* ZComponent class, or by a different entity altogether, the function with `throw` an error.
|
|
58
|
+
*
|
|
59
|
+
* @param type The ZComponent class that you are expecting to receive
|
|
60
|
+
* @returns The instance of the ZComponent that constructed this component or behavior
|
|
61
|
+
*/
|
|
62
|
+
getZComponentInstance<T extends ZComponent = ZComponent>(type?: ConstructorForComponent<T>): T;
|
|
63
|
+
/**
|
|
64
|
+
* Register a function to be called when an Event is fired, or an Observable's value changes.
|
|
65
|
+
*
|
|
66
|
+
* Using this function, rather than attaching your handler directly to the Event or Observable,
|
|
67
|
+
* ensures your handler is automatically released when this entity is disposed.
|
|
68
|
+
*
|
|
69
|
+
* @param evt The Event or Observable to listen to
|
|
70
|
+
* @param fn A function that will be called when the event fires, or the Observable value changes
|
|
71
|
+
*/
|
|
72
|
+
register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
|
|
73
|
+
register<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
|
|
74
|
+
/**
|
|
75
|
+
* Unregisters a function that was previously registered to an Event or Observable.
|
|
76
|
+
*
|
|
77
|
+
* @param evt The Event or Observable
|
|
78
|
+
* @param fn The function that was passed in the call to `register`
|
|
79
|
+
*/
|
|
80
|
+
unregister<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
|
|
81
|
+
unregister<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
|
|
82
|
+
/**
|
|
83
|
+
* Destroy this entity, cleaning up any resources that it has created and
|
|
84
|
+
* handler functions or callbacks it has registered.
|
|
85
|
+
*
|
|
86
|
+
* The base class implementation automatically unregisters any handler functions registered
|
|
87
|
+
* using `register(...)`.
|
|
88
|
+
*
|
|
89
|
+
* Override this function in your own components and behaviors to clean up any resources
|
|
90
|
+
* you have created. If you do override this function, end it with:
|
|
91
|
+
*
|
|
92
|
+
* ```
|
|
93
|
+
* return super.dispose();
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* This ensures that the dispose implementation of the parent class runs.
|
|
97
|
+
*
|
|
98
|
+
* @returns The result of a call to super.dispose()
|
|
99
|
+
*/
|
|
100
|
+
dispose(): never;
|
|
101
|
+
private static callSuperDispose;
|
|
102
|
+
}
|
package/lib/entity.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Event } from "./event";
|
|
2
|
+
import { Observable } from "./observable";
|
|
3
|
+
import { getCurrentZComponentConstruction } from "./zcomponentconstruction";
|
|
4
|
+
export class Entity {
|
|
5
|
+
constructor() {
|
|
6
|
+
this._registered = [];
|
|
7
|
+
this._disposed = false;
|
|
8
|
+
/**
|
|
9
|
+
* An event that is fired as the last act of this entity being destroyed.
|
|
10
|
+
*/
|
|
11
|
+
this.onDispose = new Event();
|
|
12
|
+
/**
|
|
13
|
+
* If `false`, this entity and its children will no longer participate in the experience.
|
|
14
|
+
*
|
|
15
|
+
* Note - to read this value, you may wish to use `enabledResolved` which will be `false` if
|
|
16
|
+
* this entity, or any of its parents, have `enabled` set to false.
|
|
17
|
+
*
|
|
18
|
+
* The precise implications of `enabled` being false will vary between entities,
|
|
19
|
+
* but in general disabled entities:
|
|
20
|
+
* - should not emit any events,
|
|
21
|
+
* - should not take any action, e.g. navigate the user to a different page,
|
|
22
|
+
* - should not perform any network communication,
|
|
23
|
+
* - should not make changes to other behaviors or components in the experience,
|
|
24
|
+
* - should minimise any runtime performance cost (e.g. detach from any frame handlers).
|
|
25
|
+
*
|
|
26
|
+
* @zprop
|
|
27
|
+
* @zdefault true
|
|
28
|
+
* @zgroup Behavior
|
|
29
|
+
* @zgrouppriority 10
|
|
30
|
+
*/
|
|
31
|
+
this.enabled = new Observable(true);
|
|
32
|
+
/**
|
|
33
|
+
* This will have value `false` if this entity, or any of its parents, have `enabled` set to `false`.
|
|
34
|
+
*
|
|
35
|
+
* To change the `enabled` status of this entity, use the `enabled` property instead.
|
|
36
|
+
*
|
|
37
|
+
* The precise implications of `enabled` being false will vary between entities,
|
|
38
|
+
* but in general disabled entities:
|
|
39
|
+
* - should not emit any events,
|
|
40
|
+
* - should not take any action, e.g. navigate the user to a different page,
|
|
41
|
+
* - should not perform any network communication,
|
|
42
|
+
* - should not make changes to other behaviors or components in the experience,
|
|
43
|
+
* - should minimise any runtime performance cost.
|
|
44
|
+
*
|
|
45
|
+
* Disabled entities will typically remain visible (if they have a visible appearance).
|
|
46
|
+
*/
|
|
47
|
+
this.enabledResolved = new Observable(true);
|
|
48
|
+
this._zcomponent = getCurrentZComponentConstruction();
|
|
49
|
+
}
|
|
50
|
+
get disposed() {
|
|
51
|
+
return this._disposed;
|
|
52
|
+
}
|
|
53
|
+
set disposed(v) {
|
|
54
|
+
this._disposed = v;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get the instance of the ZComponent that constructed this entity.
|
|
58
|
+
*
|
|
59
|
+
* If you pass the class of a ZComponent as the `type` parameter, this function will ensure that it
|
|
60
|
+
* returns an instance of that ZComponent. If this component or behavior was constructed by a different
|
|
61
|
+
* ZComponent class, or by a different entity altogether, the function with `throw` an error.
|
|
62
|
+
*
|
|
63
|
+
* @param type The ZComponent class that you are expecting to receive
|
|
64
|
+
* @returns The instance of the ZComponent that constructed this component or behavior
|
|
65
|
+
*/
|
|
66
|
+
getZComponentInstance(type) {
|
|
67
|
+
if (this._zcomponent === undefined)
|
|
68
|
+
throw new Error("getZComponentInstance called in entity that's not part of a ZComponent");
|
|
69
|
+
if (!type)
|
|
70
|
+
return this._zcomponent;
|
|
71
|
+
if (this._zcomponent instanceof type)
|
|
72
|
+
return this._zcomponent;
|
|
73
|
+
throw new Error("getZComponentInstance called in entity passing wrong kind of ZComponent");
|
|
74
|
+
}
|
|
75
|
+
register(e, fn) {
|
|
76
|
+
if (e instanceof Event)
|
|
77
|
+
e.bindfn(fn);
|
|
78
|
+
else if (e instanceof Observable)
|
|
79
|
+
e.withValue(fn);
|
|
80
|
+
this._registered.push([e, fn]);
|
|
81
|
+
}
|
|
82
|
+
unregister(e, fn) {
|
|
83
|
+
if (e instanceof Event)
|
|
84
|
+
e.unbindfn(fn);
|
|
85
|
+
else if (e instanceof Observable)
|
|
86
|
+
e.removeWithValue(fn);
|
|
87
|
+
this._registered = this._registered.filter(entry => (entry[0] !== e || entry[1] !== fn));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Destroy this entity, cleaning up any resources that it has created and
|
|
91
|
+
* handler functions or callbacks it has registered.
|
|
92
|
+
*
|
|
93
|
+
* The base class implementation automatically unregisters any handler functions registered
|
|
94
|
+
* using `register(...)`.
|
|
95
|
+
*
|
|
96
|
+
* Override this function in your own components and behaviors to clean up any resources
|
|
97
|
+
* you have created. If you do override this function, end it with:
|
|
98
|
+
*
|
|
99
|
+
* ```
|
|
100
|
+
* return super.dispose();
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* This ensures that the dispose implementation of the parent class runs.
|
|
104
|
+
*
|
|
105
|
+
* @returns The result of a call to super.dispose()
|
|
106
|
+
*/
|
|
107
|
+
dispose() {
|
|
108
|
+
for (const entry of this._registered) {
|
|
109
|
+
if (entry[0] instanceof Event)
|
|
110
|
+
entry[0].unbindfn(entry[1]);
|
|
111
|
+
else if (entry[0] instanceof Observable)
|
|
112
|
+
entry[0].removeWithValue(entry[1]);
|
|
113
|
+
}
|
|
114
|
+
this._registered = [];
|
|
115
|
+
this.onDispose.emit();
|
|
116
|
+
this.onDispose.clear();
|
|
117
|
+
this.disposed = true;
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
Entity.callSuperDispose = Symbol('Calling super.dispose() is mandatory');
|
package/lib/types.d.ts
CHANGED
package/lib/types.js
CHANGED
|
@@ -124,6 +124,17 @@ function mergeValueComments(a, b) {
|
|
|
124
124
|
}
|
|
125
125
|
return ret;
|
|
126
126
|
}
|
|
127
|
+
function mergeTupleNames(a, b) {
|
|
128
|
+
if (!a.names || !b.names)
|
|
129
|
+
return;
|
|
130
|
+
if (a.names.length !== b.names.length)
|
|
131
|
+
return;
|
|
132
|
+
for (let i = 0; i < a.names.length; i++) {
|
|
133
|
+
if (a.names[i] !== b.names[i])
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
return a.names;
|
|
137
|
+
}
|
|
127
138
|
export function mergeTypes(a, b) {
|
|
128
139
|
if (!areTypesCompatible(a, b))
|
|
129
140
|
return;
|
|
@@ -192,6 +203,7 @@ export function mergeTypes(a, b) {
|
|
|
192
203
|
typeHint,
|
|
193
204
|
comments: mergeComments(a.comments ?? [], b.comments ?? []),
|
|
194
205
|
children,
|
|
206
|
+
names: mergeTupleNames(a, b),
|
|
195
207
|
};
|
|
196
208
|
}
|
|
197
209
|
case 'union':
|