@zcomponent/core 0.0.14 → 0.0.16
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/actionbehavior.js +2 -2
- package/lib/behavior.js +2 -2
- package/lib/component.js +2 -2
- package/lib/contexts/canvascontext.js +3 -3
- package/lib/emitter.d.ts +23 -0
- package/lib/emitter.js +62 -0
- package/lib/entity.d.ts +11 -2
- package/lib/entity.js +31 -15
- package/lib/event.d.ts +6 -16
- package/lib/event.js +19 -50
- package/lib/observable.d.ts +3 -6
- package/lib/observable.js +7 -32
- package/lib/selectors.js +2 -2
- package/lib/zcomponent.d.ts +1 -0
- package/lib/zcomponent.js +7 -4
- package/package.json +1 -1
package/lib/actionbehavior.js
CHANGED
|
@@ -24,7 +24,7 @@ export class ActionBehavior extends Behavior {
|
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
26
|
const env = contextManager.get(EnvironmentContext);
|
|
27
|
-
this.register(env.editTime, this._updateRegistration);
|
|
28
|
-
this.register(this.enabledResolved, this._updateRegistration);
|
|
27
|
+
this.register(env.editTime, this._updateRegistration, { bindWhenDisabled: true });
|
|
28
|
+
this.register(this.enabledResolved, this._updateRegistration, { bindWhenDisabled: true });
|
|
29
29
|
}
|
|
30
30
|
}
|
package/lib/behavior.js
CHANGED
|
@@ -17,8 +17,8 @@ export class Behavior extends Entity {
|
|
|
17
17
|
this.enabledResolved.value = newValue;
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
|
-
this.register(this.enabled, this._updateEnabledResolved);
|
|
21
|
-
this.register(instance.enabledResolved, this._updateEnabledResolved);
|
|
20
|
+
this.register(this.enabled, this._updateEnabledResolved, { bindWhenDisabled: true });
|
|
21
|
+
this.register(instance.enabledResolved, this._updateEnabledResolved, { bindWhenDisabled: true });
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
const behaviorsToRunAtDesignTime = new Set();
|
package/lib/component.js
CHANGED
|
@@ -36,8 +36,8 @@ export class Component extends Entity {
|
|
|
36
36
|
context.registerComponent(this, this.tags.value);
|
|
37
37
|
};
|
|
38
38
|
this.constructChildren(constructorProps?.children ?? []);
|
|
39
|
-
this.register(this.enabled, this._updateEnabledResolved);
|
|
40
|
-
this.register(this.tags, this._updateTags);
|
|
39
|
+
this.register(this.enabled, this._updateEnabledResolved, { bindWhenDisabled: true });
|
|
40
|
+
this.register(this.tags, this._updateTags, { bindWhenDisabled: true });
|
|
41
41
|
}
|
|
42
42
|
constructChildren(children, contextManager) {
|
|
43
43
|
contextManager = contextManager ?? this.contextManager;
|
|
@@ -37,7 +37,7 @@ export class CanvasContext extends Context {
|
|
|
37
37
|
this.size = new Observable([this.canvas.clientWidth, this.canvas.clientHeight]);
|
|
38
38
|
this._resizeObserver.observe(this.canvas);
|
|
39
39
|
let lastRect;
|
|
40
|
-
this.onBeforeRender.
|
|
40
|
+
this.onBeforeRender.addListener(() => {
|
|
41
41
|
const rect = this.canvas.getBoundingClientRect();
|
|
42
42
|
if (lastRect && lastRect.top === rect.top && lastRect.left === rect.left && lastRect.width === rect.width && lastRect.height === rect.height)
|
|
43
43
|
return;
|
|
@@ -49,8 +49,8 @@ export class CanvasContext extends Context {
|
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
dispose() {
|
|
52
|
-
this.onBeforeRender.
|
|
53
|
-
this.onAfterRender.
|
|
52
|
+
this.onBeforeRender.clearListeners();
|
|
53
|
+
this.onAfterRender.clearListeners();
|
|
54
54
|
this._resizeObserver.disconnect();
|
|
55
55
|
if (!this.constructorProps.canvas)
|
|
56
56
|
this.canvas.remove();
|
package/lib/emitter.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare class Emitter<Args extends Array<any> = []> {
|
|
2
|
+
protected _funcs: [fn: ((...args: Args) => void), priority: number][];
|
|
3
|
+
private _emitting;
|
|
4
|
+
private _toUnbind;
|
|
5
|
+
private _needsSort;
|
|
6
|
+
clearListeners(): void;
|
|
7
|
+
/**
|
|
8
|
+
* Add a new handler function
|
|
9
|
+
* @param f - The callback function to be bound.
|
|
10
|
+
*/
|
|
11
|
+
addListener(f: (...args: Args) => void, priority?: number): void;
|
|
12
|
+
/**
|
|
13
|
+
* Unbind an existing function
|
|
14
|
+
* @param f - The callback function to be unbound.
|
|
15
|
+
*/
|
|
16
|
+
removeListener(f: (...args: Args) => void): void;
|
|
17
|
+
/**
|
|
18
|
+
* Emit an event
|
|
19
|
+
*
|
|
20
|
+
* @param a - The argument to pass to handler functions.
|
|
21
|
+
*/
|
|
22
|
+
protected _emit(...args: Args): void;
|
|
23
|
+
}
|
package/lib/emitter.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export class Emitter {
|
|
2
|
+
constructor() {
|
|
3
|
+
this._funcs = [];
|
|
4
|
+
this._emitting = false;
|
|
5
|
+
this._toUnbind = new Set();
|
|
6
|
+
this._needsSort = false;
|
|
7
|
+
}
|
|
8
|
+
clearListeners() {
|
|
9
|
+
this._funcs = [];
|
|
10
|
+
this._needsSort = false;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Add a new handler function
|
|
14
|
+
* @param f - The callback function to be bound.
|
|
15
|
+
*/
|
|
16
|
+
addListener(f, priority = 0) {
|
|
17
|
+
this._funcs.push([f, priority]);
|
|
18
|
+
this._needsSort = true;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Unbind an existing function
|
|
22
|
+
* @param f - The callback function to be unbound.
|
|
23
|
+
*/
|
|
24
|
+
removeListener(f) {
|
|
25
|
+
if (this._emitting) {
|
|
26
|
+
this._toUnbind.add(f);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
this._toUnbind.delete(f);
|
|
30
|
+
const indx = this._funcs.findIndex(entry => entry[0] === f);
|
|
31
|
+
if (indx > -1) {
|
|
32
|
+
this._funcs.splice(indx, 1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Emit an event
|
|
37
|
+
*
|
|
38
|
+
* @param a - The argument to pass to handler functions.
|
|
39
|
+
*/
|
|
40
|
+
_emit(...args) {
|
|
41
|
+
if (this._needsSort) {
|
|
42
|
+
this._funcs.sort((a, b) => b[1] - a[1]);
|
|
43
|
+
this._needsSort = false;
|
|
44
|
+
}
|
|
45
|
+
this._emitting = true;
|
|
46
|
+
for (let i = 0, total = this._funcs.length; i < total; i++) {
|
|
47
|
+
const fn = this._funcs[i][0];
|
|
48
|
+
try {
|
|
49
|
+
if (this._toUnbind.has(fn))
|
|
50
|
+
continue;
|
|
51
|
+
fn(...args);
|
|
52
|
+
}
|
|
53
|
+
catch (ex) {
|
|
54
|
+
console.log('Exception in event handler', ex);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
this._emitting = false;
|
|
58
|
+
if (this._toUnbind.size > 0) {
|
|
59
|
+
this._toUnbind.forEach(fn => this.removeListener(fn));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
package/lib/entity.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { ZComponent } from "./zcomponent";
|
|
|
6
6
|
export declare class Entity {
|
|
7
7
|
readonly contextManager: ContextManager;
|
|
8
8
|
private _registered;
|
|
9
|
+
private _handlersBound;
|
|
9
10
|
private _zcomponent;
|
|
10
11
|
private _disposed;
|
|
11
12
|
/**
|
|
@@ -64,6 +65,7 @@ export declare class Entity {
|
|
|
64
65
|
getZComponentInstance<T extends ZComponent = ZComponent>(type?: ConstructorForComponent<T>): T;
|
|
65
66
|
/**
|
|
66
67
|
* Register a function to be called when an Event is fired, or an Observable's value changes.
|
|
68
|
+
* The function will only be bound to the underlying Event or Observable while this entity is enabled.
|
|
67
69
|
*
|
|
68
70
|
* Using this function, rather than attaching your handler directly to the Event or Observable,
|
|
69
71
|
* ensures your handler is automatically released when this entity is disposed.
|
|
@@ -71,8 +73,10 @@ export declare class Entity {
|
|
|
71
73
|
* @param evt The Event or Observable to listen to
|
|
72
74
|
* @param fn A function that will be called when the event fires, or the Observable value changes
|
|
73
75
|
*/
|
|
74
|
-
register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
|
|
75
|
-
register<
|
|
76
|
+
register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void, priority?: number): any;
|
|
77
|
+
register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void, options?: RegisterOptions): any;
|
|
78
|
+
register<Type>(observable: Observable<Type>, fn: (v: Type) => void, priority?: number): any;
|
|
79
|
+
register<Type>(observable: Observable<Type>, fn: (v: Type) => void, options?: RegisterOptions): any;
|
|
76
80
|
/**
|
|
77
81
|
* Unregisters a function that was previously registered to an Event or Observable.
|
|
78
82
|
*
|
|
@@ -81,6 +85,7 @@ export declare class Entity {
|
|
|
81
85
|
*/
|
|
82
86
|
unregister<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
|
|
83
87
|
unregister<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
|
|
88
|
+
private _updateHandlers;
|
|
84
89
|
/**
|
|
85
90
|
* Destroy this entity, cleaning up any resources that it has created and
|
|
86
91
|
* handler functions or callbacks it has registered.
|
|
@@ -102,3 +107,7 @@ export declare class Entity {
|
|
|
102
107
|
dispose(): never;
|
|
103
108
|
private static callSuperDispose;
|
|
104
109
|
}
|
|
110
|
+
export interface RegisterOptions {
|
|
111
|
+
priority?: number;
|
|
112
|
+
bindWhenDisabled?: boolean;
|
|
113
|
+
}
|
package/lib/entity.js
CHANGED
|
@@ -5,6 +5,7 @@ export class Entity {
|
|
|
5
5
|
constructor(contextManager) {
|
|
6
6
|
this.contextManager = contextManager;
|
|
7
7
|
this._registered = [];
|
|
8
|
+
this._handlersBound = false;
|
|
8
9
|
this._disposed = false;
|
|
9
10
|
/**
|
|
10
11
|
* An event that is fired as the last act of this entity being destroyed.
|
|
@@ -46,7 +47,26 @@ export class Entity {
|
|
|
46
47
|
* Disabled entities will typically remain visible (if they have a visible appearance).
|
|
47
48
|
*/
|
|
48
49
|
this.enabledResolved = new Observable(true);
|
|
50
|
+
this._updateHandlers = (enabled) => {
|
|
51
|
+
if (enabled && !this._handlersBound) {
|
|
52
|
+
for (const [e, fn, priority, bindWhenDisabled] of this._registered) {
|
|
53
|
+
if (bindWhenDisabled)
|
|
54
|
+
continue;
|
|
55
|
+
e.addListener(fn, priority);
|
|
56
|
+
}
|
|
57
|
+
this._handlersBound = true;
|
|
58
|
+
}
|
|
59
|
+
if (!enabled && this._handlersBound) {
|
|
60
|
+
for (const [e, fn, _, bindWhenDisabled] of this._registered) {
|
|
61
|
+
if (bindWhenDisabled)
|
|
62
|
+
continue;
|
|
63
|
+
e.removeListener(fn);
|
|
64
|
+
}
|
|
65
|
+
this._handlersBound = false;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
49
68
|
this._zcomponent = getCurrentZComponentConstruction();
|
|
69
|
+
this.enabledResolved.addListener(this._updateHandlers);
|
|
50
70
|
}
|
|
51
71
|
get disposed() {
|
|
52
72
|
return this._disposed;
|
|
@@ -73,22 +93,20 @@ export class Entity {
|
|
|
73
93
|
return this._zcomponent;
|
|
74
94
|
throw new Error("getZComponentInstance called in entity passing wrong kind of ZComponent");
|
|
75
95
|
}
|
|
76
|
-
register(e, fn) {
|
|
96
|
+
register(e, fn, priorityOrOptions) {
|
|
97
|
+
const priority = (typeof priorityOrOptions === 'number' ? priorityOrOptions : priorityOrOptions?.priority);
|
|
98
|
+
const bindWhenDisabled = (typeof priorityOrOptions === 'number' ? false : priorityOrOptions?.bindWhenDisabled);
|
|
77
99
|
for (const entry of this._registered) {
|
|
78
100
|
if (entry[0] === e && entry[1] === fn)
|
|
79
101
|
return;
|
|
80
102
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
this._registered.push([e, fn]);
|
|
103
|
+
this._registered.push([e, fn, priority, bindWhenDisabled ?? false]);
|
|
104
|
+
if (this._handlersBound || bindWhenDisabled) {
|
|
105
|
+
e.addListener(fn, priority);
|
|
106
|
+
}
|
|
86
107
|
}
|
|
87
108
|
unregister(e, fn) {
|
|
88
|
-
|
|
89
|
-
e.unbindfn(fn);
|
|
90
|
-
else if (e instanceof Observable)
|
|
91
|
-
e.removeWithValue(fn);
|
|
109
|
+
e.removeListener(fn);
|
|
92
110
|
this._registered = this._registered.filter(entry => (entry[0] !== e || entry[1] !== fn));
|
|
93
111
|
}
|
|
94
112
|
/**
|
|
@@ -110,15 +128,13 @@ export class Entity {
|
|
|
110
128
|
* @returns The result of a call to super.dispose()
|
|
111
129
|
*/
|
|
112
130
|
dispose() {
|
|
131
|
+
this.enabledResolved.removeListener(this._updateHandlers);
|
|
113
132
|
for (const entry of this._registered) {
|
|
114
|
-
|
|
115
|
-
entry[0].unbindfn(entry[1]);
|
|
116
|
-
else if (entry[0] instanceof Observable)
|
|
117
|
-
entry[0].removeWithValue(entry[1]);
|
|
133
|
+
entry[0].removeListener(entry[1]);
|
|
118
134
|
}
|
|
119
135
|
this._registered = [];
|
|
120
136
|
this.onDispose.emit();
|
|
121
|
-
this.onDispose.
|
|
137
|
+
this.onDispose.clearListeners();
|
|
122
138
|
this.disposed = true;
|
|
123
139
|
return undefined;
|
|
124
140
|
}
|
package/lib/event.d.ts
CHANGED
|
@@ -1,24 +1,14 @@
|
|
|
1
|
+
import { Emitter } from "./emitter";
|
|
1
2
|
import { Observable } from "./observable";
|
|
2
|
-
export declare class Event<Args extends Array<any> = []> {
|
|
3
|
-
|
|
4
|
-
private _funcs;
|
|
5
|
-
private _emitting;
|
|
6
|
-
private _toUnbind;
|
|
7
|
-
clear(): void;
|
|
8
|
-
/**
|
|
9
|
-
* Bind new handler function.
|
|
10
|
-
* @param f - The callback function to be bound.
|
|
11
|
-
*/
|
|
12
|
-
bindfn(f: (...args: Args) => void): void;
|
|
13
|
-
/**
|
|
14
|
-
* Unbind an existing function.
|
|
15
|
-
* @param f - The callback function to be unbound.
|
|
16
|
-
*/
|
|
17
|
-
unbindfn(f: (...args: Args) => void): void;
|
|
3
|
+
export declare class Event<Args extends Array<any> = []> extends Emitter<Args> {
|
|
4
|
+
hasListeners: Observable<boolean, never>;
|
|
18
5
|
/**
|
|
19
6
|
* Emit an event.
|
|
20
7
|
*
|
|
21
8
|
* @param a - The argument to pass to handler functions.
|
|
22
9
|
*/
|
|
23
10
|
emit(...args: Args): void;
|
|
11
|
+
clearListeners(): void;
|
|
12
|
+
addListener(f: (...args: Args) => void, priority?: number): void;
|
|
13
|
+
removeListener(f: (...args: Args) => void): void;
|
|
24
14
|
}
|
package/lib/event.js
CHANGED
|
@@ -1,40 +1,9 @@
|
|
|
1
|
+
import { Emitter } from "./emitter";
|
|
1
2
|
import { Observable } from "./observable";
|
|
2
|
-
export class Event {
|
|
3
|
+
export class Event extends Emitter {
|
|
3
4
|
constructor() {
|
|
4
|
-
|
|
5
|
-
this.
|
|
6
|
-
this._emitting = false;
|
|
7
|
-
this._toUnbind = new Set();
|
|
8
|
-
}
|
|
9
|
-
clear() {
|
|
10
|
-
this._funcs = [];
|
|
11
|
-
this.hasBindings.value = false;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Bind new handler function.
|
|
15
|
-
* @param f - The callback function to be bound.
|
|
16
|
-
*/
|
|
17
|
-
bindfn(f) {
|
|
18
|
-
this._funcs.push(f);
|
|
19
|
-
if (!this.hasBindings.value)
|
|
20
|
-
this.hasBindings.value = true;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Unbind an existing function.
|
|
24
|
-
* @param f - The callback function to be unbound.
|
|
25
|
-
*/
|
|
26
|
-
unbindfn(f) {
|
|
27
|
-
if (this._emitting) {
|
|
28
|
-
this._toUnbind.add(f);
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
this._toUnbind.delete(f);
|
|
32
|
-
const indx = this._funcs.indexOf(f);
|
|
33
|
-
if (indx > -1) {
|
|
34
|
-
this._funcs.splice(indx, 1);
|
|
35
|
-
}
|
|
36
|
-
if (this._funcs.length === 0 && this.hasBindings.value)
|
|
37
|
-
this.hasBindings.value = false;
|
|
5
|
+
super(...arguments);
|
|
6
|
+
this.hasListeners = new Observable(false);
|
|
38
7
|
}
|
|
39
8
|
/**
|
|
40
9
|
* Emit an event.
|
|
@@ -42,20 +11,20 @@ export class Event {
|
|
|
42
11
|
* @param a - The argument to pass to handler functions.
|
|
43
12
|
*/
|
|
44
13
|
emit(...args) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
14
|
+
super._emit(...args);
|
|
15
|
+
}
|
|
16
|
+
clearListeners() {
|
|
17
|
+
super.clearListeners();
|
|
18
|
+
if (!this.hasListeners.value)
|
|
19
|
+
this.hasListeners.value = true;
|
|
20
|
+
}
|
|
21
|
+
addListener(f, priority) {
|
|
22
|
+
super.addListener(f, priority);
|
|
23
|
+
this.hasListeners.value = true;
|
|
24
|
+
}
|
|
25
|
+
removeListener(f) {
|
|
26
|
+
super.removeListener(f);
|
|
27
|
+
if (this._funcs.length === 0 && this.hasListeners.value)
|
|
28
|
+
this.hasListeners.value = false;
|
|
60
29
|
}
|
|
61
30
|
}
|
package/lib/observable.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Emitter } from "./emitter";
|
|
1
2
|
type Resolved<T, M> = [T] extends [never] ? M : T;
|
|
2
3
|
/**
|
|
3
4
|
* A class that holds a value and watches it for changes (deeply by default).
|
|
@@ -31,14 +32,11 @@ type Resolved<T, M> = [T] extends [never] ? M : T;
|
|
|
31
32
|
* @typeParam Type - The type of the contained value
|
|
32
33
|
* @typeParam TypeInternal - An internal type used to improve automatic type detection
|
|
33
34
|
*/
|
|
34
|
-
export declare class Observable<Type = never, TypeInternal extends any[] | [] | never = never> {
|
|
35
|
+
export declare class Observable<Type = never, TypeInternal extends any[] | [] | never = never> extends Emitter<[Resolved<Type, TypeInternal>]> {
|
|
35
36
|
private _default;
|
|
36
37
|
private _deep;
|
|
37
38
|
private _proxies;
|
|
38
39
|
private _value;
|
|
39
|
-
private _nextToken;
|
|
40
|
-
private _handlersByToken;
|
|
41
|
-
private _tokenByHandler;
|
|
42
40
|
/**
|
|
43
41
|
* Constructs a new Observable
|
|
44
42
|
*
|
|
@@ -56,8 +54,7 @@ export declare class Observable<Type = never, TypeInternal extends any[] | [] |
|
|
|
56
54
|
get value(): Resolved<Type, TypeInternal>;
|
|
57
55
|
private _wrap;
|
|
58
56
|
set value(v: Resolved<Type, TypeInternal> | undefined);
|
|
59
|
-
|
|
60
|
-
removeWithValue(fnOrToken: number | ((v: Resolved<Type, TypeInternal>) => void)): void;
|
|
57
|
+
addListener(fn: (v: Resolved<Type, TypeInternal>) => void, priority?: number): void;
|
|
61
58
|
private _emitValue;
|
|
62
59
|
}
|
|
63
60
|
export {};
|
package/lib/observable.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Emitter } from "./emitter";
|
|
1
2
|
/**
|
|
2
3
|
* A class that holds a value and watches it for changes (deeply by default).
|
|
3
4
|
*
|
|
@@ -30,14 +31,12 @@
|
|
|
30
31
|
* @typeParam Type - The type of the contained value
|
|
31
32
|
* @typeParam TypeInternal - An internal type used to improve automatic type detection
|
|
32
33
|
*/
|
|
33
|
-
export class Observable {
|
|
34
|
+
export class Observable extends Emitter {
|
|
34
35
|
constructor(_default, withHandler, _deep = true) {
|
|
36
|
+
super();
|
|
35
37
|
this._default = _default;
|
|
36
38
|
this._deep = _deep;
|
|
37
39
|
this._proxies = new WeakMap();
|
|
38
|
-
this._nextToken = 0;
|
|
39
|
-
this._handlersByToken = new Map();
|
|
40
|
-
this._tokenByHandler = new Map();
|
|
41
40
|
let initial = this._default;
|
|
42
41
|
if (Array.isArray(this._default) && this._deep) {
|
|
43
42
|
initial = this._default.slice();
|
|
@@ -49,7 +48,7 @@ export class Observable {
|
|
|
49
48
|
}
|
|
50
49
|
this._value = this._wrap(initial);
|
|
51
50
|
if (withHandler)
|
|
52
|
-
this.
|
|
51
|
+
this.addListener(withHandler);
|
|
53
52
|
}
|
|
54
53
|
/**
|
|
55
54
|
* Access the current value for this Observable. Changing this value (or, unless deep inspection is disabled, its recursive elements and keys) will trigger any registered handlers to be called with the new value.
|
|
@@ -117,40 +116,16 @@ export class Observable {
|
|
|
117
116
|
this._value = this._wrap(v);
|
|
118
117
|
this._emitValue();
|
|
119
118
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
this._handlersByToken.set(token, fn);
|
|
123
|
-
this._tokenByHandler.set(fn, token);
|
|
119
|
+
addListener(fn, priority = 0) {
|
|
120
|
+
super.addListener(fn);
|
|
124
121
|
try {
|
|
125
122
|
fn(this._value.proxy);
|
|
126
123
|
}
|
|
127
124
|
catch (err) {
|
|
128
125
|
console.error(err);
|
|
129
126
|
}
|
|
130
|
-
return token;
|
|
131
|
-
}
|
|
132
|
-
removeWithValue(fnOrToken) {
|
|
133
|
-
if (typeof fnOrToken === 'number') {
|
|
134
|
-
const handler = this._handlersByToken.get(fnOrToken);
|
|
135
|
-
if (handler !== undefined)
|
|
136
|
-
this._tokenByHandler.delete(handler);
|
|
137
|
-
this._handlersByToken.delete(fnOrToken);
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
const token = this._tokenByHandler.get(fnOrToken);
|
|
141
|
-
if (token !== undefined)
|
|
142
|
-
this._handlersByToken.delete(token);
|
|
143
|
-
this._tokenByHandler.delete(fnOrToken);
|
|
144
|
-
}
|
|
145
127
|
}
|
|
146
128
|
_emitValue() {
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
h(this._value.proxy);
|
|
150
|
-
}
|
|
151
|
-
catch (err) {
|
|
152
|
-
console.error(err);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
129
|
+
this._emit(this._value.proxy);
|
|
155
130
|
}
|
|
156
131
|
}
|
package/lib/selectors.js
CHANGED
|
@@ -218,7 +218,7 @@ function typeOutputForProp(prop) {
|
|
|
218
218
|
const comments = (prop.comments && prop.comments.length > 0) ? '\n\t* ' + prop.comments.map(makeCommentSafe).join('\n\t*\n\t* ') + '\n\t* ' : '';
|
|
219
219
|
return ` /**${comments}
|
|
220
220
|
* @zprop
|
|
221
|
-
* ${prop.default ? `@zdefault ${JSON.stringify(prop.default)}` : ''}
|
|
221
|
+
* ${prop.default !== undefined ? `@zdefault ${JSON.stringify(prop.default)}` : ''}
|
|
222
222
|
*/
|
|
223
223
|
public ${prop.name}: Observable<${outputForType(prop.type, true)}>;`;
|
|
224
224
|
}
|
|
@@ -226,7 +226,7 @@ function typeOutputForConstructorProp(prop) {
|
|
|
226
226
|
const comments = (prop.comments && prop.comments.length > 0) ? '\n\t* ' + prop.comments.map(makeCommentSafe).join('\n\t*\n\t* ') + '\n\t* ' : '';
|
|
227
227
|
return ` /**${comments}
|
|
228
228
|
* @zprop
|
|
229
|
-
* ${prop.default && `@zdefault ${JSON.stringify(prop.default)}`}
|
|
229
|
+
* ${prop.default !== undefined && `@zdefault ${JSON.stringify(prop.default)}`}
|
|
230
230
|
*/
|
|
231
231
|
${prop.name}: ${outputForType(prop.type, true)};`;
|
|
232
232
|
}
|
package/lib/zcomponent.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ export declare class ZComponent<RootType = any> extends Component<RootType> {
|
|
|
38
38
|
};
|
|
39
39
|
entityByID: Map<string, Entity>;
|
|
40
40
|
entityByLabel: Map<string, Entity>;
|
|
41
|
+
nodeByLabel: Map<string, Component<any, ConstructorProps>>;
|
|
41
42
|
private _constructedResolve;
|
|
42
43
|
constructed: Promise<void>;
|
|
43
44
|
isConstructed: boolean;
|
package/lib/zcomponent.js
CHANGED
|
@@ -23,6 +23,7 @@ export class ZComponent extends Component {
|
|
|
23
23
|
this.nodes = {};
|
|
24
24
|
this.entityByID = new Map();
|
|
25
25
|
this.entityByLabel = new Map();
|
|
26
|
+
this.nodeByLabel = new Map();
|
|
26
27
|
this.constructed = new Promise(resolve => this._constructedResolve = resolve);
|
|
27
28
|
this.isConstructed = false;
|
|
28
29
|
this._nodesById = new Map();
|
|
@@ -75,8 +76,10 @@ export class ZComponent extends Component {
|
|
|
75
76
|
setCurrentZComponentConstruction(that);
|
|
76
77
|
super(contextManager, constructorProps);
|
|
77
78
|
that.entityByID.set(nodeId, this);
|
|
78
|
-
if (node?.label)
|
|
79
|
+
if (node?.label) {
|
|
79
80
|
that.entityByLabel.set(node.label, this);
|
|
81
|
+
that.nodeByLabel.set(node.label, this);
|
|
82
|
+
}
|
|
80
83
|
that._nodesById.set(nodeId, this);
|
|
81
84
|
for (const element of this.elementsResolved) {
|
|
82
85
|
that.idByElement.set(element, nodeId);
|
|
@@ -224,7 +227,7 @@ export class ZComponent extends Component {
|
|
|
224
227
|
if (!v)
|
|
225
228
|
continue;
|
|
226
229
|
if (v instanceof Observable)
|
|
227
|
-
|
|
230
|
+
this.register(v, val => this._setEntityPropPath(entity, override.entityPropPath, val), { bindWhenDisabled: true });
|
|
228
231
|
else
|
|
229
232
|
this._setEntityPropPath(entity, override.entityPropPath, v);
|
|
230
233
|
break;
|
|
@@ -236,7 +239,7 @@ export class ZComponent extends Component {
|
|
|
236
239
|
if (!v)
|
|
237
240
|
continue;
|
|
238
241
|
if (v instanceof Observable)
|
|
239
|
-
|
|
242
|
+
this.register(v, val => this._setEntityPropPath(entity, override.entityPropPath, val), { bindWhenDisabled: true });
|
|
240
243
|
else
|
|
241
244
|
this._setEntityPropPath(entity, override.entityPropPath, v);
|
|
242
245
|
break;
|
|
@@ -255,7 +258,7 @@ export class ZComponent extends Component {
|
|
|
255
258
|
if (!v)
|
|
256
259
|
continue;
|
|
257
260
|
if (v instanceof Observable)
|
|
258
|
-
|
|
261
|
+
this.register(v, val => this._setEntityPropPath(entity, override.entityPropPath, val), { bindWhenDisabled: true });
|
|
259
262
|
else
|
|
260
263
|
this._setEntityPropPath(entity, override.entityPropPath, v);
|
|
261
264
|
break;
|