@zcomponent/core 0.0.1 → 0.0.2

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.
@@ -1,20 +1,17 @@
1
- import { ConcreteBehavior } from "./behavior";
2
- import { InstanceOfComponent } from "./component";
1
+ import { Behavior, BehaviorConstructorProps } from "./behavior";
3
2
  import { ContextManager } from "./context";
4
- export declare type ActionConstructorType<T extends {}> = (props: T, ctx: ContextManager) => (() => void);
5
- export interface ActionBehaviorConstructorProps {
3
+ export interface ActionBehaviorConstructorProps extends BehaviorConstructorProps {
6
4
  /** @zprop
7
5
  * @zvalues events
8
6
  */
9
7
  event: string;
10
- instance: InstanceOfComponent<any>;
11
8
  }
12
- export interface ActionBehaviorProps {
13
- dispose: () => void;
14
- }
15
- export interface PreviewableActionBehaviorProps extends ActionBehaviorProps {
16
- /** @zprop */
17
- preview: () => void;
9
+ export declare abstract class ActionBehavior<ConstructorProps extends ActionBehaviorConstructorProps = ActionBehaviorConstructorProps> extends Behavior<any, ConstructorProps> {
10
+ /**
11
+ * @zprop
12
+ * @zdefault true
13
+ */
14
+ enabled: boolean;
15
+ constructor(props: ConstructorProps, contextManager: ContextManager);
16
+ abstract perform(): any;
18
17
  }
19
- export declare function defineActionBehavior<ActionConstructorProps extends {}>(a: ActionConstructorType<ActionConstructorProps>): ConcreteBehavior<any, ActionConstructorProps & ActionBehaviorConstructorProps, ActionBehaviorProps>;
20
- export declare function defineActionBehavior<ActionConstructorProps extends {}>(a: ActionConstructorType<ActionConstructorProps>, preview: true): ConcreteBehavior<any, ActionConstructorProps & ActionBehaviorConstructorProps, PreviewableActionBehaviorProps>;
@@ -1,32 +1,22 @@
1
- import { defineBehavior } from "./behavior";
1
+ import { Behavior } from "./behavior";
2
2
  import { isEditTime } from "./contexts/environmentcontext";
3
3
  import { Event } from "./event";
4
- export function defineActionBehavior(a, preview) {
5
- return defineBehavior((props, ctx) => {
6
- let handler;
7
- let evt;
8
- const upstreamHandler = (!isEditTime(ctx) || preview) ? a(props, ctx) : undefined;
9
- if (props.event && !isEditTime(ctx)) {
10
- const evt = props.instance[props.event];
11
- if (!evt || !(evt instanceof Event))
12
- throw new Error(`Event '${props.event}' does not exist on instance`);
13
- const handler = (evt) => {
14
- if (evt && typeof evt === 'object' && typeof evt['stopPropagation'] === 'function') {
15
- evt['stopPropagation'].call(evt);
4
+ export class ActionBehavior extends Behavior {
5
+ constructor(props, contextManager) {
6
+ super(props, contextManager);
7
+ /**
8
+ * @zprop
9
+ * @zdefault true
10
+ */
11
+ this.enabled = true;
12
+ const evt = props.instance[props.event];
13
+ if (evt instanceof Event && !isEditTime(contextManager)) {
14
+ this.register(evt, e => {
15
+ this.perform();
16
+ if (e && typeof e === 'object' && typeof e['stopPropagation'] === 'function') {
17
+ e['stopPropagation'].call(e);
16
18
  }
17
- upstreamHandler?.();
18
- };
19
- evt.bindfn(handler);
19
+ });
20
20
  }
21
- return {
22
- /** @zprop */
23
- preview: preview ? () => {
24
- upstreamHandler?.();
25
- } : undefined,
26
- dispose: () => {
27
- if (handler)
28
- evt?.unbindfn(handler);
29
- },
30
- };
31
- }, true);
21
+ }
32
22
  }
package/lib/behavior.d.ts CHANGED
@@ -1,26 +1,23 @@
1
- import { Component, InstanceOfComponent } from './component';
1
+ import { Component } from './component';
2
2
  import { ContextManager } from './context';
3
- export declare type BehaviorInstance<PropsType extends {} = {
4
- [id: string]: any;
5
- }> = PropsType & {
6
- dispose?: () => void;
7
- [id: string]: any;
8
- };
9
- export declare type Behavior<ComponentType extends Component = () => {}, ConstructorPropsType extends {
10
- instance: InstanceOfComponent<ComponentType>;
11
- } = {
12
- [id: string]: any;
13
- instance: InstanceOfComponent<ComponentType>;
14
- }, PropsType extends {} = {}> = (constructorProps: ConstructorPropsType, context: ContextManager) => BehaviorInstance<PropsType> | undefined;
15
- export declare type ConcreteBehavior<ComponentType extends Component = () => {}, ConstructorPropsType extends {
16
- instance: InstanceOfComponent<ComponentType>;
17
- } = {
18
- [id: string]: any;
19
- instance: InstanceOfComponent<ComponentType>;
20
- }, PropsType extends {} = {}> = (constructorProps: ConstructorPropsType, context: ContextManager) => BehaviorInstance<PropsType>;
21
- export declare type ConstructorPropsOfBehavior<BehaviorType extends Behavior> = Parameters<BehaviorType>[0];
22
- export declare type PropsOfBehavior<BehaviorType extends Behavior> = ReturnType<BehaviorType>;
23
- export declare type InstanceOfBehavior<BehaviorType extends Behavior> = ReturnType<BehaviorType>;
24
- export declare function shouldBehaviorRunAtDesignTime(b: Behavior): boolean;
25
- /** Register a new custom behavior */
26
- export declare function defineBehavior<BehaviorType extends Behavior>(c: BehaviorType, runAtDesignTime?: boolean): BehaviorType;
3
+ import { Event } from './event';
4
+ import { Observable } from './observable';
5
+ export declare type BehaviorConstructor<BehaviorType = Behavior> = BehaviorType extends Behavior<any, infer ConstructorPropsType> ? new (props: ConstructorPropsType, contextManager: ContextManager) => BehaviorType : never;
6
+ export declare type ConstructorPropsOfBehavior<BehaviorType> = BehaviorType extends Behavior<infer R> ? R : never;
7
+ export interface BehaviorConstructorProps<InstanceType extends Component = Component> {
8
+ instance: InstanceType;
9
+ }
10
+ export declare class Behavior<InstanceType extends Component = any, ConstructorPropsType extends BehaviorConstructorProps<InstanceType> = BehaviorConstructorProps<InstanceType>> {
11
+ constructorProps: ConstructorPropsType;
12
+ contextManager: ContextManager;
13
+ private static callSuperDispose;
14
+ onDispose: Event<[]>;
15
+ instance: InstanceType;
16
+ private _registered;
17
+ constructor(constructorProps: ConstructorPropsType, contextManager: ContextManager);
18
+ register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
19
+ register<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
20
+ dispose(): never;
21
+ }
22
+ export declare function shouldBehaviorRunAtDesignTime(b: BehaviorConstructor): boolean;
23
+ export declare function registerBehaviorRunAtDesignTime(b: BehaviorConstructor): Set<new (props: BehaviorConstructorProps<any>, contextManager: ContextManager) => Behavior<any, BehaviorConstructorProps<any>>>;
package/lib/behavior.js CHANGED
@@ -1,10 +1,38 @@
1
+ import { Event } from './event';
2
+ import { Observable } from './observable';
3
+ export class Behavior {
4
+ constructor(constructorProps, contextManager) {
5
+ this.constructorProps = constructorProps;
6
+ this.contextManager = contextManager;
7
+ this.onDispose = new Event();
8
+ this._registered = [];
9
+ this.instance = this.constructorProps.instance;
10
+ }
11
+ register(e, fn) {
12
+ if (e instanceof Event)
13
+ e.bindfn(fn);
14
+ else if (e instanceof Observable)
15
+ e.withValue(fn);
16
+ this._registered.push([e, fn]);
17
+ }
18
+ dispose() {
19
+ for (const entry of this._registered) {
20
+ if (entry[0] instanceof Event)
21
+ entry[0].unbindfn(entry[1]);
22
+ else if (entry[0] instanceof Observable)
23
+ entry[0].removeWithValue(entry[1]);
24
+ }
25
+ this._registered = [];
26
+ this.onDispose.emit();
27
+ this.onDispose.clear();
28
+ return undefined;
29
+ }
30
+ }
31
+ Behavior.callSuperDispose = Symbol('Calling super.dispose() is mandatory');
1
32
  const behaviorsToRunAtDesignTime = new Set();
2
33
  export function shouldBehaviorRunAtDesignTime(b) {
3
34
  return behaviorsToRunAtDesignTime.has(b);
4
35
  }
5
- /** Register a new custom behavior */
6
- export function defineBehavior(c, runAtDesignTime = false) {
7
- if (runAtDesignTime)
8
- behaviorsToRunAtDesignTime.add(c);
9
- return c;
36
+ export function registerBehaviorRunAtDesignTime(b) {
37
+ return behaviorsToRunAtDesignTime.add(b);
10
38
  }
@@ -1,12 +1,18 @@
1
- export interface LaunchURLProps {
2
- /** @zprop */
1
+ import { ActionBehavior } from "../actionbehavior";
2
+ /**
3
+ * @zbehavior
4
+ * @zgroup Actions
5
+ */
6
+ export declare class LaunchURL extends ActionBehavior {
7
+ /**
8
+ * The URL to open
9
+ * @zprop
10
+ */
3
11
  url: string;
4
- /** @zprop
5
- * @zdefault true
12
+ /**
13
+ * If true, the URL will be opened in a new tab (using target '_blank')
14
+ * @zprop
6
15
  */
7
16
  openInNew: boolean;
17
+ perform(): void;
8
18
  }
9
- /** @zbehavior
10
- * @zgroup Actions
11
- */
12
- export declare const LaunchURL: import("..").ConcreteBehavior<any, LaunchURLProps & import("../actionbehavior").ActionBehaviorConstructorProps, import("../actionbehavior").ActionBehaviorProps>;
@@ -1,12 +1,13 @@
1
- import { defineActionBehavior } from "../actionbehavior";
2
- /** @zbehavior
1
+ import { ActionBehavior } from "../actionbehavior";
2
+ /**
3
+ * @zbehavior
3
4
  * @zgroup Actions
4
5
  */
5
- export const LaunchURL = defineActionBehavior((props) => {
6
- return () => {
7
- if (props.openInNew ?? true)
8
- window.open(props.url, '_blank', 'noopener noreferrer');
6
+ export class LaunchURL extends ActionBehavior {
7
+ perform() {
8
+ if (this.openInNew ?? true)
9
+ window.open(this.url, '_blank', 'noopener noreferrer');
9
10
  else
10
- window.location.href = props.url;
11
- };
12
- });
11
+ window.location.href = this.url;
12
+ }
13
+ }
@@ -1,10 +1,12 @@
1
- export interface LogAnalyticsEventProps {
1
+ import { ActionBehavior } from "../actionbehavior";
2
+ /**
3
+ * @zbehavior
4
+ * @zgroup Actions
5
+ */
6
+ export declare class LogAnalyticsEvent extends ActionBehavior {
2
7
  /** @zprop */
3
8
  name: string;
4
9
  /** @zprop */
5
10
  params: any;
11
+ perform(): void;
6
12
  }
7
- /** @zbehavior
8
- * @zgroup Actions
9
- */
10
- export declare const LogAnalyticsEvent: import("..").ConcreteBehavior<any, LogAnalyticsEventProps & import("../actionbehavior").ActionBehaviorConstructorProps, import("../actionbehavior").ActionBehaviorProps>;
@@ -1,10 +1,11 @@
1
- import { defineActionBehavior } from "../actionbehavior";
1
+ import { ActionBehavior } from "../actionbehavior";
2
2
  import { logEvent } from "../contexts/analyticscontext";
3
- /** @zbehavior
3
+ /**
4
+ * @zbehavior
4
5
  * @zgroup Actions
5
6
  */
6
- export const LogAnalyticsEvent = defineActionBehavior((props, mgr) => {
7
- return () => {
8
- logEvent(mgr, props.name, props.params);
9
- };
10
- });
7
+ export class LogAnalyticsEvent extends ActionBehavior {
8
+ perform() {
9
+ logEvent(this.contextManager, this.name, this.params);
10
+ }
11
+ }
@@ -1,4 +1,6 @@
1
- export interface PlaySoundProps {
1
+ import { ActionBehavior, ActionBehaviorConstructorProps } from "../actionbehavior";
2
+ import { ContextManager } from "../context";
3
+ export interface PlaySoundProps extends ActionBehaviorConstructorProps {
2
4
  /** The URL of the file to play
3
5
  * @zprop
4
6
  * @zvalues files *.wav
@@ -6,7 +8,15 @@ export interface PlaySoundProps {
6
8
  */
7
9
  source: string;
8
10
  }
9
- /** @zbehavior
11
+ /**
12
+ * @zbehavior
10
13
  * @zgroup Actions
11
14
  */
12
- export declare const PlaySound: import("..").ConcreteBehavior<any, PlaySoundProps & import("../actionbehavior").ActionBehaviorConstructorProps, import("../actionbehavior").PreviewableActionBehaviorProps>;
15
+ export declare class PlaySound extends ActionBehavior<PlaySoundProps> {
16
+ private _elm;
17
+ constructor(props: PlaySoundProps, contextManager: ContextManager);
18
+ perform(): void;
19
+ /** @zprop */
20
+ preview(): void;
21
+ dispose(): never;
22
+ }
@@ -1,18 +1,33 @@
1
- import { defineActionBehavior } from "../actionbehavior";
1
+ import { ActionBehavior, } from "../actionbehavior";
2
+ import { registerBehaviorRunAtDesignTime } from "../behavior";
2
3
  import { registerLoadable } from "../contexts/loadcontext";
3
- /** @zbehavior
4
+ /**
5
+ * @zbehavior
4
6
  * @zgroup Actions
5
7
  */
6
- export const PlaySound = defineActionBehavior((props, mgr) => {
7
- const elm = document.createElement('audio');
8
- elm.preload = 'auto';
9
- registerLoadable(mgr, new Promise((resolve, reject) => {
10
- elm.addEventListener('canplaythrough', () => resolve());
11
- elm.addEventListener('error', reject);
12
- }));
13
- elm.src = props.source;
14
- return () => {
15
- elm.currentTime = 0;
16
- elm.play();
17
- };
18
- }, true);
8
+ export class PlaySound extends ActionBehavior {
9
+ constructor(props, contextManager) {
10
+ super(props, contextManager);
11
+ this._elm = document.createElement('audio');
12
+ this._elm.preload = 'auto';
13
+ registerLoadable(contextManager, new Promise((resolve, reject) => {
14
+ this._elm.addEventListener('canplaythrough', () => resolve());
15
+ this._elm.addEventListener('error', reject);
16
+ }));
17
+ this._elm.src = props.source;
18
+ }
19
+ perform() {
20
+ this._elm.currentTime = 0;
21
+ this._elm.play();
22
+ }
23
+ /** @zprop */
24
+ preview() {
25
+ this.perform();
26
+ }
27
+ dispose() {
28
+ this._elm.pause();
29
+ this._elm.src = '';
30
+ return super.dispose();
31
+ }
32
+ }
33
+ registerBehaviorRunAtDesignTime(PlaySound);
@@ -1,22 +1,30 @@
1
1
  import { ContextManager } from './context';
2
- export declare type ComponentInstance<PropsType extends {} = {
3
- [id: string]: any;
4
- }, RootType = any> = PropsType & {
5
- dispose?: () => void;
6
- root?: RootType;
7
- [id: string]: any;
8
- };
9
- export declare type ComponentChildren = [Component, {
10
- [id: string]: any;
11
- }][];
12
- export declare type Component<ConstructorPropsType extends {
13
- children?: ComponentChildren;
14
- } = {
15
- [id: string]: any;
2
+ import { Event } from './event';
3
+ import { Observable } from './observable';
4
+ export declare type ComponentConstructor<ComponentType = Component> = ComponentType extends Component<infer ConstructorPropsType> ? new (props: ConstructorPropsType, contextManager: ContextManager) => ComponentType : never;
5
+ export declare type ConstructorPropsOfComponent<ComponentType> = ComponentType extends Component<infer R> ? R : never;
6
+ export declare type ComponentChild<ComponentType extends Component> = [ComponentConstructor<ComponentType>, ConstructorPropsOfComponent<ComponentType>];
7
+ export declare type ComponentChildren = ComponentChild<any>[];
8
+ export interface ConstructorProps {
16
9
  children?: ComponentChildren;
17
- }, PropsType extends {} = {}, RootType = any> = (constructorProps: ConstructorPropsType, context: ContextManager) => ComponentInstance<PropsType, RootType> | undefined;
18
- export declare type ConstructorPropsOfComponent<ComponentType extends Component> = Parameters<ComponentType>[0];
19
- export declare type PropsOfComponent<ComponentType extends Component> = ReturnType<ComponentType>;
20
- export declare type InstanceOfComponent<ComponentType extends Component> = ReturnType<ComponentType>;
21
- /** Register a new custom component */
22
- export declare function defineComponent<ComponentType extends Component>(c: ComponentType): ComponentType;
10
+ }
11
+ export interface ComponentOptions {
12
+ dontConstructChildren?: boolean;
13
+ }
14
+ export declare class Component<ConstructorPropsType extends ConstructorProps = ConstructorProps, RootType = any> {
15
+ constructorProps: ConstructorPropsType;
16
+ contextManager: ContextManager;
17
+ private _options?;
18
+ root?: RootType;
19
+ onDispose: Event<[]>;
20
+ children: Component[];
21
+ disposed: boolean;
22
+ private _registered;
23
+ constructor(constructorProps: ConstructorPropsType, contextManager: ContextManager, _options?: ComponentOptions | undefined);
24
+ forEachRoot(fn: (root: any) => void): void;
25
+ protected _constructChildren(children?: ComponentChildren): void;
26
+ protected register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
27
+ protected register<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
28
+ dispose(): never;
29
+ private static callSuperDispose;
30
+ }
package/lib/component.js CHANGED
@@ -1,4 +1,56 @@
1
- /** Register a new custom component */
2
- export function defineComponent(c) {
3
- return c;
1
+ import { Event } from './event';
2
+ import { Observable } from './observable';
3
+ export class Component {
4
+ constructor(constructorProps, contextManager, _options) {
5
+ this.constructorProps = constructorProps;
6
+ this.contextManager = contextManager;
7
+ this._options = _options;
8
+ this.onDispose = new Event();
9
+ this.children = [];
10
+ this.disposed = false;
11
+ this._registered = [];
12
+ if (this._options?.dontConstructChildren !== true)
13
+ this._constructChildren(this.constructorProps.children);
14
+ }
15
+ forEachRoot(fn) {
16
+ if (Array.isArray(this.root))
17
+ this.root.forEach(fn);
18
+ else if (this.root !== undefined)
19
+ fn(this.root);
20
+ }
21
+ _constructChildren(children) {
22
+ if (Array.isArray(children)) {
23
+ for (const child of children) {
24
+ this.children.push(new child[0](child[1], this.contextManager));
25
+ }
26
+ }
27
+ }
28
+ register(e, fn) {
29
+ if (e instanceof Event)
30
+ e.bindfn(fn);
31
+ else if (e instanceof Observable)
32
+ e.withValue(fn);
33
+ this._registered.push([e, fn]);
34
+ }
35
+ dispose() {
36
+ this.disposed = true;
37
+ for (const child of this.children) {
38
+ try {
39
+ child.dispose();
40
+ }
41
+ catch (err) { }
42
+ }
43
+ this.children = [];
44
+ for (const entry of this._registered) {
45
+ if (entry[0] instanceof Event)
46
+ entry[0].unbindfn(entry[1]);
47
+ else if (entry[0] instanceof Observable)
48
+ entry[0].removeWithValue(entry[1]);
49
+ }
50
+ this._registered = [];
51
+ this.onDispose.emit();
52
+ this.onDispose.clear();
53
+ return undefined;
54
+ }
4
55
  }
56
+ Component.callSuperDispose = Symbol('Calling super.dispose() is mandatory');
@@ -1,5 +1,5 @@
1
- import { Observable } from "../";
2
- export interface DefaultLoaderConstructorProps {
1
+ import { Component, Observable, ConstructorProps, ContextManager } from "..";
2
+ export interface DefaultLoaderConstructorProps extends ConstructorProps {
3
3
  /** @zprop
4
4
  * @zgroup Appearance
5
5
  * @zgrouppriority 10
@@ -16,23 +16,23 @@ export interface DefaultLoaderConstructorProps {
16
16
  * @zicon loader
17
17
  * @zgroup Advanced
18
18
  */
19
- export declare const DefaultLoader: (props: DefaultLoaderConstructorProps, mgr: import("../context").ContextManager) => {
20
- dispose: () => void;
19
+ export declare class DefaultLoader extends Component<DefaultLoaderConstructorProps> {
20
+ root: HTMLDivElement;
21
21
  /** @zprop
22
- * @zdefault false
23
- * @zgroup Design Time
24
- * @zgrouppriority 30
25
- */
22
+ * @zdefault false
23
+ * @zgroup Design Time
24
+ * @zgrouppriority 30
25
+ */
26
26
  preview: Observable<boolean>;
27
27
  /** @zprop
28
28
  * @zgroup Text
29
29
  * @zgrouppriority 20
30
- */
30
+ */
31
31
  title: Observable<string>;
32
32
  /** @zprop
33
33
  * @zgroup Text
34
34
  * @zgrouppriority 20
35
- */
35
+ */
36
36
  subtitle: Observable<string>;
37
37
  /** @zprop
38
38
  * @zdefault black
@@ -47,9 +47,16 @@ export declare const DefaultLoader: (props: DefaultLoaderConstructorProps, mgr:
47
47
  */
48
48
  textColor: Observable<string>;
49
49
  /** @zprop
50
- * @zdefault 1000
51
- * @zgroup Appearance
52
- * @zgrouppriority 10
53
- */
50
+ * @zdefault 1000
51
+ * @zgroup Appearance
52
+ * @zgrouppriority 10
53
+ */
54
54
  zIndex: Observable<number>;
55
- };
55
+ private _percentageElement;
56
+ private _attached;
57
+ constructor(props: DefaultLoaderConstructorProps, contextManager: ContextManager);
58
+ private _updatePercentage;
59
+ private _updateVisibility;
60
+ private _update;
61
+ dispose(): never;
62
+ }
@@ -1,4 +1,4 @@
1
- import { defineComponent, useCanvas, Observable, isDesignTime, useIsLoaded, useLoadPercent } from "../";
1
+ import { Component, useCanvas, Observable, isDesignTime, useIsLoaded, useLoadPercent } from "..";
2
2
  /**
3
3
  * The DefaultLoader shows a customizable loading bar while the assets of your experience are being downloaded and parsed by the browser.
4
4
  *
@@ -6,101 +6,70 @@ import { defineComponent, useCanvas, Observable, isDesignTime, useIsLoaded, useL
6
6
  * @zicon loader
7
7
  * @zgroup Advanced
8
8
  */
9
- export const DefaultLoader = defineComponent((props, mgr) => {
10
- const preview = new Observable(false);
11
- let disposed = false;
12
- let attached = false;
13
- const canvas = useCanvas(mgr);
14
- const div = document.createElement('div');
15
- div.innerHTML = loaderHTML;
16
- div.className = "zcomponent-defaultloader";
17
- if (props.backgroundImage) {
18
- div.style.backgroundImage = `url(${props.backgroundImage})`;
19
- }
20
- const titleElement = div.querySelector("#zcomponent-defaultloader-title") || document.createElement("h1");
21
- const subtitleElement = div.querySelector("#zcomponent-defaultloader-subtitle") || document.createElement("h1");
22
- const percentageElement = div.querySelector("#zcomponent-defaultloader-progress-percentage") || document.createElement("div");
23
- const title = new Observable('', t => titleElement.innerText = t);
24
- const subtitle = new Observable('', t => subtitleElement.innerText = t);
25
- const textColor = new Observable('white', t => div.style.color = t ?? 'white');
26
- const backgroundColor = new Observable('black', t => div.style.backgroundColor = t ?? 'black');
27
- const zIndex = new Observable(1000, t => div.style.zIndex = t.toString());
28
- const update = () => {
29
- if (disposed)
30
- return;
31
- const rect = canvas.getBoundingClientRect();
32
- div.style.left = rect.left.toString() + "px";
33
- div.style.top = rect.top.toString() + "px";
34
- div.style.width = rect.width.toString() + "px";
35
- div.style.height = rect.height.toString() + "px";
36
- requestAnimationFrame(update);
37
- };
38
- const updatePercentage = () => {
39
- const p = (isDesignTime(mgr) && preview.value) ? 30 : useLoadPercent(mgr).value;
40
- percentageElement.style.width = p.toString() + "%";
41
- };
42
- const updateVisibility = () => {
43
- let shouldBeAttached = false;
44
- if (!isDesignTime(mgr) && !useIsLoaded(mgr).value)
45
- shouldBeAttached = true;
46
- if (isDesignTime(mgr) && preview.value)
47
- shouldBeAttached = true;
48
- if (!attached && shouldBeAttached) {
49
- document.body.appendChild(div);
50
- attached = true;
51
- }
52
- else if (attached && !shouldBeAttached) {
53
- div.remove();
54
- attached = false;
55
- }
56
- };
57
- preview.withValue(updateVisibility);
58
- preview.withValue(updatePercentage);
59
- useIsLoaded(mgr).withValue(updateVisibility);
60
- useLoadPercent(mgr).withValue(updatePercentage);
61
- update();
62
- return {
63
- dispose: () => {
64
- disposed = true;
65
- useIsLoaded(mgr).removeWithValue(updateVisibility);
66
- useLoadPercent(mgr).removeWithValue(updatePercentage);
67
- },
68
- /** @zprop
69
- * @zdefault false
70
- * @zgroup Design Time
71
- * @zgrouppriority 30
72
- */
73
- preview,
74
- /** @zprop
75
- * @zgroup Text
76
- * @zgrouppriority 20
77
- */
78
- title,
9
+ export class DefaultLoader extends Component {
10
+ constructor(props, contextManager) {
11
+ super(props, contextManager);
12
+ this.root = document.createElement('div');
79
13
  /** @zprop
80
- * @zgroup Text
81
- * @zgrouppriority 20
14
+ * @zdefault false
15
+ * @zgroup Design Time
16
+ * @zgrouppriority 30
82
17
  */
83
- subtitle,
84
- /** @zprop
85
- * @zdefault black
86
- * @zgroup Appearance
87
- * @zgrouppriority 10
88
- */
89
- backgroundColor,
90
- /** @zprop
91
- * @zdefault white
92
- * @zgroup Appearance
93
- * @zgrouppriority 10
94
- */
95
- textColor,
96
- /** @zprop
97
- * @zdefault 1000
98
- * @zgroup Appearance
99
- * @zgrouppriority 10
100
- */
101
- zIndex,
102
- };
103
- });
18
+ this.preview = new Observable(false);
19
+ this._attached = false;
20
+ this._updatePercentage = () => {
21
+ const p = (isDesignTime(this.contextManager) && this.preview.value) ? 30 : useLoadPercent(this.contextManager).value;
22
+ this._percentageElement.style.width = p.toString() + "%";
23
+ };
24
+ this._updateVisibility = () => {
25
+ let shouldBeAttached = false;
26
+ if (!isDesignTime(this.contextManager) && !useIsLoaded(this.contextManager).value)
27
+ shouldBeAttached = true;
28
+ if (isDesignTime(this.contextManager) && this.preview.value)
29
+ shouldBeAttached = true;
30
+ if (!this._attached && shouldBeAttached) {
31
+ document.body.appendChild(this.root);
32
+ this._attached = true;
33
+ }
34
+ else if (this._attached && !shouldBeAttached) {
35
+ this.root.remove();
36
+ this._attached = false;
37
+ }
38
+ };
39
+ this._update = () => {
40
+ if (this.disposed)
41
+ return;
42
+ const rect = useCanvas(this.contextManager).getBoundingClientRect();
43
+ this.root.style.left = rect.left.toString() + "px";
44
+ this.root.style.top = rect.top.toString() + "px";
45
+ this.root.style.width = rect.width.toString() + "px";
46
+ this.root.style.height = rect.height.toString() + "px";
47
+ requestAnimationFrame(this._update);
48
+ };
49
+ this.root.innerHTML = loaderHTML;
50
+ this.root.className = "zcomponent-defaultloader";
51
+ if (props.backgroundImage) {
52
+ this.root.style.backgroundImage = `url(${props.backgroundImage})`;
53
+ }
54
+ const titleElement = this.root.querySelector("#zcomponent-defaultloader-title") || document.createElement("h1");
55
+ const subtitleElement = this.root.querySelector("#zcomponent-defaultloader-subtitle") || document.createElement("h1");
56
+ this._percentageElement = this.root.querySelector("#zcomponent-defaultloader-progress-percentage") || document.createElement("div");
57
+ this.title = new Observable('', t => titleElement.innerText = t);
58
+ this.subtitle = new Observable('', t => subtitleElement.innerText = t);
59
+ this.textColor = new Observable('white', t => this.root.style.color = t ?? 'white');
60
+ this.backgroundColor = new Observable('black', t => this.root.style.backgroundColor = t ?? 'black');
61
+ this.zIndex = new Observable(1000, t => this.root.style.zIndex = t.toString());
62
+ this.register(this.preview, this._updatePercentage);
63
+ this.register(this.preview, this._updateVisibility);
64
+ this.register(useIsLoaded(contextManager), this._updateVisibility);
65
+ this.register(useLoadPercent(contextManager), this._updatePercentage);
66
+ this._update();
67
+ }
68
+ dispose() {
69
+ this.root.remove();
70
+ return super.dispose();
71
+ }
72
+ }
104
73
  const loaderHTML = `
105
74
  <div id="zcomponent-defaultloader-container">
106
75
  <h1 id="zcomponent-defaultloader-title"></h1>
package/lib/observable.js CHANGED
@@ -7,11 +7,11 @@ export class Observable {
7
7
  this._handlersByToken = new Map();
8
8
  this._tokenByHandler = new Map();
9
9
  let initial = this._default;
10
- if (Array.isArray(this._default)) {
10
+ if (Array.isArray(this._default) && this._deep) {
11
11
  initial = this._default.slice();
12
12
  this._default = this._default.slice();
13
13
  }
14
- else if (typeof this._default === 'object') {
14
+ else if (typeof this._default === 'object' && this._deep && this._default !== null && Object.getPrototypeOf(this._default) !== Object.prototype) {
15
15
  initial = { ...this._default };
16
16
  this._default = { ...this._default };
17
17
  }
@@ -25,6 +25,7 @@ export class Observable {
25
25
  _wrap(v) {
26
26
  if (!Array.isArray(v) || this._deep === false) {
27
27
  if (typeof v !== 'object' ||
28
+ v === null ||
28
29
  Object.getPrototypeOf(v) !== Object.prototype ||
29
30
  this._deep === false ||
30
31
  typeof v === 'function') {
@@ -43,6 +44,8 @@ export class Observable {
43
44
  if (!Array.isArray(val)) {
44
45
  if (typeof val !== 'object')
45
46
  return val;
47
+ if (val === null)
48
+ return val;
46
49
  if (Object.getPrototypeOf(val) !== Object.prototype)
47
50
  return val;
48
51
  if (typeof val === 'function')
package/lib/selectors.js CHANGED
@@ -135,22 +135,22 @@ export const typeDefinitionForComponent = (nodes, props, scriptNames, url) => {
135
135
  }
136
136
  }
137
137
  }
138
- return `import { ZComponent, ContextManager, InstanceOfComponent } from "@zcomponent/core";
138
+ return `import { ZComponent, ContextManager, Observable } from "@zcomponent/core";
139
139
 
140
140
  ${importStrings.join('\n')}
141
141
 
142
142
  declare class Comp extends ZComponent {
143
143
 
144
- constructor(constructorProps: {}, ctx: ContextManager);
144
+ constructor(constructorProps: {}, ctx: ContextManager);
145
145
 
146
146
  nodes: {
147
147
  ${Object.entries(scriptNames).map(entry => {
148
148
  const values = Object.keys(entry[1]);
149
149
  if (values.length > 1) {
150
- return `\t\t${entry[0]}: {${values.map(e => `${JSON.stringify(e)}: InstanceOfComponent<typeof ${importMapping.get(nodes[e].type)}>`).join(', ')}},`;
150
+ return `\t\t${entry[0]}: {${values.map(e => `${JSON.stringify(e)}: ${importMapping.get(nodes[e].type)}`).join(', ')}},`;
151
151
  }
152
152
  else {
153
- return `\t\t${entry[0]}: InstanceOfComponent<typeof ${importMapping.get(nodes[values[0]].type)}>,`;
153
+ return `\t\t${entry[0]}: ${importMapping.get(nodes[values[0]].type)},`;
154
154
  }
155
155
  }).join("\n")}
156
156
  };
@@ -161,13 +161,13 @@ ${Object.values(props).map(typeOutputForProp).join('\n')}
161
161
  /**
162
162
  * @zcomponent
163
163
  */
164
- export default function ${getScriptName(path.basename(url), {})}(constructorProps: {}, mgr: ContextManager) : Comp;
164
+ export default Comp;
165
165
  `;
166
166
  };
167
167
  function typeOutputForProp(prop) {
168
- return ` /**
169
- * @zprop
170
- * ${prop.default && `@zdefault ${JSON.stringify(prop.default)}`}
171
- */
172
- public ${prop.name}: ${outputForType(prop.type)};`;
168
+ return ` /**
169
+ * @zprop
170
+ * ${prop.default && `@zdefault ${JSON.stringify(prop.default)}`}
171
+ */
172
+ public ${prop.name}: Observable<${outputForType(prop.type, true)}>;`;
173
173
  }
package/lib/types.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export interface BaseType {
2
2
  comments?: string[];
3
3
  typeHint?: TypeHint;
4
+ isObservable?: boolean;
4
5
  }
5
6
  export interface StringPrimitiveType extends BaseType {
6
7
  name: 'string';
@@ -102,4 +103,4 @@ export interface TemplateInfo {
102
103
  }
103
104
  export declare function symbolPathFromFilename(f: string): string;
104
105
  export declare function isValidValueForType(def: any, t: Type, allowUndefined?: boolean): boolean;
105
- export declare function outputForType(t: Type): string;
106
+ export declare function outputForType(t: Type, alwaysBasic?: boolean): string;
package/lib/types.js CHANGED
@@ -269,7 +269,12 @@ export function isValidValueForType(def, t, allowUndefined) {
269
269
  }
270
270
  return false;
271
271
  }
272
- export function outputForType(t) {
272
+ export function outputForType(t, alwaysBasic = false) {
273
+ if (t.isObservable && !alwaysBasic)
274
+ return `Observable<${getBasicType(t)}>`;
275
+ return getBasicType(t);
276
+ }
277
+ function getBasicType(t) {
273
278
  switch (t.name) {
274
279
  case 'array':
275
280
  return outputForType(t.child) + '[]';
@@ -1,4 +1,4 @@
1
- import { ComponentInstance, InstanceOfComponent } from './component';
1
+ import { Component, ComponentConstructor, ConstructorProps } from './component';
2
2
  import { ContextManager } from './context';
3
3
  import { ZComponentData } from './interfaces';
4
4
  export interface ZComponentOptions {
@@ -22,34 +22,32 @@ export interface ZComponentContext {
22
22
  zcomponent: ZComponent;
23
23
  }
24
24
  export declare const ZComponentContext: import("./context").ContextTypeWithDefault<ZComponentContext, [zcomponent: ZComponent<any>]>;
25
- export declare function useZComponentInstance<T extends ZComponent, K extends ((props: any, ctx: any) => T)>(ctx: ContextManager, comp?: K): InstanceOfComponent<K>;
25
+ export declare function useZComponentInstance<T extends ZComponent>(ctx: ContextManager, comp?: ComponentConstructor<T>): T;
26
26
  export declare function useConstructed(ctx: ContextManager): Promise<void>;
27
- export declare class ZComponent<RootType = any> implements ComponentInstance {
27
+ export declare class ZComponent<RootType = any> extends Component<ConstructorProps, RootType> {
28
28
  private _opts;
29
29
  id: string;
30
- root: RootType;
31
30
  idByRoot: Map<any, string>;
32
31
  nodes: {
33
- [id: string]: InstanceOfComponent<any> | InstanceOfComponent<any>[];
32
+ [id: string]: Component | Component[];
34
33
  };
35
34
  entityByID: Map<string, any>;
36
35
  private _constructedResolve;
37
36
  constructed: Promise<void>;
38
37
  isConstructed: boolean;
39
38
  private _nodesById;
40
- private _root;
41
- private _contextManager;
39
+ private _rootComponent;
42
40
  private _behaviorsToInitialize;
43
41
  constructor(constructorProps: {
44
42
  [id: string]: any;
45
- }, ctx: ContextManager, _opts: ZComponentOptions);
46
- private _inflate;
43
+ }, contextManager: ContextManager, _opts: ZComponentOptions);
44
+ private _constructorForNode;
45
+ private _constructorForBehavior;
47
46
  private _inflateBehaviors;
48
47
  private _wrapBehaviors;
49
48
  notifyPropsChanged(entries: Map<string, Set<string>>): void;
50
49
  private _initializeComponentProps;
51
50
  private _setEntityProp;
52
- _getNodeById(id: string): ComponentInstance | undefined;
53
- set _parent(v: any);
54
- dispose(): void;
51
+ _getNodeById(id: string): Component | undefined;
52
+ dispose(): never;
55
53
  }
package/lib/zcomponent.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { shouldBehaviorRunAtDesignTime } from './behavior';
2
+ import { Component } from './component';
2
3
  import { defineContextType } from './context';
3
4
  import { isDesignTime } from './contexts/environmentcontext';
4
5
  import { Observable } from './observable';
@@ -11,8 +12,10 @@ export function useZComponentInstance(ctx, comp) {
11
12
  export function useConstructed(ctx) {
12
13
  return ctx.getOrThrow(ZComponentContext)?.zcomponent.constructed;
13
14
  }
14
- export class ZComponent {
15
- constructor(constructorProps, ctx, _opts) {
15
+ export class ZComponent extends Component {
16
+ constructor(constructorProps, contextManager, _opts) {
17
+ contextManager = contextManager.fork(ZComponentContext, undefined)[0];
18
+ super(constructorProps, contextManager, { dontConstructChildren: true });
16
19
  this._opts = _opts;
17
20
  this.idByRoot = new Map();
18
21
  this.nodes = {};
@@ -21,16 +24,20 @@ export class ZComponent {
21
24
  this.isConstructed = false;
22
25
  this._nodesById = new Map();
23
26
  this._behaviorsToInitialize = [];
27
+ contextManager.getOrThrow(ZComponentContext).zcomponent = this;
24
28
  this.id = this._opts.data.id;
25
- this._initializeComponentProps();
26
- this._contextManager = ctx.fork(ZComponentContext, this)[0];
27
- this._root = this._inflate(this._opts.data.root, {}, this._contextManager);
28
- this.root = this._root?.root;
29
+ const rootConstructor = this._constructorForNode(this._opts.data.root);
30
+ if (rootConstructor) {
31
+ this._constructChildren([
32
+ [rootConstructor, {}]
33
+ ]);
34
+ }
29
35
  this._inflateBehaviors();
36
+ this._initializeComponentProps();
30
37
  this.isConstructed = true;
31
38
  this._constructedResolve();
32
39
  }
33
- _inflate(nodeId, additionalConstructorProps, ctx) {
40
+ _constructorForNode(nodeId) {
34
41
  const node = this._opts.data.nodes[nodeId];
35
42
  if (!node) {
36
43
  console.log('Warning - unable to find node with ID', nodeId);
@@ -41,80 +48,118 @@ export class ZComponent {
41
48
  console.log('Warning - unable to find constructor for type', node.type);
42
49
  return;
43
50
  }
44
- const children = additionalConstructorProps['children'] ?? [];
45
- for (const child of node.children) {
46
- children.push([
47
- (cp, ctx) => {
48
- const comp = this._inflate(child.id, cp, ctx);
49
- return {
50
- ...comp,
51
- dispose: () => {
52
- this.entityByID.delete(nodeId);
53
- this._nodesById.delete(nodeId);
54
- if (comp && typeof comp.dispose === 'function')
55
- comp.dispose();
51
+ const that = this;
52
+ return class extends construct {
53
+ constructor(constructorProps, contextManager) {
54
+ that._opts.onConstructingNode?.(nodeId);
55
+ const children = constructorProps.children ?? [];
56
+ for (const child of node?.children ?? []) {
57
+ const childInstance = that._constructorForNode(child.id);
58
+ if (childInstance)
59
+ children.push([childInstance, {}]);
60
+ }
61
+ constructorProps = {
62
+ ...constructorProps,
63
+ ...(that._opts.data.entityConstructorProps?.[nodeId] ?? {}),
64
+ ...(that._opts.constructorPropReplacement?.[nodeId] ?? {}),
65
+ children,
66
+ };
67
+ super(constructorProps, contextManager);
68
+ that.entityByID.set(nodeId, this);
69
+ that._nodesById.set(nodeId, this);
70
+ if (nodeId === that._opts.data.root) {
71
+ that._rootComponent = this;
72
+ that.root = this.root;
73
+ }
74
+ if (this.root)
75
+ that.idByRoot.set(this.root, nodeId);
76
+ if (node?.scriptName) {
77
+ const entriesForScriptName = that._opts.data.entitiesByScriptName?.[node.scriptName] ?? {};
78
+ let moreThanOne = false;
79
+ for (const entry in entriesForScriptName) {
80
+ if (entry !== node.id) {
81
+ moreThanOne = true;
82
+ break;
56
83
  }
57
- };
58
- },
59
- {}
60
- ]);
61
- }
62
- let impl;
63
- const constructorProps = {
64
- ...(this._opts.data.entityConstructorProps?.[nodeId] ?? {}),
65
- ...(this._opts.constructorPropReplacement?.[nodeId] ?? {}),
66
- ...additionalConstructorProps,
67
- children,
84
+ }
85
+ if (moreThanOne) {
86
+ const current = that.nodes[node.scriptName] ?? {};
87
+ that.nodes[node.scriptName] = current;
88
+ current[node.id] = this;
89
+ }
90
+ else {
91
+ that.nodes[node.scriptName] = this;
92
+ }
93
+ }
94
+ that._behaviorsToInitialize.push([nodeId, this, contextManager]);
95
+ const props = {
96
+ ...(that._opts.data.entityProps?.[nodeId] ?? {}),
97
+ ...(that._opts.propReplacement?.[nodeId] ?? {}),
98
+ // TOOD add forwarded props
99
+ };
100
+ for (const [key, val] of Object.entries(props)) {
101
+ try {
102
+ that._setEntityProp(this, key, val);
103
+ }
104
+ catch (err) {
105
+ console.log('Warning - unable to set entity prop', key, val);
106
+ }
107
+ }
108
+ that._opts.onConstructingNode?.(undefined);
109
+ if (that.isConstructed)
110
+ that._inflateBehaviors();
111
+ }
112
+ dispose() {
113
+ that.entityByID.delete(nodeId);
114
+ that._nodesById.delete(nodeId);
115
+ if (this.root)
116
+ that.idByRoot.delete(this.root);
117
+ return super.dispose();
118
+ }
68
119
  };
69
- this._opts.onConstructingNode?.(nodeId);
70
- try {
71
- impl = construct(constructorProps, ctx);
120
+ }
121
+ _constructorForBehavior(behaviorId) {
122
+ const node = this._opts.data.behaviors[behaviorId];
123
+ if (!node) {
124
+ console.log('Warning - unable to find behavior with ID', behaviorId);
125
+ return;
72
126
  }
73
- catch (err) {
74
- console.log('Warning - unable to construct node of type', node.type, err);
127
+ const construct = this._opts.importMapping[node.type]?.();
128
+ if (!construct) {
129
+ console.log('Warning - unable to find constructor for type', node.type);
75
130
  return;
76
131
  }
77
- this._behaviorsToInitialize.push([nodeId, impl, ctx]);
78
- if (impl.root)
79
- this.idByRoot.set(impl.root, nodeId);
80
- this._nodesById.set(nodeId, impl);
81
- this.entityByID.set(nodeId, impl);
82
- if (node.scriptName) {
83
- const entriesForScriptName = this._opts.data.entitiesByScriptName?.[node.scriptName] ?? {};
84
- let moreThanOne = false;
85
- for (const entry in entriesForScriptName) {
86
- if (entry !== node.id) {
87
- moreThanOne = true;
88
- break;
132
+ const designTime = isDesignTime(this.contextManager);
133
+ if (designTime && !shouldBehaviorRunAtDesignTime(construct))
134
+ return;
135
+ const that = this;
136
+ return class extends construct {
137
+ constructor(constructorProps, contextManager) {
138
+ constructorProps = {
139
+ ...constructorProps,
140
+ ...(that._opts.data.entityConstructorProps?.[behaviorId] ?? {}),
141
+ ...(that._opts.constructorPropReplacement?.[behaviorId] ?? {}),
142
+ };
143
+ super(constructorProps, contextManager);
144
+ that.entityByID.set(behaviorId, this);
145
+ const props = {
146
+ ...(that._opts.data.entityProps?.[behaviorId] ?? {}),
147
+ ...(that._opts.propReplacement?.[behaviorId] ?? {}),
148
+ // TOOD add forwarded props
149
+ };
150
+ for (const [key, val] of Object.entries(props)) {
151
+ try {
152
+ that._setEntityProp(this, key, val);
153
+ }
154
+ catch (err) {
155
+ console.log('Warning - unable to set entity prop', key, val);
156
+ }
89
157
  }
90
158
  }
91
- if (moreThanOne) {
92
- const current = this.nodes[node.scriptName] ?? {};
93
- this.nodes[node.scriptName] = current;
94
- current[node.id] = impl;
95
- }
96
- else {
97
- this.nodes[node.scriptName] = impl;
159
+ dispose() {
160
+ return super.dispose();
98
161
  }
99
- }
100
- if (!impl)
101
- return impl;
102
- const props = {
103
- ...(this._opts.data.entityProps?.[nodeId] ?? {}),
104
- ...(this._opts.propReplacement?.[nodeId] ?? {}),
105
162
  };
106
- for (const [key, val] of Object.entries(props)) {
107
- try {
108
- this._setEntityProp(impl, key, val);
109
- }
110
- catch (err) {
111
- console.log('Warning - unable to set node prop', key, val);
112
- }
113
- }
114
- this._opts.onConstructingNode?.(undefined);
115
- if (this.isConstructed)
116
- this._inflateBehaviors();
117
- return impl;
118
163
  }
119
164
  _inflateBehaviors() {
120
165
  for (const [nodeID, impl, ctx] of this._behaviorsToInitialize) {
@@ -124,7 +169,6 @@ export class ZComponent {
124
169
  }
125
170
  _wrapBehaviors(nodeID, impl, ctx) {
126
171
  const behaviors = this._opts.data.behaviorsByNode?.[nodeID] ?? [];
127
- const designTime = isDesignTime(this._contextManager);
128
172
  for (const behaviorID of behaviors) {
129
173
  const behavior = this._opts.data.behaviors?.[behaviorID];
130
174
  if (!behavior)
@@ -134,29 +178,10 @@ export class ZComponent {
134
178
  ...(this._opts.constructorPropReplacement?.[behaviorID] ?? {}),
135
179
  instance: impl
136
180
  };
137
- const constructor = this._opts.importMapping[behavior.type]?.();
138
- if (!constructor)
139
- continue;
140
- if (designTime && !shouldBehaviorRunAtDesignTime(constructor))
141
- continue;
142
- const res = constructor(constructorProps, ctx);
143
- if (!res)
144
- continue;
145
- this.entityByID.set(behaviorID, res);
146
- const props = {
147
- ...(this._opts.data.entityProps?.[behaviorID] ?? {}),
148
- ...(this._opts.propReplacement?.[behaviorID] ?? {}),
149
- };
150
- for (const [key, val] of Object.entries(props)) {
151
- try {
152
- this._setEntityProp(res, key, val);
153
- }
154
- catch (err) {
155
- console.log('Warning - unable to set behavior prop', key, val);
156
- }
157
- }
181
+ const constructor = this._constructorForBehavior(behaviorID);
182
+ if (constructor)
183
+ new constructor(constructorProps, ctx);
158
184
  }
159
- return impl;
160
185
  }
161
186
  notifyPropsChanged(entries) {
162
187
  for (const [entityID, propSet] of entries.entries()) {
@@ -176,25 +201,22 @@ export class ZComponent {
176
201
  _initializeComponentProps() {
177
202
  const componentProps = this._opts.data.propEntityOverrides ?? {};
178
203
  for (const [prop, entry] of Object.entries(componentProps)) {
179
- let value = undefined;
180
- Object.defineProperty(this, prop, {
181
- get: () => value,
182
- set: v => {
183
- value = v;
184
- for (const [entityID, overriddenProps] of Object.entries(entry)) {
185
- const entity = this.entityByID.get(entityID);
186
- if (!entity)
187
- continue;
188
- for (const overriddenProp of Object.keys(overriddenProps)) {
189
- try {
190
- this._setEntityProp(entity, overriddenProp, v);
191
- }
192
- catch (err) {
193
- console.log('Warning - unable to set prop', overriddenProp, v);
194
- }
204
+ const propInfo = this._opts.data.props[prop];
205
+ const entries = Object.entries(entry).map(e => [e[0], Object.keys(e[1])]);
206
+ this[prop] = new Observable(propInfo?.default, v => {
207
+ for (const e of entries) {
208
+ const entity = this.entityByID.get(e[0]);
209
+ if (!entity)
210
+ continue;
211
+ for (const overriddenProp of e[1]) {
212
+ try {
213
+ this._setEntityProp(entity, overriddenProp, v);
214
+ }
215
+ catch (err) {
216
+ console.log('Warning - unable to set prop', overriddenProp, v);
195
217
  }
196
218
  }
197
- },
219
+ }
198
220
  });
199
221
  }
200
222
  }
@@ -207,10 +229,6 @@ export class ZComponent {
207
229
  _getNodeById(id) {
208
230
  return this._nodesById.get(id);
209
231
  }
210
- set _parent(v) {
211
- if (this._root)
212
- this._root.parent = v;
213
- }
214
232
  dispose() {
215
233
  for (const entity of this.entityByID.values()) {
216
234
  if (entity && typeof entity.dispose === 'function') {
@@ -222,5 +240,6 @@ export class ZComponent {
222
240
  }
223
241
  }
224
242
  }
243
+ return super.dispose();
225
244
  }
226
245
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zcomponent/core",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
package/lib/props.d.ts DELETED
File without changes
package/lib/props.js DELETED
@@ -1,4 +0,0 @@
1
- // export function defineProperty<T extends string, V, DefType extends V>(prop: T, fn: (val: V) => void, def: DefType) : { [key in T]: V } {
2
- // const t = {};
3
- // return t as { [key in T]: V };
4
- // }