ueca-react 1.0.7 → 2.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.
- package/LICENSE +1 -1
- package/README.md +109 -119
- package/dist/index.d.ts +266 -4
- package/dist/ueca-react.js +1453 -0
- package/docs/Arrays and Reactivity in UECA-React.md +158 -0
- package/docs/Automatic onChange Events in UECA-React.md +142 -0
- package/docs/Automatic onChanging Events in UECA-React.md +157 -0
- package/docs/Automatic onPropChange and onPropChanging Events in UECA-React.md +112 -0
- package/docs/Component Extension in UECA-React.md +275 -0
- package/docs/Component IDs in UECA-React.md +181 -0
- package/docs/{component-intergation-model.md → Component Integration Model in UECA-React.md } +4 -3
- package/docs/{component-mental-model.md → Component Mental Model in UECA-React.md } +4 -3
- package/docs/Introduction to UECA-React Components.md +190 -0
- package/docs/Introduction to UECA-React.md +24 -0
- package/docs/Lifecycle Hooks in UECA-React.md +237 -0
- package/docs/Message Bus in UECA-React.md +260 -0
- package/docs/Model Caching in UECA-React.md +144 -0
- package/docs/Property Bindings in UECA-React.md +191 -0
- package/docs/State Management in UECA-React.md +128 -0
- package/docs/Technology of UECA-React.md +45 -0
- package/docs/Tracing in UECA-React.md +110 -0
- package/docs/code-template.md +53 -27
- package/docs/index.md +31 -11
- package/package.json +68 -72
- package/dist/componentModel.d.ts +0 -127
- package/dist/componentModel.js +0 -772
- package/dist/dynamicContent.d.ts +0 -22
- package/dist/dynamicContent.js +0 -80
- package/dist/index.js +0 -29
- package/dist/messageBus.d.ts +0 -46
- package/dist/messageBus.js +0 -141
- package/dist/utils.d.ts +0 -8
- package/dist/utils.js +0 -52
- package/docs/base-concepts.md +0 -192
- package/docs/bindings-overview.md +0 -164
- package/docs/general-code-structure.md +0 -177
- package/docs/introduction.md +0 -56
- package/docs/message-bus.md +0 -177
- package/docs/technology.md +0 -45
package/dist/dynamicContent.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { AnyComponentModel, ComponentModel, ComponentParams, ComponentStruct, DynamicChildren } from "./componentModel";
|
|
3
|
-
type Struct = ComponentStruct<{
|
|
4
|
-
props: {
|
|
5
|
-
children: React.ReactNode;
|
|
6
|
-
_baseProps: string[];
|
|
7
|
-
_staticChildrenModels: AnyComponentModel[];
|
|
8
|
-
_childrenFromJSX: boolean;
|
|
9
|
-
_forceUpdate: boolean;
|
|
10
|
-
};
|
|
11
|
-
children: DynamicChildren;
|
|
12
|
-
methods: {
|
|
13
|
-
destroyModels: () => void;
|
|
14
|
-
forceUpdate: (children?: React.ReactNode) => void;
|
|
15
|
-
getModels: () => AnyComponentModel[];
|
|
16
|
-
getChildrenNames: () => string[];
|
|
17
|
-
};
|
|
18
|
-
}>;
|
|
19
|
-
type DynamicContentModel = ComponentModel<Struct> & Record<string, ComponentModel<ComponentStruct<{}>>>;
|
|
20
|
-
declare function useDynamicContent(params?: ComponentParams<Struct>): DynamicContentModel;
|
|
21
|
-
declare const DynamicContent: (params: ComponentParams<Struct, {}>) => JSX.Element;
|
|
22
|
-
export { DynamicContentModel, DynamicContent, useDynamicContent };
|
package/dist/dynamicContent.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.DynamicContent = void 0;
|
|
7
|
-
exports.useDynamicContent = useDynamicContent;
|
|
8
|
-
const react_1 = __importDefault(require("react"));
|
|
9
|
-
const lodash_1 = require("lodash");
|
|
10
|
-
const componentModel_1 = require("./componentModel");
|
|
11
|
-
const utils_1 = require("./utils");
|
|
12
|
-
function useDynamicContent(params) {
|
|
13
|
-
var _a;
|
|
14
|
-
const struct = {
|
|
15
|
-
props: {
|
|
16
|
-
id: useDynamicContent.name,
|
|
17
|
-
children: undefined,
|
|
18
|
-
_baseProps: [],
|
|
19
|
-
_staticChildrenModels: [],
|
|
20
|
-
_childrenFromJSX: false,
|
|
21
|
-
_forceUpdate: false
|
|
22
|
-
},
|
|
23
|
-
methods: {
|
|
24
|
-
forceUpdate: (children) => {
|
|
25
|
-
model._forceUpdate = true;
|
|
26
|
-
try {
|
|
27
|
-
model.children = undefined;
|
|
28
|
-
model.destroyModels();
|
|
29
|
-
model._childrenFromJSX = false;
|
|
30
|
-
model.children = children;
|
|
31
|
-
}
|
|
32
|
-
finally {
|
|
33
|
-
model._forceUpdate = false;
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
getModels: () => {
|
|
37
|
-
var _a;
|
|
38
|
-
let res = [];
|
|
39
|
-
if ((_a = model._baseProps) === null || _a === void 0 ? void 0 : _a.length) {
|
|
40
|
-
const childrenNames = model.getChildrenNames();
|
|
41
|
-
res = childrenNames.map(name => model[name]);
|
|
42
|
-
}
|
|
43
|
-
return res;
|
|
44
|
-
},
|
|
45
|
-
getChildrenNames: () => {
|
|
46
|
-
return Reflect.ownKeys(model).filter(c => (0, lodash_1.isString)(c) && !model._baseProps.find(p => p === c));
|
|
47
|
-
},
|
|
48
|
-
destroyModels: () => {
|
|
49
|
-
var _a;
|
|
50
|
-
const childrenNames = model.getChildrenNames();
|
|
51
|
-
const didDestroy = !!(childrenNames.length || ((_a = model._staticChildrenModels) === null || _a === void 0 ? void 0 : _a.length));
|
|
52
|
-
childrenNames.forEach(name => model[componentModel_1.$].__deleteMember(name));
|
|
53
|
-
model._staticChildrenModels = undefined;
|
|
54
|
-
didDestroy && (0, componentModel_1.componentModelDebug)(`DynamicContent: clear cache in model=#${model.birthMark()} path=${model.htmlId()}`);
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
events: {
|
|
58
|
-
onChangeChildren: () => !model._forceUpdate && !model.calledFromJSX() && !model._childrenFromJSX && model.destroyModels(),
|
|
59
|
-
},
|
|
60
|
-
View: (props) => {
|
|
61
|
-
if (model._childrenFromJSX !== !!(props === null || props === void 0 ? void 0 : props.children)) {
|
|
62
|
-
model.destroyModels();
|
|
63
|
-
}
|
|
64
|
-
model._childrenFromJSX = !!(props === null || props === void 0 ? void 0 : props.children);
|
|
65
|
-
react_1.default.useEffect(() => {
|
|
66
|
-
trap.updateCache(model);
|
|
67
|
-
model._staticChildrenModels = trap.models;
|
|
68
|
-
});
|
|
69
|
-
const trap = (0, componentModel_1.newComponentModelTrapRegistry)(model._staticChildrenModels);
|
|
70
|
-
return (react_1.default.createElement(componentModel_1.ComponentModelTrap.Provider, { value: trap }, (0, utils_1.renderNode)(model._childrenFromJSX ? props.children : model.children)));
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
const model = (0, componentModel_1.useComponent)(struct, params);
|
|
74
|
-
if (!((_a = model._baseProps) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
75
|
-
model._baseProps = Reflect.ownKeys(model).filter(x => (0, lodash_1.isString)(x));
|
|
76
|
-
}
|
|
77
|
-
return model;
|
|
78
|
-
}
|
|
79
|
-
const DynamicContent = (0, componentModel_1.getFC)(useDynamicContent);
|
|
80
|
-
exports.DynamicContent = DynamicContent;
|
package/dist/index.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isSimpleNode = exports.renderNode = exports.IF = exports.useDynamicContent = exports.DynamicContent = exports.defaultMessageBus = exports.createMessageBus = exports.useCustomMessaging = exports.useMessaging = exports.messageBusEventPost = exports.Messaging = exports.$ = exports.getFC = exports.componentModelDebug = exports.bindProp = exports.bind = exports.blankView = exports.mergeStruct = exports.useComponent = exports.newComponentModelTrapRegistry = exports.useComponentModelTrap = exports.ComponentModelTrap = void 0;
|
|
4
|
-
var componentModel_1 = require("./componentModel");
|
|
5
|
-
Object.defineProperty(exports, "ComponentModelTrap", { enumerable: true, get: function () { return componentModel_1.ComponentModelTrap; } });
|
|
6
|
-
Object.defineProperty(exports, "useComponentModelTrap", { enumerable: true, get: function () { return componentModel_1.useComponentModelTrap; } });
|
|
7
|
-
Object.defineProperty(exports, "newComponentModelTrapRegistry", { enumerable: true, get: function () { return componentModel_1.newComponentModelTrapRegistry; } });
|
|
8
|
-
Object.defineProperty(exports, "useComponent", { enumerable: true, get: function () { return componentModel_1.useComponent; } });
|
|
9
|
-
Object.defineProperty(exports, "mergeStruct", { enumerable: true, get: function () { return componentModel_1.mergeStruct; } });
|
|
10
|
-
Object.defineProperty(exports, "blankView", { enumerable: true, get: function () { return componentModel_1.blankView; } });
|
|
11
|
-
Object.defineProperty(exports, "bind", { enumerable: true, get: function () { return componentModel_1.bind; } });
|
|
12
|
-
Object.defineProperty(exports, "bindProp", { enumerable: true, get: function () { return componentModel_1.bindProp; } });
|
|
13
|
-
Object.defineProperty(exports, "componentModelDebug", { enumerable: true, get: function () { return componentModel_1.componentModelDebug; } });
|
|
14
|
-
Object.defineProperty(exports, "getFC", { enumerable: true, get: function () { return componentModel_1.getFC; } });
|
|
15
|
-
Object.defineProperty(exports, "$", { enumerable: true, get: function () { return componentModel_1.$; } });
|
|
16
|
-
var messageBus_1 = require("./messageBus");
|
|
17
|
-
Object.defineProperty(exports, "Messaging", { enumerable: true, get: function () { return messageBus_1.Messaging; } });
|
|
18
|
-
Object.defineProperty(exports, "messageBusEventPost", { enumerable: true, get: function () { return messageBus_1.messageBusEventPost; } });
|
|
19
|
-
Object.defineProperty(exports, "useMessaging", { enumerable: true, get: function () { return messageBus_1.useMessaging; } });
|
|
20
|
-
Object.defineProperty(exports, "useCustomMessaging", { enumerable: true, get: function () { return messageBus_1.useCustomMessaging; } });
|
|
21
|
-
Object.defineProperty(exports, "createMessageBus", { enumerable: true, get: function () { return messageBus_1.createMessageBus; } });
|
|
22
|
-
Object.defineProperty(exports, "defaultMessageBus", { enumerable: true, get: function () { return messageBus_1.defaultMessageBus; } });
|
|
23
|
-
var dynamicContent_1 = require("./dynamicContent");
|
|
24
|
-
Object.defineProperty(exports, "DynamicContent", { enumerable: true, get: function () { return dynamicContent_1.DynamicContent; } });
|
|
25
|
-
Object.defineProperty(exports, "useDynamicContent", { enumerable: true, get: function () { return dynamicContent_1.useDynamicContent; } });
|
|
26
|
-
var utils_1 = require("./utils");
|
|
27
|
-
Object.defineProperty(exports, "IF", { enumerable: true, get: function () { return utils_1.IF; } });
|
|
28
|
-
Object.defineProperty(exports, "renderNode", { enumerable: true, get: function () { return utils_1.renderNode; } });
|
|
29
|
-
Object.defineProperty(exports, "isSimpleNode", { enumerable: true, get: function () { return utils_1.isSimpleNode; } });
|
package/dist/messageBus.d.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
type AnyName = string;
|
|
2
|
-
type InParam = {
|
|
3
|
-
in: any;
|
|
4
|
-
};
|
|
5
|
-
type OutParam = {
|
|
6
|
-
out: any;
|
|
7
|
-
};
|
|
8
|
-
type AnyMessage = Record<string, InParam | OutParam | InParam & OutParam | {}>;
|
|
9
|
-
type ParamIn<TMsg extends AnyMessage, Msg extends keyof TMsg> = TMsg[Msg] extends InParam ? TMsg[Msg][keyof InParam] : undefined;
|
|
10
|
-
type ParamOut<TMsg extends AnyMessage, Msg extends keyof TMsg> = TMsg[Msg] extends OutParam ? TMsg[Msg][keyof OutParam] : undefined;
|
|
11
|
-
type GetMethod<TMsg extends AnyMessage> = <Msg extends keyof TMsg>(message: Msg, param: ParamIn<TMsg, Msg>, callback: (param: ParamOut<TMsg, Msg>) => void) => void;
|
|
12
|
-
type PostMethod<TMsg extends AnyMessage> = <Msg extends keyof TMsg>(message: Msg, param: ParamIn<TMsg, Msg>, callback?: (param: ParamOut<TMsg, Msg>) => void) => void;
|
|
13
|
-
type AsyncMethod<TMsg extends AnyMessage> = <Msg extends keyof TMsg>(message: Msg, param: ParamIn<TMsg, Msg>) => Promise<ParamOut<TMsg, Msg>>;
|
|
14
|
-
type TargetGetMethod<TMsg extends AnyMessage, TName extends AnyName> = <Msg extends keyof TMsg>(target: TName, message: Msg, param: ParamIn<TMsg, Msg>, callback: (param: ParamOut<TMsg, Msg>) => void) => void;
|
|
15
|
-
type TargetPostMethod<TMsg extends AnyMessage, TName extends AnyName> = <Msg extends keyof TMsg>(target: TName, message: Msg, param: ParamIn<TMsg, Msg>, callback?: (param: ParamOut<TMsg, Msg>) => void) => void;
|
|
16
|
-
type TargetAsyncMethod<TMsg extends AnyMessage, TName extends AnyName> = <Msg extends keyof TMsg>(target: TName, message: Msg, param: ParamIn<TMsg, Msg>) => Promise<ParamOut<TMsg, Msg>>;
|
|
17
|
-
interface IMessageBus<TMsg extends AnyMessage, TName extends AnyName> {
|
|
18
|
-
readonly name?: TName;
|
|
19
|
-
readonly get: GetMethod<TMsg>;
|
|
20
|
-
readonly post: PostMethod<TMsg>;
|
|
21
|
-
readonly getFrom: TargetGetMethod<TMsg, TName>;
|
|
22
|
-
readonly postTo: TargetPostMethod<TMsg, TName>;
|
|
23
|
-
readonly getAsync: AsyncMethod<TMsg>;
|
|
24
|
-
readonly postAsync: AsyncMethod<TMsg>;
|
|
25
|
-
readonly getFromAsync: TargetAsyncMethod<TMsg, TName>;
|
|
26
|
-
readonly postToAsync: TargetAsyncMethod<TMsg, TName>;
|
|
27
|
-
as<M extends AnyMessage, N extends AnyName = TName>(): IMessageBus<M, N>;
|
|
28
|
-
}
|
|
29
|
-
type MessageHandler<TMsg extends AnyMessage, Msg extends keyof TMsg> = (param: ParamIn<TMsg, Msg>) => ParamOut<TMsg, Msg> extends undefined ? Promise<void> : Promise<ParamOut<TMsg, Msg>>;
|
|
30
|
-
type MessageHandlerNoPar<TMsg extends AnyMessage, Msg extends keyof TMsg> = () => ParamOut<TMsg, Msg> extends undefined ? Promise<void> : Promise<ParamOut<TMsg, Msg>>;
|
|
31
|
-
type Messages<TMsg extends AnyMessage> = {
|
|
32
|
-
[Msg in keyof TMsg]?: ParamIn<TMsg, Msg> extends undefined ? MessageHandlerNoPar<TMsg, Msg> : MessageHandler<TMsg, Msg>;
|
|
33
|
-
};
|
|
34
|
-
declare function useMessaging<TMsg extends AnyMessage, TName extends AnyName>(incoming?: Messages<TMsg>, name?: TName): IMessageBus<TMsg, TName>;
|
|
35
|
-
declare function useCustomMessaging<TMsg extends AnyMessage, TName extends AnyName>(bus: IMessageBus<TMsg, TName>, incoming?: Messages<TMsg>, name?: TName): IMessageBus<TMsg, TName>;
|
|
36
|
-
declare function createMessageBus<TMsg extends AnyMessage, TName extends AnyName>(name?: string): IMessageBus<TMsg, TName>;
|
|
37
|
-
declare const messageBusEventPost = "messagebus.post";
|
|
38
|
-
type MessageBusEvent = Event & {
|
|
39
|
-
detail: {
|
|
40
|
-
message: string;
|
|
41
|
-
params?: any;
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
|
-
declare const Messaging: import("react").Context<IMessageBus<AnyMessage, any>>;
|
|
45
|
-
declare function defaultMessageBus<TMsg extends AnyMessage>(): IMessageBus<TMsg, any>;
|
|
46
|
-
export { IMessageBus, Messages, AsyncMethod, AnyMessage, MessageBusEvent, AnyName, Messaging, messageBusEventPost, useMessaging, useCustomMessaging, createMessageBus, defaultMessageBus };
|
package/dist/messageBus.js
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.messageBusEventPost = exports.Messaging = void 0;
|
|
4
|
-
exports.useMessaging = useMessaging;
|
|
5
|
-
exports.useCustomMessaging = useCustomMessaging;
|
|
6
|
-
exports.createMessageBus = createMessageBus;
|
|
7
|
-
exports.defaultMessageBus = defaultMessageBus;
|
|
8
|
-
const react_1 = require("react");
|
|
9
|
-
function useMessaging(incoming, name) {
|
|
10
|
-
return useCustomMessaging((0, react_1.useContext)(Messaging), incoming, name);
|
|
11
|
-
}
|
|
12
|
-
function useCustomMessaging(bus, incoming, name) {
|
|
13
|
-
(0, react_1.useEffect)(() => {
|
|
14
|
-
if (incoming) {
|
|
15
|
-
const messageRecepient = {
|
|
16
|
-
id: generateId(),
|
|
17
|
-
name: name,
|
|
18
|
-
messages: incoming
|
|
19
|
-
};
|
|
20
|
-
bus.subscribe(messageRecepient);
|
|
21
|
-
return () => bus.unsubscribe(messageRecepient);
|
|
22
|
-
}
|
|
23
|
-
}, [incoming, bus, name]);
|
|
24
|
-
return bus;
|
|
25
|
-
function generateId() {
|
|
26
|
-
return Date.now().toString(36) + Math.random().toString(36).substring(2, 5);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
function createMessageBus(name) {
|
|
30
|
-
const bus = {
|
|
31
|
-
name: name,
|
|
32
|
-
subscribers: [],
|
|
33
|
-
messageQueue: [],
|
|
34
|
-
as: () => bus,
|
|
35
|
-
get: (messageType, param, callback) => _queueMessage({ message: messageType, param: param, callback: callback }),
|
|
36
|
-
getFrom: (target, messageType, param, callback) => _queueMessage({ target: target, message: messageType, param: param, callback: callback }),
|
|
37
|
-
post: (messageType, param, callback) => _queueMessage({ message: messageType, param: param, callback: callback }),
|
|
38
|
-
postTo: (target, messageType, param, callback) => _queueMessage({ target: target, message: messageType, param: param, callback: callback }),
|
|
39
|
-
getAsync: (messageType, param) => {
|
|
40
|
-
return new Promise((resolve, reject) => bus.get(messageType, param, result => _promiseCallback(result, messageType, resolve, reject)));
|
|
41
|
-
},
|
|
42
|
-
getFromAsync: (target, messageType, param) => {
|
|
43
|
-
return new Promise((resolve, reject) => bus.getFrom(target, messageType, param, result => _promiseCallback(result, messageType, resolve, reject)));
|
|
44
|
-
},
|
|
45
|
-
postAsync: (messageType, param) => {
|
|
46
|
-
return new Promise((resolve, reject) => bus.post(messageType, param, result => _promiseCallback(result, messageType, resolve, reject)));
|
|
47
|
-
},
|
|
48
|
-
postToAsync: (target, messageType, param) => {
|
|
49
|
-
return new Promise((resolve, reject) => bus.postTo(target, messageType, param, result => _promiseCallback(result, messageType, resolve, reject)));
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
bus.subscribe = (recipient) => {
|
|
53
|
-
let subscriber = bus.subscribers.find((s) => s.id === recipient.id);
|
|
54
|
-
subscriber ?
|
|
55
|
-
subscriber.messages = recipient.messages :
|
|
56
|
-
bus.subscribers.push(recipient);
|
|
57
|
-
};
|
|
58
|
-
bus.unsubscribe = (recipient) => {
|
|
59
|
-
bus.subscribers = bus.subscribers.filter((s) => s.id !== recipient.id);
|
|
60
|
-
};
|
|
61
|
-
function isValidResult(result) {
|
|
62
|
-
return !(result && (result instanceof Error));
|
|
63
|
-
}
|
|
64
|
-
bus.processMessages = () => {
|
|
65
|
-
const msgCount = bus.messageQueue.length;
|
|
66
|
-
if (msgCount === 0)
|
|
67
|
-
return;
|
|
68
|
-
bus.messageQueue.forEach(message => {
|
|
69
|
-
let dispatched = false;
|
|
70
|
-
let targetFound = false;
|
|
71
|
-
bus.subscribers.forEach(subscriber => {
|
|
72
|
-
const method = subscriber.messages[message.message];
|
|
73
|
-
targetFound = targetFound || (message.target ? message.target === subscriber.name : false);
|
|
74
|
-
if (method !== undefined && (!message.target || message.target === subscriber.name)) {
|
|
75
|
-
const methodPromise = method(message.param);
|
|
76
|
-
if (methodPromise) {
|
|
77
|
-
methodPromise.catch(reason => { var _a; return (_a = message.callback) === null || _a === void 0 ? void 0 : _a.call(message, reason); });
|
|
78
|
-
methodPromise.then(methodResult => { var _a; return (_a = message.callback) === null || _a === void 0 ? void 0 : _a.call(message, methodResult); }, reason => { var _a; return (_a = message.callback) === null || _a === void 0 ? void 0 : _a.call(message, reason); });
|
|
79
|
-
}
|
|
80
|
-
dispatched = true;
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
if (!dispatched) {
|
|
84
|
-
if (!message.target) {
|
|
85
|
-
console.warn(`MessageBus (${bus.name}): no subscribers for message "${String(message.message)}"`);
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
(targetFound
|
|
89
|
-
? console.warn(`MessageBus (${bus.name}): target "${message.target}" has no subscription for message "${String(message.message)}"`)
|
|
90
|
-
: console.warn(`MessageBus (${bus.name}): target "${message.target}" not found"`));
|
|
91
|
-
}
|
|
92
|
-
if (message.callback) {
|
|
93
|
-
message.callback(undefined);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
if (bus.messageQueue.length > msgCount) {
|
|
98
|
-
bus.messageQueue = bus.messageQueue.splice(msgCount);
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
bus.messageQueue = [];
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
return bus;
|
|
105
|
-
function _queueMessage(msg) {
|
|
106
|
-
bus.messageQueue.push(msg);
|
|
107
|
-
setTimeout(() => {
|
|
108
|
-
try {
|
|
109
|
-
bus.processMessages();
|
|
110
|
-
}
|
|
111
|
-
catch (e) {
|
|
112
|
-
console.error("Message bus crashed", e);
|
|
113
|
-
}
|
|
114
|
-
}, 0);
|
|
115
|
-
}
|
|
116
|
-
function _promiseCallback(result, messageType, resolve, reject) {
|
|
117
|
-
if (isValidResult(result)) {
|
|
118
|
-
resolve(result);
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
reject(result);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
;
|
|
126
|
-
const messageBusEventPost = "messagebus.post";
|
|
127
|
-
exports.messageBusEventPost = messageBusEventPost;
|
|
128
|
-
function createDefaultMessageBus() {
|
|
129
|
-
const defaultMessageBus = createMessageBus("Default Message Bus");
|
|
130
|
-
window.addEventListener(messageBusEventPost, _onPost);
|
|
131
|
-
return defaultMessageBus;
|
|
132
|
-
function _onPost(event) {
|
|
133
|
-
defaultMessageBus.post(event.detail.message, event.detail.params);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
const _defaultMessageBus = createDefaultMessageBus();
|
|
137
|
-
const Messaging = (0, react_1.createContext)(_defaultMessageBus);
|
|
138
|
-
exports.Messaging = Messaging;
|
|
139
|
-
function defaultMessageBus() {
|
|
140
|
-
return _defaultMessageBus;
|
|
141
|
-
}
|
package/dist/utils.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
declare function IF(props: {
|
|
3
|
-
condition: boolean;
|
|
4
|
-
children: React.ReactNode;
|
|
5
|
-
}): JSX.Element;
|
|
6
|
-
declare function renderNode(node: React.ReactNode | (() => React.ReactNode)): any;
|
|
7
|
-
declare function isSimpleNode(node: React.ReactNode): boolean;
|
|
8
|
-
export { IF, renderNode, isSimpleNode };
|
package/dist/utils.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.IF = IF;
|
|
37
|
-
exports.renderNode = renderNode;
|
|
38
|
-
exports.isSimpleNode = isSimpleNode;
|
|
39
|
-
const React = __importStar(require("react"));
|
|
40
|
-
const _ = __importStar(require("lodash"));
|
|
41
|
-
function IF(props) {
|
|
42
|
-
return props.condition ? React.createElement(React.Fragment, null, renderNode(props.children)) : null;
|
|
43
|
-
}
|
|
44
|
-
function renderNode(node) {
|
|
45
|
-
return _.isFunction(node) ? node() : node;
|
|
46
|
-
}
|
|
47
|
-
function isSimpleNode(node) {
|
|
48
|
-
if (_.isString(node) || _.isNumber(node) || _.isBoolean(node) || _.isNull(node) || _.isUndefined(node)) {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
return false;
|
|
52
|
-
}
|
package/docs/base-concepts.md
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
# UECA Base Concepts
|
|
2
|
-
|
|
3
|
-
This section covers the base concepts of UECA, providing you with a foundational understanding of the architecture and its principles. By mastering these concepts, you'll be well-equipped to develop scalable, maintainable, and modular applications.
|
|
4
|
-
|
|
5
|
-
## Introduction to UECA
|
|
6
|
-
|
|
7
|
-
UECA is a modern framework designed to enhance the development of web applications by promoting encapsulation, modularity, and maintainability. It leverages TypeScript and JSX to create robust, type-safe components with minimal reliance on React-specific features.
|
|
8
|
-
|
|
9
|
-
## Core Principles of UECA
|
|
10
|
-
|
|
11
|
-
### Encapsulation
|
|
12
|
-
|
|
13
|
-
Encapsulation is a core principle of UECA, ensuring that each component manages its own state and behavior while exposing only necessary interfaces. This reduces code complexity and enhances maintainability by keeping implementation details hidden from other components.
|
|
14
|
-
|
|
15
|
-
### Declarative and Modular Code Style
|
|
16
|
-
|
|
17
|
-
UECA emphasizes a declarative and modular approach to coding. This means focusing on what the application should do rather than how it should do it, and breaking down the application into smaller, reusable components. This approach enhances readability and maintainability.
|
|
18
|
-
|
|
19
|
-
### Minimal React Usage
|
|
20
|
-
|
|
21
|
-
UECA uses React's custom hooks for component model instantiation but avoids other React features like class components, `useState`, and `useEffect`. This simplifies the architecture and makes the codebase more approachable for developers with a TypeScript background.
|
|
22
|
-
|
|
23
|
-
### Consistency
|
|
24
|
-
|
|
25
|
-
Consistency is key in UECA. By using [standard code templates](./code-template.md) and maintaining a uniform structure across components, developers can easily navigate and understand the codebase. This consistency reduces the cognitive load and helps maintain high code quality.
|
|
26
|
-
|
|
27
|
-
## Base Components of UECA
|
|
28
|
-
|
|
29
|
-
### TypeScript
|
|
30
|
-
|
|
31
|
-
TypeScript is the primary language used in UECA development. It provides static typing, enhancing code quality and maintainability. TypeScript's type system helps catch errors early and ensures that components are used correctly throughout the application.
|
|
32
|
-
|
|
33
|
-
### JSX
|
|
34
|
-
|
|
35
|
-
JSX is used to describe the UI in a syntax familiar to both JavaScript and HTML. Combined with TypeScript, JSX allows for type-checked components, reducing runtime errors and improving development efficiency.
|
|
36
|
-
|
|
37
|
-
### React Custom Hooks
|
|
38
|
-
|
|
39
|
-
Custom hooks are the only React feature heavily used in UECA. They are employed to instantiate and manage the lifecycle of component models, integrating React’s state and effect management seamlessly into UECA.
|
|
40
|
-
|
|
41
|
-
## Component Structure
|
|
42
|
-
|
|
43
|
-
A typical UECA component consists of the following sections:
|
|
44
|
-
|
|
45
|
-
### Props
|
|
46
|
-
|
|
47
|
-
Props are properties that serve as inputs to the component. They define the initial state and configuration of the component.
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
props: {
|
|
51
|
-
title: "Default Title",
|
|
52
|
-
},
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Events
|
|
56
|
-
|
|
57
|
-
Events are custom events that the component can trigger and handle. They allow for interaction and communication within the component.
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
events: {
|
|
61
|
-
onAction: () => {
|
|
62
|
-
console.log("Action triggered");
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### Children
|
|
68
|
-
|
|
69
|
-
Children are the nested components within this component. They promote reusability and modularity by allowing components to be composed together.
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
children: {
|
|
73
|
-
okButton: useButton({
|
|
74
|
-
caption: "OK",
|
|
75
|
-
onClick: () => _processOrder()
|
|
76
|
-
}),
|
|
77
|
-
},
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Methods
|
|
81
|
-
|
|
82
|
-
Methods are functions that the component can execute. They define the behavior and logic of the component.
|
|
83
|
-
|
|
84
|
-
```typescript
|
|
85
|
-
methods: {
|
|
86
|
-
performAction: () => {
|
|
87
|
-
console.log("Action performed");
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
toolbarView: () => JSX.Element,
|
|
91
|
-
},
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### Messages
|
|
95
|
-
|
|
96
|
-
Messages are used for inter-component communication via the message bus system. They promote a decoupled architecture by allowing components to send and receive messages without direct dependencies.
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
// Component 1 - message sender
|
|
100
|
-
children: {
|
|
101
|
-
okButton: useButton({
|
|
102
|
-
caption: "OK",
|
|
103
|
-
onClick: async () => {
|
|
104
|
-
const reportData = await model.getAsync("API.getReportData", { reportId: model.reportId });
|
|
105
|
-
_updateReportPreview(reportData);
|
|
106
|
-
}
|
|
107
|
-
}),
|
|
108
|
-
},
|
|
109
|
-
|
|
110
|
-
// Component 2 - message receiver
|
|
111
|
-
messages: {
|
|
112
|
-
"API.getReportData": async ({ reportId }) => await model.apiService.getReportData(reportId),
|
|
113
|
-
},
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### Lifecycle Hooks
|
|
117
|
-
|
|
118
|
-
Lifecycle hooks manage the initialization, mounting, and unmounting processes of the component.
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
init: () => {
|
|
122
|
-
console.log("Model create. Component initialized.");
|
|
123
|
-
},
|
|
124
|
-
|
|
125
|
-
mount: () => {
|
|
126
|
-
console.log("Component mounted to React DOM");
|
|
127
|
-
},
|
|
128
|
-
|
|
129
|
-
unmount: () => {
|
|
130
|
-
console.log("Component unmounted from React DOM");
|
|
131
|
-
},
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### View
|
|
135
|
-
|
|
136
|
-
The `View` function defines the JSX that represents the component's UI. It should end with "View" if it returns JSX.
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
View: () => (
|
|
140
|
-
<div>
|
|
141
|
-
<model.toolbar.View />
|
|
142
|
-
<div>
|
|
143
|
-
<model.mainMenu.View />
|
|
144
|
-
<div>
|
|
145
|
-
<model.topBar.View />
|
|
146
|
-
<model.activeScreen.View />
|
|
147
|
-
<model.bottomBar.View />
|
|
148
|
-
</div>
|
|
149
|
-
</div>
|
|
150
|
-
<model.copirightBandView />
|
|
151
|
-
</div>
|
|
152
|
-
),
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
## Automatic Events
|
|
156
|
-
|
|
157
|
-
UECA supports automatic events for properties, such as `onChange$Property$` and `onChanging$Property$`. These events are triggered when a property changes, facilitating reactive programming within components.
|
|
158
|
-
|
|
159
|
-
### onChange$Property$
|
|
160
|
-
|
|
161
|
-
The `onChange$Property$` event is triggered after a property value is updated. It allows you to react to changes in the property.
|
|
162
|
-
|
|
163
|
-
```typescript
|
|
164
|
-
events: {
|
|
165
|
-
onChangeTitle: (newValue: string) => {
|
|
166
|
-
console.log(`Title changed to ${newValue}`);
|
|
167
|
-
},
|
|
168
|
-
|
|
169
|
-
onChangeMyProperty: (newValue: MyType) => {
|
|
170
|
-
console.log(`MyProperty changed to ${newValue}`);
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### onChanging$Property$
|
|
176
|
-
|
|
177
|
-
The `onChanging$Property$` event acts as a value change interceptor, allowing you to validate or modify the value before it is committed.
|
|
178
|
-
|
|
179
|
-
```typescript
|
|
180
|
-
events: {
|
|
181
|
-
onChangingTitle: (newValue: string, oldValue: string) => {
|
|
182
|
-
if (newValue.trim() === "") {
|
|
183
|
-
return oldValue; // Revert to old value if new value is invalid
|
|
184
|
-
}
|
|
185
|
-
return newValue;
|
|
186
|
-
},
|
|
187
|
-
},
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
## Conclusion
|
|
191
|
-
|
|
192
|
-
Understanding these base concepts is crucial for mastering UECA. By focusing on encapsulation, modularity, and consistency, UECA provides a robust framework for developing scalable and maintainable web applications. This tutorial will guide you through the practical applications of these concepts, helping you build efficient and high-quality components.
|