@zcomponent/core 0.0.1

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.
Files changed (55) hide show
  1. package/README.md +7 -0
  2. package/css/zcomponent.css +35 -0
  3. package/index.d.ts +1 -0
  4. package/index.js +2 -0
  5. package/lib/actionbehavior.d.ts +20 -0
  6. package/lib/actionbehavior.js +32 -0
  7. package/lib/animation.d.ts +129 -0
  8. package/lib/animation.js +1 -0
  9. package/lib/behavior.d.ts +26 -0
  10. package/lib/behavior.js +10 -0
  11. package/lib/behaviors/LaunchURL.d.ts +12 -0
  12. package/lib/behaviors/LaunchURL.js +12 -0
  13. package/lib/behaviors/LogAnalyticsEvent.d.ts +10 -0
  14. package/lib/behaviors/LogAnalyticsEvent.js +10 -0
  15. package/lib/behaviors/PlaySound.d.ts +12 -0
  16. package/lib/behaviors/PlaySound.js +18 -0
  17. package/lib/component.d.ts +22 -0
  18. package/lib/component.js +4 -0
  19. package/lib/components/DefaultLoader.d.ts +55 -0
  20. package/lib/components/DefaultLoader.js +112 -0
  21. package/lib/context.d.ts +28 -0
  22. package/lib/context.js +65 -0
  23. package/lib/contexts/analyticscontext.d.ts +9 -0
  24. package/lib/contexts/analyticscontext.js +17 -0
  25. package/lib/contexts/canvascontext.d.ts +15 -0
  26. package/lib/contexts/canvascontext.js +45 -0
  27. package/lib/contexts/cookieconsentcontext.d.ts +38 -0
  28. package/lib/contexts/cookieconsentcontext.js +63 -0
  29. package/lib/contexts/environmentcontext.d.ts +9 -0
  30. package/lib/contexts/environmentcontext.js +14 -0
  31. package/lib/contexts/loadcontext.d.ts +24 -0
  32. package/lib/contexts/loadcontext.js +94 -0
  33. package/lib/contexts/usereventcontext.d.ts +12 -0
  34. package/lib/contexts/usereventcontext.js +32 -0
  35. package/lib/data.d.ts +38 -0
  36. package/lib/data.js +240 -0
  37. package/lib/event.d.ts +24 -0
  38. package/lib/event.js +61 -0
  39. package/lib/index.d.ts +13 -0
  40. package/lib/index.js +20 -0
  41. package/lib/interfaces.d.ts +67 -0
  42. package/lib/interfaces.js +1 -0
  43. package/lib/observable.d.ts +16 -0
  44. package/lib/observable.js +116 -0
  45. package/lib/props.d.ts +0 -0
  46. package/lib/props.js +4 -0
  47. package/lib/selectors.d.ts +13 -0
  48. package/lib/selectors.js +173 -0
  49. package/lib/types.d.ts +105 -0
  50. package/lib/types.js +295 -0
  51. package/lib/validators.d.ts +8 -0
  52. package/lib/validators.js +32 -0
  53. package/lib/zcomponent.d.ts +55 -0
  54. package/lib/zcomponent.js +226 -0
  55. package/package.json +40 -0
