xmlui 0.7.20 → 0.7.21
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/dist/{apiInterceptorWorker-D3L7dpSV.mjs → apiInterceptorWorker-LRHkKnha.mjs} +1 -1
- package/dist/{grammar.tmLanguage-69iP6c5d.mjs → grammar.tmLanguage-DNepe_jP.mjs} +1 -1
- package/dist/index-5NLXyjX0.mjs +31055 -0
- package/dist/index.css +1 -1
- package/dist/scripts/bin/build-lib.js +1 -1
- package/dist/scripts/bin/index.js +2 -2
- package/dist/scripts/bin/start.js +23 -6
- package/dist/scripts/bin/viteConfig.js +1 -0
- package/dist/scripts/package.json +2 -1
- package/dist/scripts/src/abstractions/ExtensionDefs.js +2 -0
- package/dist/scripts/src/components/ComponentProvider.js +171 -148
- package/dist/scripts/src/components/FormItem/FormItemNative.js +1 -1
- package/dist/scripts/src/components/HtmlTags/HtmlTags.js +33 -0
- package/dist/scripts/src/components/RawHtml/RawHtml.js +39 -0
- package/dist/scripts/src/components/RawHtml/RawHtmlNative.js +13 -0
- package/dist/scripts/src/components/Theme/ThemeNative.js +1 -1
- package/dist/scripts/src/components-core/LoaderComponent.js +1 -1
- package/dist/scripts/src/components-core/RestApiProxy.js +1 -1
- package/dist/scripts/src/components-core/StandaloneApp.js +19 -19
- package/dist/scripts/src/components-core/{StandaloneComponentManager.js → StandaloneExtensionManager.js} +6 -13
- package/dist/scripts/src/components-core/action/APICall.js +1 -1
- package/dist/scripts/src/components-core/loader/PageableLoader.js +4 -4
- package/dist/scripts/src/components-core/{AppRoot.js → rendering/AppContent.js} +60 -145
- package/dist/scripts/src/components-core/rendering/AppRoot.js +55 -0
- package/dist/scripts/src/components-core/rendering/AppWrapper.js +44 -0
- package/dist/scripts/src/components-core/{ComponentBed.js → rendering/ComponentAdapter.js} +8 -8
- package/dist/scripts/src/components-core/rendering/ComponentWrapper.js +147 -0
- package/dist/scripts/src/components-core/rendering/Container.js +576 -0
- package/dist/scripts/src/components-core/rendering/ContainerWrapper.js +82 -0
- package/dist/scripts/src/components-core/{ErrorBoundary.js → rendering/ErrorBoundary.js} +9 -3
- package/dist/scripts/src/components-core/rendering/StateContainer.js +331 -0
- package/dist/scripts/src/components-core/{container → rendering}/buildProxy.js +11 -7
- package/dist/scripts/src/components-core/{container → rendering}/collectFnVarDeps.js +2 -2
- package/dist/scripts/src/components-core/{container → rendering}/reducer.js +3 -0
- package/dist/scripts/src/components-core/rendering/renderChild.js +81 -0
- package/dist/scripts/src/index.js +3 -6
- package/dist/scripts/src/parsers/xmlui-parser/transform.js +193 -164
- package/dist/scripts/src/syntax/grammar.tmLanguage.json +1 -1
- package/dist/style.css +1 -1
- package/dist/xmlui-metadata.mjs +4216 -4232
- package/dist/xmlui-metadata.umd.js +16 -16
- package/dist/xmlui-standalone.umd.js +262 -290
- package/dist/xmlui.d.ts +36 -61
- package/dist/xmlui.mjs +1 -1
- package/package.json +2 -1
- package/dist/index-BYjaMGrD.mjs +0 -76804
- package/dist/scripts/src/components/BarChart/BarChart.js +0 -49
- package/dist/scripts/src/components/BarChart/BarChartNative.js +0 -176
- package/dist/scripts/src/components/Map/Map.js +0 -75
- package/dist/scripts/src/components/Map/world_countries.json +0 -45307
- package/dist/scripts/src/components/PieChart/PieChart.js +0 -45
- package/dist/scripts/src/components/PieChart/PieChartNative.js +0 -165
- package/dist/scripts/src/components/chart-color-schemes.js +0 -43
- package/dist/scripts/src/components-core/container/Container.js +0 -1186
- package/dist/scripts/src/components-core/container/ContainerComponentDef.js +0 -15
- /package/dist/scripts/src/components-core/{InvalidComponent.js → rendering/InvalidComponent.js} +0 -0
- /package/dist/scripts/src/components-core/{UnknownComponent.js → rendering/UnknownComponent.js} +0 -0
- /package/dist/scripts/src/components-core/{container → rendering}/valueExtractor.js +0 -0
|
@@ -8,7 +8,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
8
8
|
const react_1 = __importDefault(require("react"));
|
|
9
9
|
const ErrorBoundary_module_scss_1 = __importDefault(require("./ErrorBoundary.module.scss"));
|
|
10
10
|
/**
|
|
11
|
-
* This component serves as an error boundary; it catches any errors within
|
|
11
|
+
* This React component serves as an error boundary; it catches any errors within
|
|
12
12
|
* the nested components
|
|
13
13
|
*/
|
|
14
14
|
class ErrorBoundary extends react_1.default.Component {
|
|
@@ -17,13 +17,16 @@ class ErrorBoundary extends react_1.default.Component {
|
|
|
17
17
|
// --- We start with "no error" state
|
|
18
18
|
this.state = {
|
|
19
19
|
hasError: false,
|
|
20
|
-
error: null
|
|
20
|
+
error: null,
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* This method implements the Error Boundaries for the React application.
|
|
25
25
|
* It is invoked if errors occur during the rendering phase of any lifecycle
|
|
26
26
|
* methods or children components.
|
|
27
|
+
*
|
|
28
|
+
* DO NOT DELETE this method! Though it is not referenced directly from the code,
|
|
29
|
+
* it is a required part of the React component lifecycle.
|
|
27
30
|
*/
|
|
28
31
|
static getDerivedStateFromError(error) {
|
|
29
32
|
// --- Update state so the next render will show the fallback UI.
|
|
@@ -47,10 +50,13 @@ class ErrorBoundary extends react_1.default.Component {
|
|
|
47
50
|
componentDidUpdate(prevProps, prevState, snapshot) {
|
|
48
51
|
if (prevProps.node !== this.props.node) {
|
|
49
52
|
this.setState({
|
|
50
|
-
hasError: false
|
|
53
|
+
hasError: false,
|
|
51
54
|
});
|
|
52
55
|
}
|
|
53
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Display an error message if an error occurred during rendering.
|
|
59
|
+
*/
|
|
54
60
|
render() {
|
|
55
61
|
var _a;
|
|
56
62
|
return this.state.hasError ? ((0, jsx_runtime_1.jsxs)("div", { className: ErrorBoundary_module_scss_1.default.errorOverlay, children: [(0, jsx_runtime_1.jsx)("div", { className: ErrorBoundary_module_scss_1.default.title, children: "There was an error!" }), (0, jsx_runtime_1.jsx)("div", { className: ErrorBoundary_module_scss_1.default.errorItem, children: (_a = this.state.error) === null || _a === void 0 ? void 0 : _a.message })] })) : (this.props.children);
|
|
@@ -0,0 +1,331 @@
|
|
|
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.StateContainer = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const immer_1 = __importDefault(require("immer"));
|
|
9
|
+
const lodash_es_1 = require("lodash-es");
|
|
10
|
+
const memoize_one_1 = __importDefault(require("memoize-one"));
|
|
11
|
+
const containers_1 = require("@components-core/abstractions/containers");
|
|
12
|
+
const constants_1 = require("@components-core/constants");
|
|
13
|
+
const collectFnVarDeps_1 = require("@components-core/rendering/collectFnVarDeps");
|
|
14
|
+
const reducer_1 = require("@components-core/rendering/reducer");
|
|
15
|
+
const DebugViewProvider_1 = require("@components-core/DebugViewProvider");
|
|
16
|
+
const ErrorBoundary_1 = require("@components-core/rendering/ErrorBoundary");
|
|
17
|
+
const visitors_1 = require("@components-core/script-runner/visitors");
|
|
18
|
+
const hooks_1 = require("@components-core/utils/hooks");
|
|
19
|
+
const react_1 = require("react");
|
|
20
|
+
const Container_1 = require("./Container");
|
|
21
|
+
const react_2 = require("@remix-run/react");
|
|
22
|
+
const code_behind_collect_1 = require("../../parsers/scripting/code-behind-collect");
|
|
23
|
+
const AppContext_1 = require("@components-core/AppContext");
|
|
24
|
+
const ParameterParser_1 = require("@components-core/script-runner/ParameterParser");
|
|
25
|
+
const eval_tree_sync_1 = require("@components-core/script-runner/eval-tree-sync");
|
|
26
|
+
const extractParam_1 = require("@components-core/utils/extractParam");
|
|
27
|
+
const misc_1 = require("@components-core/utils/misc");
|
|
28
|
+
// A React component that wraps a view container into an error boundary
|
|
29
|
+
// (it's a named function inside the memo, this way it will be visible with that name in the react devtools)
|
|
30
|
+
exports.StateContainer = (0, react_1.memo)((0, react_1.forwardRef)(function StateContainer({ node, resolvedKey, parentState, parentStatePartChanged, parentRegisterComponentApi, parentDispatch, parentRenderContext, layoutContextRef, uidInfoRef, isImplicit, }, ref) {
|
|
31
|
+
const [version, setVersion] = (0, react_1.useState)(0);
|
|
32
|
+
const routingParams = useRoutingParams();
|
|
33
|
+
const memoedVars = (0, react_1.useRef)(new Map());
|
|
34
|
+
const stateFromOutside = (0, hooks_1.useShallowCompareMemoize)((0, react_1.useMemo)(() => extractScopedState(parentState, node.uses), [node.uses, parentState]));
|
|
35
|
+
// --- All state manipulation happens through the container reducer, which is created here.
|
|
36
|
+
// --- This reducer allow collecting state changes for debugging purposes. The `debugView`
|
|
37
|
+
// --- contains the debug configuration; it may enable (or disable) logging.
|
|
38
|
+
const debugView = (0, DebugViewProvider_1.useDebugView)();
|
|
39
|
+
const containerReducer = (0, reducer_1.createContainerReducer)(debugView);
|
|
40
|
+
const [componentState, dispatch] = (0, react_1.useReducer)(containerReducer, constants_1.EMPTY_OBJECT);
|
|
41
|
+
// --- The exposed APIs of components are also the part of the state.
|
|
42
|
+
const [componentApis, setComponentApis] = (0, react_1.useState)(constants_1.EMPTY_OBJECT);
|
|
43
|
+
const componentStateWithApis = (0, hooks_1.useShallowCompareMemoize)((0, react_1.useMemo)(() => {
|
|
44
|
+
const ret = Object.assign({}, componentState);
|
|
45
|
+
for (const stateKey of Object.getOwnPropertySymbols(componentState)) {
|
|
46
|
+
const value = componentState[stateKey];
|
|
47
|
+
if (stateKey.description) {
|
|
48
|
+
ret[stateKey.description] = value;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (Reflect.ownKeys(componentApis).length === 0) {
|
|
52
|
+
//skip containers with no registered apis
|
|
53
|
+
return ret;
|
|
54
|
+
}
|
|
55
|
+
for (const componentApiKey of Object.getOwnPropertySymbols(componentApis)) {
|
|
56
|
+
const value = componentApis[componentApiKey];
|
|
57
|
+
if (componentApiKey.description) {
|
|
58
|
+
const key = componentApiKey.description;
|
|
59
|
+
ret[key] = Object.assign(Object.assign({}, (ret[key] || {})), value);
|
|
60
|
+
}
|
|
61
|
+
ret[componentApiKey] = Object.assign(Object.assign({}, ret[componentApiKey]), value);
|
|
62
|
+
}
|
|
63
|
+
return ret;
|
|
64
|
+
}, [componentState, componentApis]));
|
|
65
|
+
const localVarsStateContext = useCombinedState(stateFromOutside, componentStateWithApis, node.contextVars);
|
|
66
|
+
const parsedScriptPart = node.scriptCollected;
|
|
67
|
+
if ((parsedScriptPart === null || parsedScriptPart === void 0 ? void 0 : parsedScriptPart.moduleErrors) && !(0, lodash_es_1.isEmpty)(parsedScriptPart.moduleErrors)) {
|
|
68
|
+
throw new CodeBehindParseError(parsedScriptPart.moduleErrors);
|
|
69
|
+
}
|
|
70
|
+
if (node.scriptError && !(0, lodash_es_1.isEmpty)(node.scriptError)) {
|
|
71
|
+
throw new CodeBehindParseError(node.scriptError);
|
|
72
|
+
}
|
|
73
|
+
const referenceTrackedApi = (0, hooks_1.useReferenceTrackedApi)(componentState);
|
|
74
|
+
const varDefinitions = (0, hooks_1.useShallowCompareMemoize)(Object.assign(Object.assign(Object.assign(Object.assign({}, parsedScriptPart === null || parsedScriptPart === void 0 ? void 0 : parsedScriptPart.functions), node.functions), parsedScriptPart === null || parsedScriptPart === void 0 ? void 0 : parsedScriptPart.vars), node.vars));
|
|
75
|
+
//first: collection function (arrowExpressions) dependencies
|
|
76
|
+
// -> do it until there's no function dep, only var deps
|
|
77
|
+
const functionDeps = (0, react_1.useMemo)(() => {
|
|
78
|
+
const fnDeps = {};
|
|
79
|
+
Object.entries(varDefinitions).forEach(([key, value]) => {
|
|
80
|
+
if (isParsedValue(value) && value.tree.type === "ArrowE") {
|
|
81
|
+
fnDeps[key] = (0, visitors_1.collectVariableDependencies)(value.tree, referenceTrackedApi);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return (0, collectFnVarDeps_1.collectFnVarDeps)(fnDeps);
|
|
85
|
+
}, [referenceTrackedApi, varDefinitions]);
|
|
86
|
+
// then resolve vars and replace function deps with the collected deps for that function
|
|
87
|
+
//first resolve round (we do 2, to make sure that the order of the definitions doesn't cause problems)
|
|
88
|
+
// e.g. 'testFn' uses $props, but $props is not resolved yet
|
|
89
|
+
const preResolvedLocalVars = useVars(varDefinitions, functionDeps, localVarsStateContext, (0, react_1.useRef)(new Map()));
|
|
90
|
+
const localVarsStateContextWithPreResolvedLocalVars = (0, hooks_1.useShallowCompareMemoize)(Object.assign(Object.assign({}, preResolvedLocalVars), localVarsStateContext));
|
|
91
|
+
const resolvedLocalVars = useVars(varDefinitions, functionDeps, localVarsStateContextWithPreResolvedLocalVars, memoedVars);
|
|
92
|
+
const mergedWithVars = useMergedState(resolvedLocalVars, componentStateWithApis);
|
|
93
|
+
const combinedState = useCombinedState(stateFromOutside, node.contextVars, mergedWithVars, routingParams);
|
|
94
|
+
const registerComponentApi = (0, react_1.useCallback)((uid, api) => {
|
|
95
|
+
setComponentApis((0, immer_1.default)((draft) => {
|
|
96
|
+
// console.log("-----BUST----setComponentApis");
|
|
97
|
+
if (!draft[uid]) {
|
|
98
|
+
draft[uid] = {};
|
|
99
|
+
}
|
|
100
|
+
Object.entries(api).forEach(([key, value]) => {
|
|
101
|
+
if (draft[uid][key] !== value) {
|
|
102
|
+
// console.log(`-----BUST------new api for ${uid}`, draft[uid][key], value)
|
|
103
|
+
draft[uid][key] = value;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}));
|
|
107
|
+
}, []);
|
|
108
|
+
const componentStateRef = (0, react_1.useRef)(componentStateWithApis);
|
|
109
|
+
const statePartChanged = (0, react_1.useCallback)((pathArray, newValue, target, action) => {
|
|
110
|
+
const key = pathArray[0];
|
|
111
|
+
if (key in componentStateRef.current || key in resolvedLocalVars) {
|
|
112
|
+
// --- Sign that a state field (or a part of it) has changed
|
|
113
|
+
dispatch({
|
|
114
|
+
type: containers_1.ContainerActionKind.STATE_PART_CHANGED,
|
|
115
|
+
payload: {
|
|
116
|
+
path: pathArray,
|
|
117
|
+
value: newValue,
|
|
118
|
+
target,
|
|
119
|
+
actionType: action,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
if (!node.uses || node.uses.includes(key)) {
|
|
125
|
+
parentStatePartChanged(pathArray, newValue, target, action);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}, [resolvedLocalVars, node.uses, parentStatePartChanged]);
|
|
129
|
+
return ((0, jsx_runtime_1.jsx)(ErrorBoundary_1.ErrorBoundary, { node: node, location: "container", children: (0, jsx_runtime_1.jsx)(Container_1.Container, { resolvedKey: resolvedKey, node: node, componentState: combinedState, dispatch: dispatch, parentDispatch: parentDispatch, setVersion: setVersion, version: version, statePartChanged: statePartChanged, registerComponentApi: registerComponentApi, parentRegisterComponentApi: parentRegisterComponentApi, layoutContextRef: layoutContextRef, parentRenderContext: parentRenderContext, memoedVarsRef: memoedVars, isImplicit: isImplicit, ref: ref, uidInfoRef: uidInfoRef }) }));
|
|
130
|
+
}));
|
|
131
|
+
const useRoutingParams = () => {
|
|
132
|
+
const [queryParams] = (0, react_2.useSearchParams)();
|
|
133
|
+
const routeParams = (0, react_2.useParams)();
|
|
134
|
+
const queryParamsMap = (0, react_1.useMemo)(() => {
|
|
135
|
+
const result = {};
|
|
136
|
+
for (const [key, value] of Array.from(queryParams.entries())) {
|
|
137
|
+
result[key] = value;
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
}, [queryParams]);
|
|
141
|
+
return (0, react_1.useMemo)(() => {
|
|
142
|
+
return {
|
|
143
|
+
$routeParams: routeParams,
|
|
144
|
+
$queryParams: queryParamsMap,
|
|
145
|
+
};
|
|
146
|
+
}, [queryParamsMap, routeParams]);
|
|
147
|
+
};
|
|
148
|
+
// Extracts the `state` property values defined in a component definition's `uses` property. It uses the specified
|
|
149
|
+
// `appContext` when resolving the state values.
|
|
150
|
+
function extractScopedState(parentState, uses) {
|
|
151
|
+
if (!uses) {
|
|
152
|
+
return parentState;
|
|
153
|
+
}
|
|
154
|
+
if (uses.length === 0) {
|
|
155
|
+
return constants_1.EMPTY_OBJECT;
|
|
156
|
+
}
|
|
157
|
+
return (0, lodash_es_1.pick)(parentState, uses);
|
|
158
|
+
}
|
|
159
|
+
// This hook combines state properties in a list of states so that a particular state property in a higher
|
|
160
|
+
// argument index overrides the same-named state property in a lower argument index.
|
|
161
|
+
function useCombinedState(...states) {
|
|
162
|
+
const combined = (0, react_1.useMemo)(() => {
|
|
163
|
+
let ret = {};
|
|
164
|
+
states.forEach((state = constants_1.EMPTY_OBJECT) => {
|
|
165
|
+
// console.log("st", state);
|
|
166
|
+
if (state !== constants_1.EMPTY_OBJECT) {
|
|
167
|
+
ret = Object.assign(Object.assign({}, ret), state);
|
|
168
|
+
}
|
|
169
|
+
// console.log("ret", ret);
|
|
170
|
+
});
|
|
171
|
+
return ret;
|
|
172
|
+
}, [states]);
|
|
173
|
+
return (0, hooks_1.useShallowCompareMemoize)(combined);
|
|
174
|
+
}
|
|
175
|
+
// This hook combines state properties in a list of states so that a particular state property in a higher
|
|
176
|
+
// argument index merges into the same-named state property in a lower argument index.
|
|
177
|
+
// This hook combines state properties in a list of states so that a particular state property in a higher
|
|
178
|
+
// argument index merges into the same-named state property in a lower argument index.
|
|
179
|
+
function useMergedState(localVars, componentState) {
|
|
180
|
+
const merged = (0, react_1.useMemo)(() => {
|
|
181
|
+
const ret = Object.assign({}, localVars);
|
|
182
|
+
Reflect.ownKeys(componentState).forEach((key) => {
|
|
183
|
+
const value = componentState[key];
|
|
184
|
+
if (ret[key] === undefined) {
|
|
185
|
+
ret[key] = value;
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
if ((0, lodash_es_1.isPlainObject)(ret[key]) && (0, lodash_es_1.isPlainObject)(value)) {
|
|
189
|
+
ret[key] = (0, lodash_es_1.merge)((0, lodash_es_1.cloneDeep)(ret[key]), value);
|
|
190
|
+
}
|
|
191
|
+
else if (Array.isArray(ret[key]) && Array.isArray(value)) {
|
|
192
|
+
ret[key] = Object.assign([], ret[key], value);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
ret[key] = value;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
return ret;
|
|
200
|
+
}, [localVars, componentState]);
|
|
201
|
+
return (0, hooks_1.useShallowCompareMemoize)(merged);
|
|
202
|
+
}
|
|
203
|
+
// This hook resolves variables to their current value (using binding expression evaluation)
|
|
204
|
+
function useVars(vars = constants_1.EMPTY_OBJECT, fnDeps = constants_1.EMPTY_OBJECT, componentState, memoedVars) {
|
|
205
|
+
const appContext = (0, AppContext_1.useAppContext)();
|
|
206
|
+
const referenceTrackedApi = (0, hooks_1.useReferenceTrackedApi)(componentState);
|
|
207
|
+
const resolvedVars = (0, react_1.useMemo)(() => {
|
|
208
|
+
const ret = {};
|
|
209
|
+
Object.entries(vars).forEach(([key, value]) => {
|
|
210
|
+
if (key === "$props") {
|
|
211
|
+
// --- We already resolved props in a compound component
|
|
212
|
+
ret[key] = value;
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
if (!isParsedValue(value) && typeof value !== "string") {
|
|
216
|
+
ret[key] = value;
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
// --- Resolve each variable's value, without going into the details of arrays and objects
|
|
220
|
+
if (!memoedVars.current.has(value)) {
|
|
221
|
+
memoedVars.current.set(value, {
|
|
222
|
+
getDependencies: (0, memoize_one_1.default)((value, referenceTrackedApi) => {
|
|
223
|
+
if (isParsedValue(value)) {
|
|
224
|
+
return (0, visitors_1.collectVariableDependencies)(value.tree, referenceTrackedApi);
|
|
225
|
+
}
|
|
226
|
+
// console.log(`GETTING DEPENDENCY FOR ${value} with:`, referenceTrackedApi);
|
|
227
|
+
const params = (0, ParameterParser_1.parseParameterString)(value);
|
|
228
|
+
let ret = new Set();
|
|
229
|
+
params.forEach((param) => {
|
|
230
|
+
if (param.type === "expression") {
|
|
231
|
+
ret = new Set([
|
|
232
|
+
...ret,
|
|
233
|
+
...(0, visitors_1.collectVariableDependencies)(param.value, referenceTrackedApi),
|
|
234
|
+
]);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
return Array.from(ret);
|
|
238
|
+
}),
|
|
239
|
+
obtainValue: (0, memoize_one_1.default)((value, state, appContext, strict, deps, appContextDeps) => {
|
|
240
|
+
// console.log(
|
|
241
|
+
// "VARS, BUST, obtain value called with",
|
|
242
|
+
// value,
|
|
243
|
+
// { state, appContext },
|
|
244
|
+
// {
|
|
245
|
+
// deps,
|
|
246
|
+
// appContextDeps,
|
|
247
|
+
// }
|
|
248
|
+
// );
|
|
249
|
+
try {
|
|
250
|
+
return isParsedValue(value)
|
|
251
|
+
? (0, eval_tree_sync_1.evalBinding)(value.tree, {
|
|
252
|
+
localContext: state,
|
|
253
|
+
appContext,
|
|
254
|
+
options: {
|
|
255
|
+
defaultToOptionalMemberAccess: true,
|
|
256
|
+
},
|
|
257
|
+
})
|
|
258
|
+
: (0, extractParam_1.extractParam)(state, value, appContext, strict);
|
|
259
|
+
}
|
|
260
|
+
catch (e) {
|
|
261
|
+
console.log(state);
|
|
262
|
+
throw new ParseVarError(value, e);
|
|
263
|
+
}
|
|
264
|
+
}, ([_newExpression, _newState, _newAppContext, _newStrict, newDeps, newAppContextDeps,], [_lastExpression, _lastState, _lastAppContext, _lastStrict, lastDeps, lastAppContextDeps,]) => {
|
|
265
|
+
return ((0, misc_1.shallowCompare)(newDeps, lastDeps) &&
|
|
266
|
+
(0, misc_1.shallowCompare)(newAppContextDeps, lastAppContextDeps));
|
|
267
|
+
}),
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
const stateContext = Object.assign(Object.assign({}, ret), componentState);
|
|
271
|
+
let dependencies = [];
|
|
272
|
+
if (fnDeps[key]) {
|
|
273
|
+
dependencies = fnDeps[key];
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
memoedVars.current
|
|
277
|
+
.get(value)
|
|
278
|
+
.getDependencies(value, referenceTrackedApi)
|
|
279
|
+
.forEach((dep) => {
|
|
280
|
+
if (fnDeps[dep]) {
|
|
281
|
+
dependencies.push(...fnDeps[dep]);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
dependencies.push(dep);
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
dependencies = [...new Set(dependencies)];
|
|
288
|
+
}
|
|
289
|
+
const stateDepValues = (0, misc_1.pickFromObject)(stateContext, dependencies);
|
|
290
|
+
const appContextDepValues = (0, misc_1.pickFromObject)(appContext, dependencies);
|
|
291
|
+
// console.log("VARS, obtain value called with", stateDepValues, appContextDepValues);
|
|
292
|
+
ret[key] = memoedVars.current
|
|
293
|
+
.get(value)
|
|
294
|
+
.obtainValue(value, stateContext, appContext, true, stateDepValues, appContextDepValues);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
return ret;
|
|
299
|
+
}, [appContext, componentState, fnDeps, memoedVars, referenceTrackedApi, vars]);
|
|
300
|
+
return (0, hooks_1.useShallowCompareMemoize)(resolvedVars);
|
|
301
|
+
}
|
|
302
|
+
class CodeBehindParseError extends Error {
|
|
303
|
+
constructor(errors) {
|
|
304
|
+
const mainErrors = errors["Main"] || [];
|
|
305
|
+
const messages = mainErrors.map((errorMessage) => {
|
|
306
|
+
let ret = `${errorMessage.code} : ${errorMessage.text}`;
|
|
307
|
+
const posInfo = [];
|
|
308
|
+
if (errorMessage.line !== undefined) {
|
|
309
|
+
posInfo.push(`line:${errorMessage.line}`);
|
|
310
|
+
}
|
|
311
|
+
if (errorMessage.column !== undefined) {
|
|
312
|
+
posInfo.push(`column:${errorMessage.column}`);
|
|
313
|
+
}
|
|
314
|
+
if (posInfo.length) {
|
|
315
|
+
ret = `${ret} (${posInfo.join(", ")})`;
|
|
316
|
+
}
|
|
317
|
+
return ret;
|
|
318
|
+
});
|
|
319
|
+
super(messages.join("\n"));
|
|
320
|
+
Object.setPrototypeOf(this, CodeBehindParseError.prototype);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
class ParseVarError extends Error {
|
|
324
|
+
constructor(varName, originalError) {
|
|
325
|
+
super(`Error on var: ${varName} - ${(originalError === null || originalError === void 0 ? void 0 : originalError.message) || "unknown"}`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
//true if it's coming from a code behind or a script tag
|
|
329
|
+
function isParsedValue(value) {
|
|
330
|
+
return value && typeof value === "object" && value[code_behind_collect_1.PARSED_MARK_PROP];
|
|
331
|
+
}
|
|
@@ -1,25 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildProxy = buildProxy;
|
|
3
4
|
/**
|
|
4
|
-
* Use this function to build a JavaScript proxy for localContext objects. The
|
|
5
|
-
*
|
|
5
|
+
* Use this function to build a JavaScript proxy for localContext objects. The
|
|
6
|
+
* responsibility of the proxy is to collect the changes within the localContext
|
|
7
|
+
* so that we can refresh the UI according to them.
|
|
6
8
|
*/
|
|
7
9
|
function buildProxy(proxyTarget, callback, tree = []) {
|
|
8
|
-
// --- We identify a particular (deep) localContext property by its full path;
|
|
10
|
+
// --- We identify a particular (deep) localContext property by its full path;
|
|
11
|
+
// --- this function creates the path
|
|
9
12
|
const getPath = (prop) => tree.concat(prop).join(".");
|
|
10
13
|
const proxiedValues = new WeakMap();
|
|
11
14
|
// --- Create the proxy object for `proxyTarget`
|
|
12
15
|
return new Proxy(proxyTarget, {
|
|
13
16
|
get: function (target, prop, receiver) {
|
|
14
17
|
const value = Reflect.get(target, prop, receiver);
|
|
15
|
-
// --- Create proxies only for writable objects and arrays, except arrow
|
|
18
|
+
// --- Create proxies only for writable objects and arrays, except arrow
|
|
19
|
+
// --- function expressions.
|
|
16
20
|
if (value &&
|
|
17
21
|
!value._ARROW_EXPR_ &&
|
|
18
22
|
!Object.isFrozen(value) &&
|
|
19
23
|
typeof value === "object" &&
|
|
20
24
|
["Array", "Object"].includes(value.constructor.name)) {
|
|
21
|
-
//
|
|
22
|
-
//
|
|
25
|
+
// --- Just to make sure that accessing the proxied objects' field gets
|
|
26
|
+
// --- the same reference every time. e.g. this wouldn't be true otherwise:
|
|
27
|
+
// --- proxiedObject['field'] === proxiedObject['field']
|
|
23
28
|
if (!proxiedValues.has(value)) {
|
|
24
29
|
proxiedValues.set(value, buildProxy(value, callback, tree.concat(prop)));
|
|
25
30
|
}
|
|
@@ -51,4 +56,3 @@ function buildProxy(proxyTarget, callback, tree = []) {
|
|
|
51
56
|
},
|
|
52
57
|
});
|
|
53
58
|
}
|
|
54
|
-
exports.default = buildProxy;
|
|
@@ -5,7 +5,7 @@ exports.collectFnVarDeps = collectFnVarDeps;
|
|
|
5
5
|
* This function collects all the dependencies of a function in a flat list
|
|
6
6
|
* (no circular deps).
|
|
7
7
|
* @param fnDeps The dependencies of the functions. Each key is a function name
|
|
8
|
-
* and the value is an array of the
|
|
8
|
+
* and the value is an array of variables the function depends on.
|
|
9
9
|
* @returns The flat dependencies of the functions.
|
|
10
10
|
*
|
|
11
11
|
* Example:
|
|
@@ -33,7 +33,7 @@ function collectFnVarDeps(fnDeps = {}) {
|
|
|
33
33
|
const ret = [];
|
|
34
34
|
fnDeps[depKey].forEach((key) => {
|
|
35
35
|
if (visitedPath.has(key)) {
|
|
36
|
-
//
|
|
36
|
+
// --- We already walked here, avoid infinite loops for circular deps
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
39
|
visitedPath.add(key);
|
|
@@ -125,6 +125,9 @@ function createContainerReducer(debugView) {
|
|
|
125
125
|
prevState,
|
|
126
126
|
nextState,
|
|
127
127
|
};
|
|
128
|
+
// TODO: Logging to the console is a temporary solution. We should use a proper
|
|
129
|
+
// logging mechanism. Nonetheless, this works only with state transition logging
|
|
130
|
+
// enabled (which is disabled by default).
|
|
128
131
|
console.log("Transition", loggedTransition);
|
|
129
132
|
if (debugView.stateTransitions) {
|
|
130
133
|
if (debugView.stateTransitions.length >= MAX_STATE_TRANSITION_LENGTH) {
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderChild = renderChild;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ComponentWrapper_1 = require("./ComponentWrapper");
|
|
6
|
+
const extractParam_1 = require("@components-core/utils/extractParam");
|
|
7
|
+
/**
|
|
8
|
+
* This function is the jolly-joker of the rendering process. It renders a child component
|
|
9
|
+
* based on the specified context, which contains the component's definition, the current state,
|
|
10
|
+
* and other necessary information.
|
|
11
|
+
*
|
|
12
|
+
* The function checks a few special cases:
|
|
13
|
+
* - <Slot> with a single text node child: it renders the text in the context of the parent component.
|
|
14
|
+
* - CDATA text nodes: it renders the text as is without parsing it.
|
|
15
|
+
* - TextNode: it extracts the text from the node and renders it.
|
|
16
|
+
*
|
|
17
|
+
* In other cases, it extracts the component's ID and renders the component as a <ComponentNode>.
|
|
18
|
+
*
|
|
19
|
+
* As this function passes itself as a renderChild function to the <ComponentNode>, it can render
|
|
20
|
+
* nested components recursively.
|
|
21
|
+
*/
|
|
22
|
+
function renderChild({ node, state, dispatch, appContext, lookupAction, lookupSyncCallback, registerComponentApi, renderChild, statePartChanged, layoutContext, parentRenderContext, memoedVarsRef, cleanup, uidInfoRef, }) {
|
|
23
|
+
var _a, _b, _c;
|
|
24
|
+
// --- Render only visible components
|
|
25
|
+
if (!(0, extractParam_1.shouldKeep)(node.when, state, appContext)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
// --- We do not parse text nodes specified with CDATA to avoid whitespace collapsing
|
|
29
|
+
const nodeValue = (_a = node.props) === null || _a === void 0 ? void 0 : _a.value;
|
|
30
|
+
if (node.type === "TextNodeCData") {
|
|
31
|
+
return nodeValue !== null && nodeValue !== void 0 ? nodeValue : "";
|
|
32
|
+
}
|
|
33
|
+
// --- A TextNode value may contain nexted expressions, so we extract it.
|
|
34
|
+
if (node.type === "TextNode") {
|
|
35
|
+
return (0, extractParam_1.extractParam)(state, nodeValue, appContext, true);
|
|
36
|
+
}
|
|
37
|
+
// --- Rendering a Slot requires some preparations, as TextNode and
|
|
38
|
+
// --- TextNodeCData are virtual nodes. Also, slots may have default templates
|
|
39
|
+
// --- to render when no slot children are specified. The following section
|
|
40
|
+
// --- handles these cases.
|
|
41
|
+
if (node.type === "Slot") {
|
|
42
|
+
// --- Check for special Slot cases
|
|
43
|
+
let slotChildren;
|
|
44
|
+
const templateName = (_b = node.props) === null || _b === void 0 ? void 0 : _b.name;
|
|
45
|
+
// console.log("templateName", templateName);
|
|
46
|
+
if (templateName) {
|
|
47
|
+
// --- Let's check the validity of the slot name
|
|
48
|
+
if (!templateName.endsWith("Template")) {
|
|
49
|
+
throw new Error(`Slot name '${templateName}' is not valid. ` +
|
|
50
|
+
"A named slot should use a name ending with 'Template'.");
|
|
51
|
+
}
|
|
52
|
+
// --- Named slot: use a template property from the parent component
|
|
53
|
+
slotChildren = (_c = parentRenderContext === null || parentRenderContext === void 0 ? void 0 : parentRenderContext.props) === null || _c === void 0 ? void 0 : _c[templateName];
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// --- Children slot: use the children of the parent component
|
|
57
|
+
slotChildren = parentRenderContext === null || parentRenderContext === void 0 ? void 0 : parentRenderContext.children;
|
|
58
|
+
}
|
|
59
|
+
if (!slotChildren) {
|
|
60
|
+
// --- No children to render, let's try the default slot template (if there is any)
|
|
61
|
+
slotChildren = node.children;
|
|
62
|
+
}
|
|
63
|
+
if (slotChildren) {
|
|
64
|
+
const toRender = Array.isArray(slotChildren) ? slotChildren : [slotChildren];
|
|
65
|
+
// --- Check for the virtual nodes. At this point, parentRendererContext is
|
|
66
|
+
// --- undefined when the parent does not provide slot children. In this case,
|
|
67
|
+
// --- the ComponentBed component will render the default slot template.
|
|
68
|
+
if (toRender.length === 1 && parentRenderContext) {
|
|
69
|
+
if (toRender[0].type === "TextNodeCData" || toRender[0].type === "TextNode") {
|
|
70
|
+
// --- Preserve the text and render it in the parent context
|
|
71
|
+
return parentRenderContext.renderChild(toRender);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// --- In other cases, we extract the component ID, and then render the component.
|
|
77
|
+
// --- A component's ID is generally a string with identifier syntax. However, some
|
|
78
|
+
// --- internal components have IDs with expressions, so we evaluate them.
|
|
79
|
+
const key = (0, extractParam_1.extractParam)(state, node.uid, appContext, true);
|
|
80
|
+
return ((0, jsx_runtime_1.jsx)(ComponentWrapper_1.ComponentWrapper, { resolvedKey: key, node: node, cleanup: cleanup, statePartChanged: statePartChanged, memoedVarsRef: memoedVarsRef, state: state, dispatch: dispatch, appContext: appContext, lookupAction: lookupAction, lookupSyncCallback: lookupSyncCallback, registerComponentApi: registerComponentApi, renderChild: renderChild, layoutContext: layoutContext, parentRenderContext: parentRenderContext, uidInfoRef: uidInfoRef }, key));
|
|
81
|
+
}
|
|
@@ -32,9 +32,6 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
36
|
exports.toCssVar = exports.useColors = exports.getColor = exports.Splitter = exports.Button = exports.Stack = exports.Icon = exports.ErrorBoundary = exports.AppRoot = exports.useTheme = exports.startApp = exports.parseScssVar = exports.d = exports.createMetadata = exports.createComponentRenderer = exports.StandaloneApp = void 0;
|
|
40
37
|
const StandaloneApp_1 = __importStar(require("@components-core/StandaloneApp"));
|
|
@@ -43,13 +40,13 @@ Object.defineProperty(exports, "startApp", { enumerable: true, get: function ()
|
|
|
43
40
|
const ComponentDefs_1 = require("@abstractions/ComponentDefs");
|
|
44
41
|
Object.defineProperty(exports, "createMetadata", { enumerable: true, get: function () { return ComponentDefs_1.createMetadata; } });
|
|
45
42
|
Object.defineProperty(exports, "d", { enumerable: true, get: function () { return ComponentDefs_1.d; } });
|
|
46
|
-
const AppRoot_1 =
|
|
47
|
-
exports
|
|
43
|
+
const AppRoot_1 = require("@components-core/rendering/AppRoot");
|
|
44
|
+
Object.defineProperty(exports, "AppRoot", { enumerable: true, get: function () { return AppRoot_1.AppRoot; } });
|
|
48
45
|
const renderers_1 = require("@components-core/renderers");
|
|
49
46
|
Object.defineProperty(exports, "createComponentRenderer", { enumerable: true, get: function () { return renderers_1.createComponentRenderer; } });
|
|
50
47
|
const IconNative_1 = require("@components/Icon/IconNative");
|
|
51
48
|
Object.defineProperty(exports, "Icon", { enumerable: true, get: function () { return IconNative_1.Icon; } });
|
|
52
|
-
const ErrorBoundary_1 = require("@components-core/ErrorBoundary");
|
|
49
|
+
const ErrorBoundary_1 = require("@components-core/rendering/ErrorBoundary");
|
|
53
50
|
Object.defineProperty(exports, "ErrorBoundary", { enumerable: true, get: function () { return ErrorBoundary_1.ErrorBoundary; } });
|
|
54
51
|
const StackNative_1 = require("@components/Stack/StackNative");
|
|
55
52
|
Object.defineProperty(exports, "Stack", { enumerable: true, get: function () { return StackNative_1.Stack; } });
|