@zcomponent/core 0.0.12 → 0.0.14
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 -24
- package/lib/behavior.js +9 -52
- package/lib/component.d.ts +30 -23
- package/lib/component.js +31 -52
- package/lib/contexts/canvascontext.d.ts +2 -0
- package/lib/contexts/canvascontext.js +1 -0
- package/lib/contexts/environmentcontext.d.ts +10 -0
- package/lib/contexts/environmentcontext.js +13 -1
- package/lib/contexts/loadcontext.d.ts +5 -0
- package/lib/contexts/loadcontext.js +5 -0
- package/lib/data.d.ts +6 -1
- package/lib/data.js +82 -0
- package/lib/entity.d.ts +104 -0
- package/lib/entity.js +126 -0
- package/lib/interfaces.d.ts +30 -6
- package/lib/interfaces.js +6 -1
- package/lib/selectors.d.ts +15 -3
- package/lib/selectors.js +78 -7
- package/lib/types.d.ts +32 -4
- package/lib/types.js +73 -0
- package/lib/zcomponent.d.ts +7 -2
- package/lib/zcomponent.js +97 -17
- package/package.json +4 -3
package/lib/entity.d.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { ConstructorForComponent } from "./component";
|
|
2
|
+
import { ContextManager } from "./context";
|
|
3
|
+
import { Event } from "./event";
|
|
4
|
+
import { Observable } from "./observable";
|
|
5
|
+
import { ZComponent } from "./zcomponent";
|
|
6
|
+
export declare class Entity {
|
|
7
|
+
readonly contextManager: ContextManager;
|
|
8
|
+
private _registered;
|
|
9
|
+
private _zcomponent;
|
|
10
|
+
private _disposed;
|
|
11
|
+
/**
|
|
12
|
+
* An event that is fired as the last act of this entity being destroyed.
|
|
13
|
+
*/
|
|
14
|
+
readonly onDispose: Event<[]>;
|
|
15
|
+
constructor(contextManager: ContextManager);
|
|
16
|
+
get disposed(): boolean;
|
|
17
|
+
private set disposed(value);
|
|
18
|
+
/**
|
|
19
|
+
* If `false`, this entity and its children will no longer participate in the experience.
|
|
20
|
+
*
|
|
21
|
+
* Note - to read this value, you may wish to use `enabledResolved` which will be `false` if
|
|
22
|
+
* this entity, or any of its parents, have `enabled` set to false.
|
|
23
|
+
*
|
|
24
|
+
* The precise implications of `enabled` being false will vary between entities,
|
|
25
|
+
* but in general disabled entities:
|
|
26
|
+
* - should not emit any events,
|
|
27
|
+
* - should not take any action, e.g. navigate the user to a different page,
|
|
28
|
+
* - should not perform any network communication,
|
|
29
|
+
* - should not make changes to other behaviors or components in the experience,
|
|
30
|
+
* - should minimise any runtime performance cost (e.g. detach from any frame handlers).
|
|
31
|
+
*
|
|
32
|
+
* @zprop
|
|
33
|
+
* @zdefault true
|
|
34
|
+
* @zgroup Behavior
|
|
35
|
+
* @zgrouppriority 10
|
|
36
|
+
*/
|
|
37
|
+
enabled: Observable<boolean, never>;
|
|
38
|
+
/**
|
|
39
|
+
* This will have value `false` if this entity, or any of its parents, have `enabled` set to `false`.
|
|
40
|
+
*
|
|
41
|
+
* To change the `enabled` status of this entity, use the `enabled` property instead.
|
|
42
|
+
*
|
|
43
|
+
* The precise implications of `enabled` being false will vary between entities,
|
|
44
|
+
* but in general disabled entities:
|
|
45
|
+
* - should not emit any events,
|
|
46
|
+
* - should not take any action, e.g. navigate the user to a different page,
|
|
47
|
+
* - should not perform any network communication,
|
|
48
|
+
* - should not make changes to other behaviors or components in the experience,
|
|
49
|
+
* - should minimise any runtime performance cost.
|
|
50
|
+
*
|
|
51
|
+
* Disabled entities will typically remain visible (if they have a visible appearance).
|
|
52
|
+
*/
|
|
53
|
+
enabledResolved: Observable<boolean, never>;
|
|
54
|
+
/**
|
|
55
|
+
* Get the instance of the ZComponent that constructed this entity.
|
|
56
|
+
*
|
|
57
|
+
* If you pass the class of a ZComponent as the `type` parameter, this function will ensure that it
|
|
58
|
+
* returns an instance of that ZComponent. If this component or behavior was constructed by a different
|
|
59
|
+
* ZComponent class, or by a different entity altogether, the function with `throw` an error.
|
|
60
|
+
*
|
|
61
|
+
* @param type The ZComponent class that you are expecting to receive
|
|
62
|
+
* @returns The instance of the ZComponent that constructed this component or behavior
|
|
63
|
+
*/
|
|
64
|
+
getZComponentInstance<T extends ZComponent = ZComponent>(type?: ConstructorForComponent<T>): T;
|
|
65
|
+
/**
|
|
66
|
+
* Register a function to be called when an Event is fired, or an Observable's value changes.
|
|
67
|
+
*
|
|
68
|
+
* Using this function, rather than attaching your handler directly to the Event or Observable,
|
|
69
|
+
* ensures your handler is automatically released when this entity is disposed.
|
|
70
|
+
*
|
|
71
|
+
* @param evt The Event or Observable to listen to
|
|
72
|
+
* @param fn A function that will be called when the event fires, or the Observable value changes
|
|
73
|
+
*/
|
|
74
|
+
register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
|
|
75
|
+
register<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
|
|
76
|
+
/**
|
|
77
|
+
* Unregisters a function that was previously registered to an Event or Observable.
|
|
78
|
+
*
|
|
79
|
+
* @param evt The Event or Observable
|
|
80
|
+
* @param fn The function that was passed in the call to `register`
|
|
81
|
+
*/
|
|
82
|
+
unregister<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
|
|
83
|
+
unregister<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
|
|
84
|
+
/**
|
|
85
|
+
* Destroy this entity, cleaning up any resources that it has created and
|
|
86
|
+
* handler functions or callbacks it has registered.
|
|
87
|
+
*
|
|
88
|
+
* The base class implementation automatically unregisters any handler functions registered
|
|
89
|
+
* using `register(...)`.
|
|
90
|
+
*
|
|
91
|
+
* Override this function in your own components and behaviors to clean up any resources
|
|
92
|
+
* you have created. If you do override this function, end it with:
|
|
93
|
+
*
|
|
94
|
+
* ```
|
|
95
|
+
* return super.dispose();
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* This ensures that the dispose implementation of the parent class runs.
|
|
99
|
+
*
|
|
100
|
+
* @returns The result of a call to super.dispose()
|
|
101
|
+
*/
|
|
102
|
+
dispose(): never;
|
|
103
|
+
private static callSuperDispose;
|
|
104
|
+
}
|
package/lib/entity.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Event } from "./event";
|
|
2
|
+
import { Observable } from "./observable";
|
|
3
|
+
import { getCurrentZComponentConstruction } from "./zcomponentconstruction";
|
|
4
|
+
export class Entity {
|
|
5
|
+
constructor(contextManager) {
|
|
6
|
+
this.contextManager = contextManager;
|
|
7
|
+
this._registered = [];
|
|
8
|
+
this._disposed = false;
|
|
9
|
+
/**
|
|
10
|
+
* An event that is fired as the last act of this entity being destroyed.
|
|
11
|
+
*/
|
|
12
|
+
this.onDispose = new Event();
|
|
13
|
+
/**
|
|
14
|
+
* If `false`, this entity and its children will no longer participate in the experience.
|
|
15
|
+
*
|
|
16
|
+
* Note - to read this value, you may wish to use `enabledResolved` which will be `false` if
|
|
17
|
+
* this entity, or any of its parents, have `enabled` set to false.
|
|
18
|
+
*
|
|
19
|
+
* The precise implications of `enabled` being false will vary between entities,
|
|
20
|
+
* but in general disabled entities:
|
|
21
|
+
* - should not emit any events,
|
|
22
|
+
* - should not take any action, e.g. navigate the user to a different page,
|
|
23
|
+
* - should not perform any network communication,
|
|
24
|
+
* - should not make changes to other behaviors or components in the experience,
|
|
25
|
+
* - should minimise any runtime performance cost (e.g. detach from any frame handlers).
|
|
26
|
+
*
|
|
27
|
+
* @zprop
|
|
28
|
+
* @zdefault true
|
|
29
|
+
* @zgroup Behavior
|
|
30
|
+
* @zgrouppriority 10
|
|
31
|
+
*/
|
|
32
|
+
this.enabled = new Observable(true);
|
|
33
|
+
/**
|
|
34
|
+
* This will have value `false` if this entity, or any of its parents, have `enabled` set to `false`.
|
|
35
|
+
*
|
|
36
|
+
* To change the `enabled` status of this entity, use the `enabled` property instead.
|
|
37
|
+
*
|
|
38
|
+
* The precise implications of `enabled` being false will vary between entities,
|
|
39
|
+
* but in general disabled entities:
|
|
40
|
+
* - should not emit any events,
|
|
41
|
+
* - should not take any action, e.g. navigate the user to a different page,
|
|
42
|
+
* - should not perform any network communication,
|
|
43
|
+
* - should not make changes to other behaviors or components in the experience,
|
|
44
|
+
* - should minimise any runtime performance cost.
|
|
45
|
+
*
|
|
46
|
+
* Disabled entities will typically remain visible (if they have a visible appearance).
|
|
47
|
+
*/
|
|
48
|
+
this.enabledResolved = new Observable(true);
|
|
49
|
+
this._zcomponent = getCurrentZComponentConstruction();
|
|
50
|
+
}
|
|
51
|
+
get disposed() {
|
|
52
|
+
return this._disposed;
|
|
53
|
+
}
|
|
54
|
+
set disposed(v) {
|
|
55
|
+
this._disposed = v;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the instance of the ZComponent that constructed this entity.
|
|
59
|
+
*
|
|
60
|
+
* If you pass the class of a ZComponent as the `type` parameter, this function will ensure that it
|
|
61
|
+
* returns an instance of that ZComponent. If this component or behavior was constructed by a different
|
|
62
|
+
* ZComponent class, or by a different entity altogether, the function with `throw` an error.
|
|
63
|
+
*
|
|
64
|
+
* @param type The ZComponent class that you are expecting to receive
|
|
65
|
+
* @returns The instance of the ZComponent that constructed this component or behavior
|
|
66
|
+
*/
|
|
67
|
+
getZComponentInstance(type) {
|
|
68
|
+
if (this._zcomponent === undefined)
|
|
69
|
+
throw new Error("getZComponentInstance called in entity that's not part of a ZComponent");
|
|
70
|
+
if (!type)
|
|
71
|
+
return this._zcomponent;
|
|
72
|
+
if (this._zcomponent instanceof type)
|
|
73
|
+
return this._zcomponent;
|
|
74
|
+
throw new Error("getZComponentInstance called in entity passing wrong kind of ZComponent");
|
|
75
|
+
}
|
|
76
|
+
register(e, fn) {
|
|
77
|
+
for (const entry of this._registered) {
|
|
78
|
+
if (entry[0] === e && entry[1] === fn)
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (e instanceof Event)
|
|
82
|
+
e.bindfn(fn);
|
|
83
|
+
else if (e instanceof Observable)
|
|
84
|
+
e.withValue(fn);
|
|
85
|
+
this._registered.push([e, fn]);
|
|
86
|
+
}
|
|
87
|
+
unregister(e, fn) {
|
|
88
|
+
if (e instanceof Event)
|
|
89
|
+
e.unbindfn(fn);
|
|
90
|
+
else if (e instanceof Observable)
|
|
91
|
+
e.removeWithValue(fn);
|
|
92
|
+
this._registered = this._registered.filter(entry => (entry[0] !== e || entry[1] !== fn));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Destroy this entity, cleaning up any resources that it has created and
|
|
96
|
+
* handler functions or callbacks it has registered.
|
|
97
|
+
*
|
|
98
|
+
* The base class implementation automatically unregisters any handler functions registered
|
|
99
|
+
* using `register(...)`.
|
|
100
|
+
*
|
|
101
|
+
* Override this function in your own components and behaviors to clean up any resources
|
|
102
|
+
* you have created. If you do override this function, end it with:
|
|
103
|
+
*
|
|
104
|
+
* ```
|
|
105
|
+
* return super.dispose();
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* This ensures that the dispose implementation of the parent class runs.
|
|
109
|
+
*
|
|
110
|
+
* @returns The result of a call to super.dispose()
|
|
111
|
+
*/
|
|
112
|
+
dispose() {
|
|
113
|
+
for (const entry of this._registered) {
|
|
114
|
+
if (entry[0] instanceof Event)
|
|
115
|
+
entry[0].unbindfn(entry[1]);
|
|
116
|
+
else if (entry[0] instanceof Observable)
|
|
117
|
+
entry[0].removeWithValue(entry[1]);
|
|
118
|
+
}
|
|
119
|
+
this._registered = [];
|
|
120
|
+
this.onDispose.emit();
|
|
121
|
+
this.onDispose.clear();
|
|
122
|
+
this.disposed = true;
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
Entity.callSuperDispose = Symbol('Calling super.dispose() is mandatory');
|
package/lib/interfaces.d.ts
CHANGED
|
@@ -29,15 +29,12 @@ export interface ZComponentData {
|
|
|
29
29
|
nodes: NodeByID;
|
|
30
30
|
root: string;
|
|
31
31
|
props: Props;
|
|
32
|
+
constructorProps?: Props;
|
|
32
33
|
entityProps: PropsByID;
|
|
33
34
|
entityConstructorProps: PropsByID;
|
|
34
35
|
preview: Import;
|
|
35
|
-
|
|
36
|
-
[
|
|
37
|
-
[entityID: string]: {
|
|
38
|
-
[propName: string]: boolean;
|
|
39
|
-
};
|
|
40
|
-
};
|
|
36
|
+
entityPropOverrides?: {
|
|
37
|
+
[id: string]: EntityPropOverride;
|
|
41
38
|
};
|
|
42
39
|
behaviors: BehaviorByID;
|
|
43
40
|
animation?: Animation;
|
|
@@ -70,3 +67,30 @@ export interface BehaviorData {
|
|
|
70
67
|
order: string;
|
|
71
68
|
};
|
|
72
69
|
}
|
|
70
|
+
export type EntityPropOverride = PropEntityPropOverride | ImportEntityPropOverride | ContextValueEntityPropOverride;
|
|
71
|
+
export declare enum EntityPropOverrideType {
|
|
72
|
+
ComponentProp = "componentprop",
|
|
73
|
+
Import = "import",
|
|
74
|
+
ContextValue = "contextvalue"
|
|
75
|
+
}
|
|
76
|
+
export interface BaseEntityPropOverride {
|
|
77
|
+
id: string;
|
|
78
|
+
entityID: string;
|
|
79
|
+
entityPropPath: (string | number)[];
|
|
80
|
+
entityPropIsConstructor: boolean;
|
|
81
|
+
type: EntityPropOverrideType;
|
|
82
|
+
}
|
|
83
|
+
export interface PropEntityPropOverride extends BaseEntityPropOverride {
|
|
84
|
+
propName: string;
|
|
85
|
+
isConstructorProp: boolean;
|
|
86
|
+
type: EntityPropOverrideType.ComponentProp;
|
|
87
|
+
}
|
|
88
|
+
export interface ImportEntityPropOverride extends BaseEntityPropOverride {
|
|
89
|
+
imp: string;
|
|
90
|
+
type: EntityPropOverrideType.Import;
|
|
91
|
+
}
|
|
92
|
+
export interface ContextValueEntityPropOverride extends BaseEntityPropOverride {
|
|
93
|
+
imp: string;
|
|
94
|
+
val: string;
|
|
95
|
+
type: EntityPropOverrideType.ContextValue;
|
|
96
|
+
}
|
package/lib/interfaces.js
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
export
|
|
1
|
+
export var EntityPropOverrideType;
|
|
2
|
+
(function (EntityPropOverrideType) {
|
|
3
|
+
EntityPropOverrideType["ComponentProp"] = "componentprop";
|
|
4
|
+
EntityPropOverrideType["Import"] = "import";
|
|
5
|
+
EntityPropOverrideType["ContextValue"] = "contextvalue";
|
|
6
|
+
})(EntityPropOverrideType || (EntityPropOverrideType = {}));
|
package/lib/selectors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Import, NodeByID, ParsedImport, Props } from './interfaces';
|
|
1
|
+
import { EntityPropOverride, Import, NodeByID, ParsedImport, Props } from './interfaces';
|
|
2
2
|
export declare function parseImport(i: Import): ParsedImport;
|
|
3
3
|
export declare function constructImport(from: string, destFile: string, imp: string): string;
|
|
4
4
|
export declare function getScriptName(n: string, requireUniqueIn: {
|
|
@@ -6,8 +6,20 @@ export declare function getScriptName(n: string, requireUniqueIn: {
|
|
|
6
6
|
}): string;
|
|
7
7
|
export declare function isValidVariableName(n: string): boolean;
|
|
8
8
|
export declare function variableNameFromImport(imp: ParsedImport): string;
|
|
9
|
-
export
|
|
9
|
+
export type EntityPropOverrideByEntityPropPath = {
|
|
10
|
+
[entityID: string]: {
|
|
11
|
+
[propName: string]: {
|
|
12
|
+
[path: string]: EntityPropOverride;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare function entityPropOverrideByEntityAndProp(entityPropOverrides: {
|
|
17
|
+
[id: string]: EntityPropOverride;
|
|
18
|
+
}): EntityPropOverrideByEntityPropPath;
|
|
19
|
+
export declare function summaryForEntityPropOverrideDestination(o: EntityPropOverride): string;
|
|
20
|
+
export declare const typeDefinitionForComponent: (nodes: NodeByID, props: Props, constructorProps: Props | undefined, scriptNames: {
|
|
10
21
|
[id: string]: {
|
|
11
22
|
[id: string]: boolean;
|
|
12
23
|
};
|
|
13
|
-
}, url: string) => string;
|
|
24
|
+
} | undefined, url: string) => string;
|
|
25
|
+
export declare function getSafeKeyName(n: string): string;
|
package/lib/selectors.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EntityPropOverrideType } from './interfaces';
|
|
1
2
|
import * as path from 'path';
|
|
2
3
|
import { outputForType } from './types';
|
|
3
4
|
export function parseImport(i) {
|
|
@@ -117,11 +118,52 @@ export function variableNameFromImport(imp) {
|
|
|
117
118
|
return imp[1];
|
|
118
119
|
return 'unknown';
|
|
119
120
|
}
|
|
120
|
-
export
|
|
121
|
+
export function entityPropOverrideByEntityAndProp(entityPropOverrides) {
|
|
122
|
+
const ret = Object.create(null);
|
|
123
|
+
for (const val of Object.values(entityPropOverrides)) {
|
|
124
|
+
if (!Array.isArray(val.entityPropPath) || val.entityPropPath.length < 1)
|
|
125
|
+
continue;
|
|
126
|
+
const obj = ret[val.entityID] || Object.create(null);
|
|
127
|
+
ret[val.entityID] = obj;
|
|
128
|
+
const propName = val.entityPropPath[0];
|
|
129
|
+
const arr = obj[propName] || Object.create(null);
|
|
130
|
+
obj[propName] = arr;
|
|
131
|
+
arr[val.entityPropPath.join('.')] = val;
|
|
132
|
+
}
|
|
133
|
+
return ret;
|
|
134
|
+
}
|
|
135
|
+
export function summaryForEntityPropOverrideDestination(o) {
|
|
136
|
+
switch (o.type) {
|
|
137
|
+
case EntityPropOverrideType.ComponentProp:
|
|
138
|
+
return 'Component Prop: ' + o.propName;
|
|
139
|
+
case EntityPropOverrideType.ContextValue: {
|
|
140
|
+
const imp = parseImport(o.imp);
|
|
141
|
+
if (imp[1] === 'default' && typeof imp[0] === 'string') {
|
|
142
|
+
const parts = imp[0].split(path.sep);
|
|
143
|
+
return parts[parts.length - 1] + '.' + o.val;
|
|
144
|
+
}
|
|
145
|
+
if (typeof imp[1] === 'string')
|
|
146
|
+
return imp[1] + '.' + o.val;
|
|
147
|
+
return `?.` + o.val;
|
|
148
|
+
}
|
|
149
|
+
case EntityPropOverrideType.Import: {
|
|
150
|
+
return o.imp;
|
|
151
|
+
// const imp = parseImport(o.imp);
|
|
152
|
+
// if (imp[1] === 'default' && typeof imp[0] === 'string') {
|
|
153
|
+
// const parts = imp[0].split(path.sep);
|
|
154
|
+
// return parts[parts.length - 1];
|
|
155
|
+
// }
|
|
156
|
+
// if (typeof imp[1] === 'string') return imp[1];
|
|
157
|
+
// return '?';
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return '?';
|
|
161
|
+
}
|
|
162
|
+
export const typeDefinitionForComponent = (nodes, props, constructorProps, scriptNames, url) => {
|
|
121
163
|
const importMapping = new Map();
|
|
122
164
|
let indx = 0;
|
|
123
165
|
let importStrings = [];
|
|
124
|
-
for (const scriptNameNodes of Object.values(scriptNames)) {
|
|
166
|
+
for (const scriptNameNodes of Object.values(scriptNames ?? {})) {
|
|
125
167
|
for (const nodeID of Object.keys(scriptNameNodes)) {
|
|
126
168
|
const node = nodes[nodeID];
|
|
127
169
|
if (!node)
|
|
@@ -139,15 +181,20 @@ export const typeDefinitionForComponent = (nodes, props, scriptNames, url) => {
|
|
|
139
181
|
|
|
140
182
|
${importStrings.join('\n')}
|
|
141
183
|
|
|
184
|
+
interface ConstructorProps {
|
|
185
|
+
${Object.values(constructorProps ?? {}).map(typeOutputForConstructorProp).join('\n\n')}
|
|
186
|
+
}
|
|
187
|
+
|
|
142
188
|
/**
|
|
143
189
|
* @zcomponent
|
|
190
|
+
* @zicon zcomponent
|
|
144
191
|
*/
|
|
145
192
|
declare class Comp extends ZComponent {
|
|
146
193
|
|
|
147
|
-
constructor(contextManager: ContextManager, constructorProps:
|
|
194
|
+
constructor(contextManager: ContextManager, constructorProps: ConstructorProps);
|
|
148
195
|
|
|
149
196
|
nodes: {
|
|
150
|
-
${Object.entries(scriptNames).map(entry => {
|
|
197
|
+
${Object.entries(scriptNames ?? {}).map(entry => {
|
|
151
198
|
const values = Object.keys(entry[1]);
|
|
152
199
|
if (values.length > 1) {
|
|
153
200
|
return `\t\t${entry[0]}: {${values.map(e => `${JSON.stringify(e)}: ${importMapping.get(nodes[e].type)}`).join(', ')}},`;
|
|
@@ -158,16 +205,40 @@ ${Object.entries(scriptNames).map(entry => {
|
|
|
158
205
|
}).join("\n")}
|
|
159
206
|
};
|
|
160
207
|
|
|
161
|
-
${Object.values(props).map(typeOutputForProp).join('\n')}
|
|
208
|
+
${Object.values(props).map(typeOutputForProp).join('\n\n')}
|
|
162
209
|
}
|
|
163
210
|
|
|
164
211
|
export default Comp;
|
|
165
212
|
`;
|
|
166
213
|
};
|
|
214
|
+
function makeCommentSafe(c) {
|
|
215
|
+
return c.replaceAll('*/', '').split('\n').join('\n\t* ');
|
|
216
|
+
}
|
|
167
217
|
function typeOutputForProp(prop) {
|
|
168
|
-
|
|
218
|
+
const comments = (prop.comments && prop.comments.length > 0) ? '\n\t* ' + prop.comments.map(makeCommentSafe).join('\n\t*\n\t* ') + '\n\t* ' : '';
|
|
219
|
+
return ` /**${comments}
|
|
169
220
|
* @zprop
|
|
170
|
-
* ${prop.default
|
|
221
|
+
* ${prop.default ? `@zdefault ${JSON.stringify(prop.default)}` : ''}
|
|
171
222
|
*/
|
|
172
223
|
public ${prop.name}: Observable<${outputForType(prop.type, true)}>;`;
|
|
173
224
|
}
|
|
225
|
+
function typeOutputForConstructorProp(prop) {
|
|
226
|
+
const comments = (prop.comments && prop.comments.length > 0) ? '\n\t* ' + prop.comments.map(makeCommentSafe).join('\n\t*\n\t* ') + '\n\t* ' : '';
|
|
227
|
+
return ` /**${comments}
|
|
228
|
+
* @zprop
|
|
229
|
+
* ${prop.default && `@zdefault ${JSON.stringify(prop.default)}`}
|
|
230
|
+
*/
|
|
231
|
+
${prop.name}: ${outputForType(prop.type, true)};`;
|
|
232
|
+
}
|
|
233
|
+
export function getSafeKeyName(n) {
|
|
234
|
+
if (n.length === 0)
|
|
235
|
+
return '_';
|
|
236
|
+
let scriptname = n.replace(' ', '_');
|
|
237
|
+
scriptname = scriptname.replace('-', '_');
|
|
238
|
+
scriptname = scriptname.replace('.', '_');
|
|
239
|
+
scriptname = scriptname.replace(/[^a-zA-Z0-9_]/g, '');
|
|
240
|
+
if (scriptname.match(/^[0-9]/)) {
|
|
241
|
+
scriptname = 'n' + scriptname;
|
|
242
|
+
}
|
|
243
|
+
return scriptname;
|
|
244
|
+
}
|
package/lib/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EntityPropOverride } from "./interfaces";
|
|
1
2
|
export interface BaseType {
|
|
2
3
|
comments?: string[];
|
|
3
4
|
typeHint?: TypeHint;
|
|
@@ -23,6 +24,7 @@ export interface ArrayType extends BaseType {
|
|
|
23
24
|
export interface TupleType extends BaseType {
|
|
24
25
|
name: 'tuple';
|
|
25
26
|
children: Type[];
|
|
27
|
+
names?: string[];
|
|
26
28
|
}
|
|
27
29
|
export interface UnionType extends BaseType {
|
|
28
30
|
name: 'union';
|
|
@@ -68,10 +70,18 @@ export interface Prop {
|
|
|
68
70
|
groupPriority?: number;
|
|
69
71
|
values?: Values[];
|
|
70
72
|
}
|
|
73
|
+
export interface DefaultChild {
|
|
74
|
+
label: string;
|
|
75
|
+
type: string;
|
|
76
|
+
initialProps: {
|
|
77
|
+
[id: string]: any;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export type ComponentInfoType = "component" | "behavior" | "context";
|
|
71
81
|
export interface ComponentInfo {
|
|
72
82
|
name: string;
|
|
73
83
|
file: string;
|
|
74
|
-
type:
|
|
84
|
+
type: ComponentInfoType;
|
|
75
85
|
isDefault?: boolean;
|
|
76
86
|
constructorProps: {
|
|
77
87
|
[id: string]: Prop;
|
|
@@ -85,10 +95,23 @@ export interface ComponentInfo {
|
|
|
85
95
|
tags: string[];
|
|
86
96
|
allowedChildren: string[];
|
|
87
97
|
allowedParents?: string[];
|
|
98
|
+
defaultChildren?: DefaultChild[];
|
|
99
|
+
}
|
|
100
|
+
export interface ValueInfo {
|
|
101
|
+
name: string;
|
|
102
|
+
file: string;
|
|
103
|
+
isDefault?: boolean;
|
|
104
|
+
type: Type;
|
|
105
|
+
comments?: string[];
|
|
106
|
+
}
|
|
107
|
+
export interface SourceFileTypeInfo {
|
|
108
|
+
components: {
|
|
109
|
+
[id: string]: ComponentInfo;
|
|
110
|
+
};
|
|
111
|
+
values: {
|
|
112
|
+
[id: string]: ValueInfo;
|
|
113
|
+
};
|
|
88
114
|
}
|
|
89
|
-
export type SourceFileTypeInfo = {
|
|
90
|
-
[id: string]: ComponentInfo;
|
|
91
|
-
};
|
|
92
115
|
export type TypeInfoByFileName = {
|
|
93
116
|
[id: string]: SourceFileTypeInfo;
|
|
94
117
|
};
|
|
@@ -104,3 +127,8 @@ export interface TemplateInfo {
|
|
|
104
127
|
export declare function symbolPathFromFilename(f: string): string;
|
|
105
128
|
export declare function isValidValueForType(def: any, t: Type, allowUndefined?: boolean): boolean;
|
|
106
129
|
export declare function outputForType(t: Type, alwaysBasic?: boolean): string;
|
|
130
|
+
export declare function overridesAreCompatible(a: {
|
|
131
|
+
[path: string]: EntityPropOverride;
|
|
132
|
+
}, b: {
|
|
133
|
+
[path: string]: EntityPropOverride;
|
|
134
|
+
}): boolean;
|
package/lib/types.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { EntityPropOverrideType } from "./interfaces";
|
|
2
|
+
import { getSafeKeyName } from "./selectors";
|
|
1
3
|
export var TypeHint;
|
|
2
4
|
(function (TypeHint) {
|
|
3
5
|
TypeHint["proportion"] = "proportion";
|
|
@@ -124,6 +126,17 @@ function mergeValueComments(a, b) {
|
|
|
124
126
|
}
|
|
125
127
|
return ret;
|
|
126
128
|
}
|
|
129
|
+
function mergeTupleNames(a, b) {
|
|
130
|
+
if (!a.names || !b.names)
|
|
131
|
+
return;
|
|
132
|
+
if (a.names.length !== b.names.length)
|
|
133
|
+
return;
|
|
134
|
+
for (let i = 0; i < a.names.length; i++) {
|
|
135
|
+
if (a.names[i] !== b.names[i])
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
return a.names;
|
|
139
|
+
}
|
|
127
140
|
export function mergeTypes(a, b) {
|
|
128
141
|
if (!areTypesCompatible(a, b))
|
|
129
142
|
return;
|
|
@@ -192,6 +205,7 @@ export function mergeTypes(a, b) {
|
|
|
192
205
|
typeHint,
|
|
193
206
|
comments: mergeComments(a.comments ?? [], b.comments ?? []),
|
|
194
207
|
children,
|
|
208
|
+
names: mergeTupleNames(a, b),
|
|
195
209
|
};
|
|
196
210
|
}
|
|
197
211
|
case 'union':
|
|
@@ -279,6 +293,9 @@ function getBasicType(t) {
|
|
|
279
293
|
case 'array':
|
|
280
294
|
return outputForType(t.child) + '[]';
|
|
281
295
|
case 'tuple':
|
|
296
|
+
if (Array.isArray(t.names) && t.names.length === t.children.length) {
|
|
297
|
+
return `[${t.children.map((c, indx) => `${getSafeKeyName(t.names[indx])}: ${outputForType(c)}`).join(', ')}]`;
|
|
298
|
+
}
|
|
282
299
|
return `[${t.children.map(c => outputForType(c)).join(', ')}]`;
|
|
283
300
|
case 'unknown':
|
|
284
301
|
return 'any';
|
|
@@ -298,3 +315,59 @@ function getBasicType(t) {
|
|
|
298
315
|
return 'Event';
|
|
299
316
|
}
|
|
300
317
|
}
|
|
318
|
+
export function overridesAreCompatible(a, b) {
|
|
319
|
+
const bkeys = new Set(Object.keys(b));
|
|
320
|
+
for (const [p, obj] of Object.entries(a)) {
|
|
321
|
+
if (!b[p])
|
|
322
|
+
return false;
|
|
323
|
+
if (!overrideAreCompatible(obj, b[p]))
|
|
324
|
+
return false;
|
|
325
|
+
bkeys.delete(p);
|
|
326
|
+
}
|
|
327
|
+
if (bkeys.size > 0)
|
|
328
|
+
return false;
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
function overrideAreCompatible(a, b) {
|
|
332
|
+
if (a && b) {
|
|
333
|
+
if (a.type !== b.type)
|
|
334
|
+
return false;
|
|
335
|
+
if (a.entityPropPath.length !== b.entityPropPath.length)
|
|
336
|
+
return false;
|
|
337
|
+
if (a.entityPropIsConstructor !== b.entityPropIsConstructor)
|
|
338
|
+
return false;
|
|
339
|
+
for (let i = 0; i < a.entityPropPath.length; i++) {
|
|
340
|
+
if (a.entityPropPath[i] !== b.entityPropPath[i])
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
switch (a.type) {
|
|
344
|
+
case EntityPropOverrideType.ComponentProp: {
|
|
345
|
+
const bt = b;
|
|
346
|
+
if (a.isConstructorProp !== bt.isConstructorProp)
|
|
347
|
+
return false;
|
|
348
|
+
if (a.propName !== bt.propName)
|
|
349
|
+
return false;
|
|
350
|
+
return true;
|
|
351
|
+
}
|
|
352
|
+
case EntityPropOverrideType.ContextValue: {
|
|
353
|
+
const bt = b;
|
|
354
|
+
if (a.imp !== bt.imp)
|
|
355
|
+
return false;
|
|
356
|
+
if (a.val !== bt.val)
|
|
357
|
+
return false;
|
|
358
|
+
return true;
|
|
359
|
+
}
|
|
360
|
+
case EntityPropOverrideType.Import: {
|
|
361
|
+
const bt = b;
|
|
362
|
+
if (a.imp !== bt.imp)
|
|
363
|
+
return false;
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (!a && b)
|
|
369
|
+
return false;
|
|
370
|
+
if (a && !b)
|
|
371
|
+
return false;
|
|
372
|
+
return true;
|
|
373
|
+
}
|
package/lib/zcomponent.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Component, ComponentChildren, ConstructorProps } from './component';
|
|
2
2
|
import { ContextManager, Context } from './context';
|
|
3
|
+
import { Entity } from './entity';
|
|
3
4
|
import { ZComponentData } from './interfaces';
|
|
4
5
|
export interface ZComponentOptions {
|
|
5
6
|
data: ZComponentData;
|
|
@@ -35,21 +36,25 @@ export declare class ZComponent<RootType = any> extends Component<RootType> {
|
|
|
35
36
|
nodes: {
|
|
36
37
|
[id: string]: Component | Component[];
|
|
37
38
|
};
|
|
38
|
-
entityByID: Map<string,
|
|
39
|
-
entityByLabel: Map<string,
|
|
39
|
+
entityByID: Map<string, Entity>;
|
|
40
|
+
entityByLabel: Map<string, Entity>;
|
|
40
41
|
private _constructedResolve;
|
|
41
42
|
constructed: Promise<void>;
|
|
42
43
|
isConstructed: boolean;
|
|
43
44
|
private _nodesById;
|
|
44
45
|
private _behaviorsToInitialize;
|
|
46
|
+
private _constructorPropOverridesByEntityID;
|
|
45
47
|
constructor(contextManager: ContextManager, constructorProps: ConstructorProps, _opts: ZComponentOptions);
|
|
46
48
|
private _constructorForNode;
|
|
47
49
|
private _constructorForBehavior;
|
|
48
50
|
private _inflateBehaviors;
|
|
49
51
|
private _wrapBehaviors;
|
|
50
52
|
notifyPropsChanged(entries: Map<string, Set<string>>): void;
|
|
53
|
+
private _initializeOverrides;
|
|
54
|
+
private _initializeConstructorPropOverrides;
|
|
51
55
|
private _initializeComponentProps;
|
|
52
56
|
private _setEntityProp;
|
|
57
|
+
private _setEntityPropPath;
|
|
53
58
|
_getNodeById(id: string): Component | undefined;
|
|
54
59
|
dispose(): never;
|
|
55
60
|
}
|