package/lib/event.js ADDED
@@ -0,0 +1,61 @@
1
+ import { Observable } from "./observable";
2
+ export class Event {
3
+ constructor() {
4
+ this.hasBindings = new Observable(false);
5
+ this._funcs = [];
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;
38
+ }
39
+ /**
40
+ * Emit an event.
41
+ *
42
+ * @param a - The argument to pass to handler functions.
43
+ */
44
+ emit(...args) {
45
+ this._emitting = true;
46
+ for (let i = 0, total = this._funcs.length; i < total; i++) {
47
+ try {
48
+ if (this._toUnbind.has(this._funcs[i]))
49
+ continue;
50
+ this._funcs[i](...args);
51
+ }
52
+ catch (ex) {
53
+ console.log('Exception in event handler', ex);
54
+ }
55
+ }
56
+ this._emitting = false;
57
+ if (this._toUnbind.size > 0) {
58
+ this._toUnbind.forEach(fn => this.unbindfn(fn));
59
+ }
60
+ }
61
+ }
package/lib/index.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ export * from './component';
2
+ export * from './behavior';
3
+ export * from './actionbehavior';
4
+ export * from './zcomponent';
5
+ export * from './context';
6
+ export * from './event';
7
+ export * from './contexts/canvascontext';
8
+ export * from './contexts/loadcontext';
9
+ export * from './contexts/cookieconsentcontext';
10
+ export * from './contexts/analyticscontext';
11
+ export * from './contexts/usereventcontext';
12
+ export * from './observable';
13
+ export * from './contexts/environmentcontext';
package/lib/index.js ADDED
@@ -0,0 +1,20 @@
1
+ export * from './component';
2
+ export * from './behavior';
3
+ export * from './actionbehavior';
4
+ export * from './zcomponent';
5
+ export * from './context';
6
+ export * from './event';
7
+ export * from './contexts/canvascontext';
8
+ export * from './contexts/loadcontext';
9
+ export * from './contexts/cookieconsentcontext';
10
+ export * from './contexts/analyticscontext';
11
+ export * from './contexts/usereventcontext';
12
+ export * from './observable';
13
+ export * from './contexts/environmentcontext';
14
+ const link = document.createElement('link');
15
+ link.setAttribute('rel', 'stylesheet');
16
+ link.setAttribute('href', new URL('../css/zcomponent.css', import.meta.url).toString());
17
+ if (document.head)
18
+ document.head.appendChild(link);
19
+ else if (document.body)
20
+ document.body.appendChild(link);
@@ -0,0 +1,67 @@
1
+ import { Prop } from './types';
2
+ export interface ID {
3
+ id: string;
4
+ }
5
+ export declare type Child = ID;
6
+ export declare type NodeByID = {
7
+ [id: string]: NodeData | undefined;
8
+ };
9
+ export declare type PropsByID = {
10
+ [id: string]: {
11
+ [id: string]: any;
12
+ } | undefined;
13
+ };
14
+ export declare type BehaviorByID = {
15
+ [id: string]: BehaviorData | undefined;
16
+ };
17
+ export declare type Props = {
18
+ [id: string]: Prop;
19
+ };
20
+ export declare type Import = string;
21
+ export declare type ParsedImport = [string, string];
22
+ export declare type ElementType = Import;
23
+ export declare type PropType = string;
24
+ export interface ZComponentData {
25
+ id: string;
26
+ nodes: NodeByID;
27
+ root: string;
28
+ props: Props;
29
+ entityProps: PropsByID;
30
+ entityConstructorProps: PropsByID;
31
+ preview: Import;
32
+ propEntityOverrides?: {
33
+ [propName: string]: {
34
+ [entityID: string]: {
35
+ [propName: string]: boolean;
36
+ };
37
+ };
38
+ };
39
+ behaviors: BehaviorByID;
40
+ behaviorsByNode: {
41
+ [nodeId: string]: string[];
42
+ };
43
+ animation?: Animation;
44
+ entitiesByLabel?: {
45
+ [id: string]: {
46
+ [id: string]: boolean;
47
+ };
48
+ };
49
+ entitiesByScriptName?: {
50
+ [id: string]: {
51
+ [id: string]: boolean;
52
+ };
53
+ };
54
+ }
55
+ export interface NodeData {
56
+ id: string;
57
+ label?: string;
58
+ scriptName?: string;
59
+ type: ElementType;
60
+ parent?: string;
61
+ children: Child[];
62
+ }
63
+ export interface BehaviorData {
64
+ id: string;
65
+ type: Import;
66
+ nodeId?: string;
67
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ export declare class Observable<T> {
2
+ private _default;
3
+ private _deep;
4
+ private _proxies;
5
+ private _value;
6
+ private _nextToken;
7
+ private _handlersByToken;
8
+ private _tokenByHandler;
9
+ constructor(_default: T, withHandler?: ((v: T) => void), _deep?: boolean);
10
+ get value(): T;
11
+ private _wrap;
12
+ set value(v: T | undefined);
13
+ withValue(fn: (v: T) => void): number;
14
+ removeWithValue(fnOrToken: number | ((v: T) => void)): void;
15
+ private _emitValue;
16
+ }
@@ -0,0 +1,116 @@
1
+ export class Observable {
2
+ constructor(_default, withHandler, _deep = true) {
3
+ this._default = _default;
4
+ this._deep = _deep;
5
+ this._proxies = new WeakMap();
6
+ this._nextToken = 0;
7
+ this._handlersByToken = new Map();
8
+ this._tokenByHandler = new Map();
9
+ let initial = this._default;
10
+ if (Array.isArray(this._default)) {
11
+ initial = this._default.slice();
12
+ this._default = this._default.slice();
13
+ }
14
+ else if (typeof this._default === 'object') {
15
+ initial = { ...this._default };
16
+ this._default = { ...this._default };
17
+ }
18
+ this._value = this._wrap(initial);
19
+ if (withHandler)
20
+ this.withValue(withHandler);
21
+ }
22
+ get value() {
23
+ return this._value.proxy;
24
+ }
25
+ _wrap(v) {
26
+ if (!Array.isArray(v) || this._deep === false) {
27
+ if (typeof v !== 'object' ||
28
+ Object.getPrototypeOf(v) !== Object.prototype ||
29
+ this._deep === false ||
30
+ typeof v === 'function') {
31
+ return { proxy: v, target: v };
32
+ }
33
+ }
34
+ const that = this;
35
+ return {
36
+ target: v,
37
+ proxy: new Proxy(v, {
38
+ get(target, p, receiver) {
39
+ const val = target[p];
40
+ if (Array.isArray(target) && p === "splice") {
41
+ return function (...args) { val.apply(target, args); that._emitValue(); };
42
+ }
43
+ if (!Array.isArray(val)) {
44
+ if (typeof val !== 'object')
45
+ return val;
46
+ if (Object.getPrototypeOf(val) !== Object.prototype)
47
+ return val;
48
+ if (typeof val === 'function')
49
+ return val;
50
+ }
51
+ if (val['__z_is_observable'])
52
+ return val;
53
+ const proxy = that._proxies.get(val) || that._wrap(val);
54
+ that._proxies.set(val, proxy);
55
+ return proxy;
56
+ },
57
+ set(target, p, val) {
58
+ target[p] = val;
59
+ that._emitValue();
60
+ return true;
61
+ },
62
+ deleteProperty(target, p) {
63
+ delete target[p];
64
+ that._emitValue();
65
+ return true;
66
+ }
67
+ })
68
+ };
69
+ }
70
+ set value(v) {
71
+ v = v ?? this._default;
72
+ if (Array.isArray(this._value.target) && Array.isArray(v)) {
73
+ this._value.target.splice(0, Infinity, ...v);
74
+ this._emitValue();
75
+ return;
76
+ }
77
+ this._value = this._wrap(v);
78
+ this._emitValue();
79
+ }
80
+ withValue(fn) {
81
+ const token = this._nextToken++;
82
+ this._handlersByToken.set(token, fn);
83
+ this._tokenByHandler.set(fn, token);
84
+ try {
85
+ fn(this._value.proxy);
86
+ }
87
+ catch (err) {
88
+ console.error(err);
89
+ }
90
+ return token;
91
+ }
92
+ removeWithValue(fnOrToken) {
93
+ if (typeof fnOrToken === 'number') {
94
+ const handler = this._handlersByToken.get(fnOrToken);
95
+ if (handler !== undefined)
96
+ this._tokenByHandler.delete(handler);
97
+ this._handlersByToken.delete(fnOrToken);
98
+ }
99
+ else {
100
+ const token = this._tokenByHandler.get(fnOrToken);
101
+ if (token !== undefined)
102
+ this._handlersByToken.delete(token);
103
+ this._tokenByHandler.delete(fnOrToken);
104
+ }
105
+ }
106
+ _emitValue() {
107
+ for (let [key, h] of this._handlersByToken) {
108
+ try {
109
+ h(this._value.proxy);
110
+ }
111
+ catch (err) {
112
+ console.error(err);
113
+ }
114
+ }
115
+ }
116
+ }
package/lib/props.d.ts ADDED
File without changes
package/lib/props.js ADDED
@@ -0,0 +1,4 @@
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
+ // }
@@ -0,0 +1,13 @@
1
+ import { Import, NodeByID, ParsedImport, Props } from './interfaces';
2
+ export declare function parseImport(i: Import): ParsedImport;
3
+ export declare function constructImport(from: string, destFile: string, imp: string): string;
4
+ export declare function getScriptName(n: string, requireUniqueIn: {
5
+ [k: string]: any;
6
+ }): string;
7
+ export declare function isValidVariableName(n: string): boolean;
8
+ export declare function variableNameFromImport(imp: ParsedImport): string;
9
+ export declare const typeDefinitionForComponent: (nodes: NodeByID, props: Props, scriptNames: {
10
+ [id: string]: {
11
+ [id: string]: boolean;
12
+ };
13
+ }, url: string) => string;
@@ -0,0 +1,173 @@
1
+ import * as path from 'path';
2
+ import { outputForType } from './types';
3
+ export function parseImport(i) {
4
+ if (typeof i !== 'string')
5
+ return ['', ''];
6
+ const indx = i.lastIndexOf('#');
7
+ if (indx < 0)
8
+ return [i, 'default'];
9
+ return [i.substr(0, indx), i.substr(indx + 1)];
10
+ }
11
+ export function constructImport(from, destFile, imp) {
12
+ if (destFile.indexOf('/node_modules/') === 0) {
13
+ return destFile.substr('/node_modules/'.length) + '#' + imp;
14
+ }
15
+ let relative = path.relative(path.dirname(from), destFile);
16
+ if (!relative.startsWith('./') && !relative.startsWith('../'))
17
+ relative = './' + relative;
18
+ return relative + '#' + imp;
19
+ }
20
+ const reservedWords = [
21
+ 'abstract',
22
+ 'arguments',
23
+ 'boolean',
24
+ 'break',
25
+ 'byte',
26
+ 'case',
27
+ 'catch',
28
+ 'char',
29
+ 'class',
30
+ 'const',
31
+ 'continue',
32
+ 'debugger',
33
+ 'default',
34
+ 'delete',
35
+ 'do',
36
+ 'double',
37
+ 'else',
38
+ 'enum',
39
+ 'eval',
40
+ 'export',
41
+ 'extends',
42
+ 'false',
43
+ 'final',
44
+ 'finally',
45
+ 'float',
46
+ 'for',
47
+ 'function',
48
+ 'goto',
49
+ 'if',
50
+ 'implements',
51
+ 'import',
52
+ 'in',
53
+ 'instanceof',
54
+ 'int',
55
+ 'interface',
56
+ 'let',
57
+ 'long',
58
+ 'native',
59
+ 'new',
60
+ 'null',
61
+ 'package',
62
+ 'private',
63
+ 'protected',
64
+ 'public',
65
+ 'return',
66
+ 'short',
67
+ 'static',
68
+ 'super',
69
+ 'switch',
70
+ 'synchronized',
71
+ 'this',
72
+ 'throw',
73
+ 'throws',
74
+ 'transient',
75
+ 'true',
76
+ 'try',
77
+ 'typeof',
78
+ 'var',
79
+ 'void',
80
+ 'volatile',
81
+ 'while',
82
+ 'with',
83
+ 'yield',
84
+ ];
85
+ export function getScriptName(n, requireUniqueIn) {
86
+ if (n === undefined || n.length === 0) {
87
+ n = 'node';
88
+ }
89
+ let scriptname = n.replace(' ', '_');
90
+ scriptname = scriptname.replace('-', '_');
91
+ scriptname = scriptname.replace('.', '_');
92
+ scriptname = scriptname.replace(/[^a-zA-Z0-9_]/g, '');
93
+ if (scriptname.match(/^[0-9]/)) {
94
+ scriptname = 'n' + scriptname;
95
+ }
96
+ if (reservedWords.indexOf(scriptname) >= 0) {
97
+ scriptname += '_';
98
+ }
99
+ let finalname = scriptname;
100
+ let indx = 0;
101
+ while (requireUniqueIn[finalname]) {
102
+ finalname = scriptname + indx;
103
+ indx++;
104
+ }
105
+ return finalname;
106
+ }
107
+ const variableNameRegex = new RegExp(/[a-zA-Z_$][0-9a-zA-Z_$]*/);
108
+ export function isValidVariableName(n) {
109
+ return variableNameRegex.test(n);
110
+ }
111
+ export function variableNameFromImport(imp) {
112
+ if (imp[1] === 'default' && typeof imp[0] === 'string') {
113
+ const parts = imp[0].split(path.sep);
114
+ return parts[parts.length - 1];
115
+ }
116
+ if (typeof imp[1] === 'string')
117
+ return imp[1];
118
+ return 'unknown';
119
+ }
120
+ export const typeDefinitionForComponent = (nodes, props, scriptNames, url) => {
121
+ const importMapping = new Map();
122
+ let indx = 0;
123
+ let importStrings = [];
124
+ for (const scriptNameNodes of Object.values(scriptNames)) {
125
+ for (const nodeID of Object.keys(scriptNameNodes)) {
126
+ const node = nodes[nodeID];
127
+ if (!node)
128
+ continue;
129
+ if (!importMapping.has(node.type)) {
130
+ const imp = parseImport(node.type);
131
+ const variable = `${getScriptName(variableNameFromImport(imp), {})}_${indx.toString()}`;
132
+ importStrings.push(`import { ${imp[1]} as ${variable} } from ${JSON.stringify(imp[0])};`);
133
+ importMapping.set(node.type, variable);
134
+ indx++;
135
+ }
136
+ }
137
+ }
138
+ return `import { ZComponent, ContextManager, InstanceOfComponent } from "@zcomponent/core";
139
+
140
+ ${importStrings.join('\n')}
141
+
142
+ declare class Comp extends ZComponent {
143
+
144
+ constructor(constructorProps: {}, ctx: ContextManager);
145
+
146
+ nodes: {
147
+ ${Object.entries(scriptNames).map(entry => {
148
+ const values = Object.keys(entry[1]);
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(', ')}},`;
151
+ }
152
+ else {
153
+ return `\t\t${entry[0]}: InstanceOfComponent<typeof ${importMapping.get(nodes[values[0]].type)}>,`;
154
+ }
155
+ }).join("\n")}
156
+ };
157
+
158
+ ${Object.values(props).map(typeOutputForProp).join('\n')}
159
+ }
160
+
161
+ /**
162
+ * @zcomponent
163
+ */
164
+ export default function ${getScriptName(path.basename(url), {})}(constructorProps: {}, mgr: ContextManager) : Comp;
165
+ `;
166
+ };
167
+ function typeOutputForProp(prop) {
168
+ return ` /**
169
+ * @zprop
170
+ * ${prop.default && `@zdefault ${JSON.stringify(prop.default)}`}
171
+ */
172
+ public ${prop.name}: ${outputForType(prop.type)};`;
173
+ }
package/lib/types.d.ts ADDED
@@ -0,0 +1,105 @@
1
+ export interface BaseType {
2
+ comments?: string[];
3
+ typeHint?: TypeHint;
4
+ }
5
+ export interface StringPrimitiveType extends BaseType {
6
+ name: 'string';
7
+ }
8
+ export interface NumberPrimitiveType extends BaseType {
9
+ name: 'number';
10
+ }
11
+ export interface BooleanPrimitiveType extends BaseType {
12
+ name: 'boolean';
13
+ }
14
+ export interface LiteralType extends BaseType {
15
+ name: 'literal';
16
+ value: string | number | boolean | undefined | null;
17
+ }
18
+ export interface ArrayType extends BaseType {
19
+ name: 'array';
20
+ child: Type;
21
+ }
22
+ export interface TupleType extends BaseType {
23
+ name: 'tuple';
24
+ children: Type[];
25
+ }
26
+ export interface UnionType extends BaseType {
27
+ name: 'union';
28
+ children: Type[];
29
+ }
30
+ export interface UnknownType extends BaseType {
31
+ name: 'unknown';
32
+ }
33
+ export interface EnumType extends BaseType {
34
+ name: 'enum';
35
+ values: {
36
+ [id: string]: string | number;
37
+ };
38
+ valueComments?: {
39
+ [id: string]: string[];
40
+ };
41
+ }
42
+ export interface FunctionType extends BaseType {
43
+ name: 'function';
44
+ args: Prop[];
45
+ ret?: Type;
46
+ }
47
+ export interface EventType extends BaseType {
48
+ name: 'event';
49
+ }
50
+ export declare type Type = StringPrimitiveType | NumberPrimitiveType | BooleanPrimitiveType | ArrayType | TupleType | UnknownType | EnumType | UnionType | LiteralType | FunctionType | EventType;
51
+ export declare enum TypeHint {
52
+ "proportion" = "proportion",
53
+ 'color-norm-rgb' = "color-norm-rgb",
54
+ 'color-unnorm-rgb' = "color-unnorm-rgb",
55
+ 'color-hex' = "color-hex"
56
+ }
57
+ export interface Values {
58
+ type: 'files' | 'animations' | 'morphTargets' | 'events' | 'parentNodes' | 'nodelabels';
59
+ param: string;
60
+ }
61
+ export interface Prop {
62
+ name: string;
63
+ type: Type;
64
+ comments?: string[];
65
+ default?: any;
66
+ group?: string;
67
+ groupPriority?: number;
68
+ values?: Values[];
69
+ }
70
+ export interface ComponentInfo {
71
+ name: string;
72
+ file: string;
73
+ type: "component" | "behavior";
74
+ isDefault?: boolean;
75
+ constructorProps: {
76
+ [id: string]: Prop;
77
+ };
78
+ props: {
79
+ [id: string]: Prop;
80
+ };
81
+ comments?: string[];
82
+ icon?: string;
83
+ group?: string;
84
+ tags: string[];
85
+ allowedChildren: string[];
86
+ allowedParents?: string[];
87
+ }
88
+ export declare type SourceFileTypeInfo = {
89
+ [id: string]: ComponentInfo;
90
+ };
91
+ export declare type TypeInfoByFileName = {
92
+ [id: string]: SourceFileTypeInfo;
93
+ };
94
+ export declare function areTypesCompatible(a: Type, b: Type): boolean;
95
+ export declare function mergeValues(a: Values[] | undefined, b: Values[] | undefined): Values[] | undefined;
96
+ export declare function mergeProps(a: Prop, b: Prop): Prop | undefined;
97
+ export declare function mergeTypes(a: Type, b: Type): Type | undefined;
98
+ export interface TemplateInfo {
99
+ name: string;
100
+ content: string;
101
+ extn?: string;
102
+ }
103
+ export declare function symbolPathFromFilename(f: string): string;
104
+ export declare function isValidValueForType(def: any, t: Type, allowUndefined?: boolean): boolean;
105
+ export declare function outputForType(t: Type): string;