@xuda.io/xuda-worker-bundle 1.3.2635 → 1.3.2637
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/index.js +150 -88
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -64,6 +64,51 @@ func.runtime.ui = {};
|
|
|
64
64
|
func.runtime.widgets = {};
|
|
65
65
|
glb.IS_STUDIO = null;
|
|
66
66
|
|
|
67
|
+
// Lodash replacement utilities
|
|
68
|
+
var xu_isEmpty = function (val) {
|
|
69
|
+
if (val == null) return true;
|
|
70
|
+
if (typeof val === 'boolean' || typeof val === 'number') return !val;
|
|
71
|
+
if (typeof val === 'string' || Array.isArray(val)) return val.length === 0;
|
|
72
|
+
if (val instanceof Map || val instanceof Set) return val.size === 0;
|
|
73
|
+
return Object.keys(val).length === 0;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
var xu_isEqual = function (a, b) {
|
|
77
|
+
if (a === b) return true;
|
|
78
|
+
if (a == null || b == null) return a === b;
|
|
79
|
+
if (typeof a !== typeof b) return false;
|
|
80
|
+
if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();
|
|
81
|
+
if (typeof a !== 'object') return false;
|
|
82
|
+
var keysA = Object.keys(a);
|
|
83
|
+
var keysB = Object.keys(b);
|
|
84
|
+
if (keysA.length !== keysB.length) return false;
|
|
85
|
+
for (var i = 0; i < keysA.length; i++) {
|
|
86
|
+
if (!Object.prototype.hasOwnProperty.call(b, keysA[i]) || !xu_isEqual(a[keysA[i]], b[keysA[i]])) return false;
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
var xu_get = function (obj, path, defaultVal) {
|
|
92
|
+
var keys = typeof path === 'string' ? path.split('.') : path;
|
|
93
|
+
var result = obj;
|
|
94
|
+
for (var i = 0; i < keys.length; i++) {
|
|
95
|
+
if (result == null) return defaultVal;
|
|
96
|
+
result = result[keys[i]];
|
|
97
|
+
}
|
|
98
|
+
return result === undefined ? defaultVal : result;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
var xu_set = function (obj, path, value) {
|
|
102
|
+
var keys = typeof path === 'string' ? path.split('.') : path;
|
|
103
|
+
var current = obj;
|
|
104
|
+
for (var i = 0; i < keys.length - 1; i++) {
|
|
105
|
+
if (current[keys[i]] == null) current[keys[i]] = {};
|
|
106
|
+
current = current[keys[i]];
|
|
107
|
+
}
|
|
108
|
+
current[keys[keys.length - 1]] = value;
|
|
109
|
+
return obj;
|
|
110
|
+
};
|
|
111
|
+
|
|
67
112
|
var PROJECT_OBJ = {};
|
|
68
113
|
|
|
69
114
|
var APP_OBJ = {};
|
|
@@ -765,7 +810,7 @@ func.runtime.bind.get_field_type = function (field_prop) {
|
|
|
765
810
|
};
|
|
766
811
|
func.runtime.bind.toggle_array_value = function (arr_value_before_cast, value_from_getter) {
|
|
767
812
|
if (arr_value_before_cast.includes(value_from_getter)) {
|
|
768
|
-
return arr_value_before_cast.filter((item) => !
|
|
813
|
+
return arr_value_before_cast.filter((item) => !xu_isEqual(item, value_from_getter));
|
|
769
814
|
}
|
|
770
815
|
arr_value_before_cast.push(value_from_getter);
|
|
771
816
|
return arr_value_before_cast;
|
|
@@ -813,7 +858,7 @@ func.runtime.bind.update_reference_source_array = async function (options) {
|
|
|
813
858
|
|
|
814
859
|
const arr_idx = Number(options.iterate_info._key);
|
|
815
860
|
const dataset_arr = await func.datasource.get_value(options.SESSION_ID, reference_source_obj.fieldIdP, options.dsSessionP, reference_source_obj.currentRecordId);
|
|
816
|
-
let new_arr =
|
|
861
|
+
let new_arr = klona.klona(dataset_arr.ret.value);
|
|
817
862
|
|
|
818
863
|
if (field_type === 'object' && options.val_is_reference_field) {
|
|
819
864
|
let obj_item = new_arr[arr_idx];
|
|
@@ -830,10 +875,10 @@ func.runtime.bind.update_reference_source_array = async function (options) {
|
|
|
830
875
|
};
|
|
831
876
|
func.runtime.resources.load_cdn = async function (SESSION_ID, resource) {
|
|
832
877
|
let normalized_resource = resource;
|
|
833
|
-
if (!
|
|
878
|
+
if (!(typeof normalized_resource === 'object' && normalized_resource !== null) && typeof normalized_resource === 'string') {
|
|
834
879
|
normalized_resource = { src: normalized_resource, type: 'js' };
|
|
835
880
|
}
|
|
836
|
-
if (!
|
|
881
|
+
if (!(typeof normalized_resource === 'object' && normalized_resource !== null)) {
|
|
837
882
|
throw new Error('cdn resource in wrong format');
|
|
838
883
|
}
|
|
839
884
|
|
|
@@ -879,7 +924,7 @@ func.runtime.resources.load_plugin_runtime_css = async function (SESSION_ID, plu
|
|
|
879
924
|
return true;
|
|
880
925
|
};
|
|
881
926
|
func.runtime.resources.resolve_plugin_properties = async function (SESSION_ID, dsSessionP, attributes, properties) {
|
|
882
|
-
let resolved_properties =
|
|
927
|
+
let resolved_properties = klona.klona(properties);
|
|
883
928
|
for await (let [prop_name, prop_val] of Object.entries(resolved_properties || {})) {
|
|
884
929
|
prop_val.value = attributes?.[prop_name];
|
|
885
930
|
if (attributes?.[`xu-exp:${prop_name}`]) {
|
|
@@ -905,7 +950,7 @@ func.runtime.resources.run_ui_plugin = async function (SESSION_ID, paramsP, $elm
|
|
|
905
950
|
const plugin_runtime_src = await func.runtime.resources.get_plugin_module_url(SESSION_ID, plugin_name, plugin, 'runtime.mjs');
|
|
906
951
|
const plugin_runtime_resources = await import(plugin_runtime_src);
|
|
907
952
|
|
|
908
|
-
if (plugin_runtime_resources.cdn &&
|
|
953
|
+
if (plugin_runtime_resources.cdn && Array.isArray(plugin_runtime_resources.cdn)) {
|
|
909
954
|
for await (const resource of plugin_runtime_resources.cdn) {
|
|
910
955
|
await func.runtime.resources.load_cdn(SESSION_ID, resource);
|
|
911
956
|
}
|
|
@@ -1037,12 +1082,12 @@ func.runtime.widgets.build_params = function (context, $containerP, plugin_setup
|
|
|
1037
1082
|
};
|
|
1038
1083
|
};
|
|
1039
1084
|
func.common.find_item_by_key = function (arr, key, val) {
|
|
1040
|
-
return
|
|
1085
|
+
return arr.find(function (e) {
|
|
1041
1086
|
return e.data[key] === val;
|
|
1042
1087
|
});
|
|
1043
1088
|
};
|
|
1044
1089
|
func.common.find_item_by_key_root = function (arr, key, val) {
|
|
1045
|
-
return
|
|
1090
|
+
return arr.find(function (e) {
|
|
1046
1091
|
return e[key] === val;
|
|
1047
1092
|
});
|
|
1048
1093
|
};
|
|
@@ -1302,7 +1347,7 @@ func.common.db = async function (SESSION_ID, serviceP, dataP, opt = {}, dsSessio
|
|
|
1302
1347
|
}
|
|
1303
1348
|
|
|
1304
1349
|
await db.get(row_id);
|
|
1305
|
-
let _data =
|
|
1350
|
+
let _data = klona.klona(dataP);
|
|
1306
1351
|
_data.ids = [row_id];
|
|
1307
1352
|
return await func.db.pouch['dbs_delete'](SESSION_ID, _data);
|
|
1308
1353
|
} catch (err) {
|
|
@@ -1391,7 +1436,7 @@ func.common.db = async function (SESSION_ID, serviceP, dataP, opt = {}, dsSessio
|
|
|
1391
1436
|
|
|
1392
1437
|
const get_white_spaced_data = function (data) {
|
|
1393
1438
|
var e = {};
|
|
1394
|
-
|
|
1439
|
+
for (const [key, val] of Object.entries(data)) {
|
|
1395
1440
|
if (!val) {
|
|
1396
1441
|
if (typeof val === 'boolean') {
|
|
1397
1442
|
e[key] = 'false';
|
|
@@ -1405,7 +1450,7 @@ func.common.db = async function (SESSION_ID, serviceP, dataP, opt = {}, dsSessio
|
|
|
1405
1450
|
e[key] = val;
|
|
1406
1451
|
}
|
|
1407
1452
|
}
|
|
1408
|
-
}
|
|
1453
|
+
}
|
|
1409
1454
|
|
|
1410
1455
|
if (data.fields && !data.fields.length) {
|
|
1411
1456
|
e.fields = '';
|
|
@@ -1654,14 +1699,14 @@ var UI_FRAMEWORK_PLUGIN = {};
|
|
|
1654
1699
|
func.common.get_cast_val = async function (SESSION_ID, source, attributeP, typeP, valP, errorP) {
|
|
1655
1700
|
const report_conversion_error = function (res) {
|
|
1656
1701
|
if (errorP) {
|
|
1657
|
-
return func.utils.debug_report(SESSION_ID,
|
|
1702
|
+
return func.utils.debug_report(SESSION_ID, source.charAt(0).toUpperCase() + source.slice(1).toLowerCase(), errorP, 'W');
|
|
1658
1703
|
}
|
|
1659
1704
|
var msg = `error converting ${attributeP} from ${valP} to ${typeP}`;
|
|
1660
|
-
func.utils.debug_report(SESSION_ID,
|
|
1705
|
+
func.utils.debug_report(SESSION_ID, source.charAt(0).toUpperCase() + source.slice(1).toLowerCase(), msg, 'E');
|
|
1661
1706
|
};
|
|
1662
1707
|
const report_conversion_warn = function (msg) {
|
|
1663
1708
|
var msg = `type mismatch auto conversion made to ${attributeP} from value ${valP} to ${typeP}`;
|
|
1664
|
-
func.utils.debug_report(SESSION_ID,
|
|
1709
|
+
func.utils.debug_report(SESSION_ID, source.charAt(0).toUpperCase() + source.slice(1).toLowerCase(), msg, 'W');
|
|
1665
1710
|
};
|
|
1666
1711
|
const module = await func.common.get_module(SESSION_ID, `xuda-get-cast-util-module.mjs`);
|
|
1667
1712
|
return module.cast(typeP, valP, report_conversion_error, report_conversion_warn);
|
|
@@ -1679,11 +1724,17 @@ var WEBSOCKET_PROCESS_PID = null;
|
|
|
1679
1724
|
glb.worker_queue_num = 0;
|
|
1680
1725
|
glb.websocket_queue_num = 0;
|
|
1681
1726
|
|
|
1727
|
+
func.common._import_cache = func.common._import_cache || {};
|
|
1728
|
+
|
|
1682
1729
|
func.common.get_module = async function (SESSION_ID, module, paramsP = {}) {
|
|
1683
1730
|
let ret;
|
|
1684
1731
|
|
|
1685
1732
|
const get_ret = async function (src) {
|
|
1686
|
-
|
|
1733
|
+
// Cache the import() result to avoid repeated dynamic imports
|
|
1734
|
+
if (!func.common._import_cache[src]) {
|
|
1735
|
+
func.common._import_cache[src] = await import(src);
|
|
1736
|
+
}
|
|
1737
|
+
const module_ret = func.common._import_cache[src];
|
|
1687
1738
|
var params = get_params();
|
|
1688
1739
|
|
|
1689
1740
|
const ret = module_ret.XudaModule ? new module_ret.XudaModule(params) : await invoke_init_module(module_ret, params);
|
|
@@ -1734,7 +1785,7 @@ func.common.get_module = async function (SESSION_ID, module, paramsP = {}) {
|
|
|
1734
1785
|
}
|
|
1735
1786
|
|
|
1736
1787
|
const rep = function () {
|
|
1737
|
-
return
|
|
1788
|
+
return module.endsWith('.js') ? module.replace('.js', '.min.js') : module.replace('.mjs', '.min.mjs');
|
|
1738
1789
|
};
|
|
1739
1790
|
|
|
1740
1791
|
if (typeof IS_DOCKER !== 'undefined' || typeof IS_PROCESS_SERVER !== 'undefined') {
|
|
@@ -1892,7 +1943,7 @@ func.api.watch = function (path, cb, opt = {}) {
|
|
|
1892
1943
|
_session.watchers[path] = { ...opt, handler: cb };
|
|
1893
1944
|
|
|
1894
1945
|
if (opt.immediate) {
|
|
1895
|
-
const value =
|
|
1946
|
+
const value = xu_get(SESSION_OBJ[SESSION_ID].DS_GLB[0], path);
|
|
1896
1947
|
cb({ path, newValue: value, oldValue: value, timestamp: Date.now(), opt });
|
|
1897
1948
|
|
|
1898
1949
|
if (opt.once) {
|
|
@@ -2538,7 +2589,7 @@ func.runtime.ui.get_node_snapshot = function (nodeP) {
|
|
|
2538
2589
|
if (func.runtime.ui.node_snapshot_cache.has(nodeP)) {
|
|
2539
2590
|
return func.runtime.ui.node_snapshot_cache.get(nodeP);
|
|
2540
2591
|
}
|
|
2541
|
-
const snapshot = typeof
|
|
2592
|
+
const snapshot = typeof klona !== 'undefined' ? klona.klona(nodeP) : JSON.parse(JSON.stringify(nodeP));
|
|
2542
2593
|
func.runtime.ui.node_snapshot_cache.set(nodeP, snapshot);
|
|
2543
2594
|
return snapshot;
|
|
2544
2595
|
};
|
|
@@ -2885,7 +2936,7 @@ func.datasource.create = async function (
|
|
|
2885
2936
|
}
|
|
2886
2937
|
// vvvv run at worker vvvv
|
|
2887
2938
|
if (_ds) IS_DATASOURCE_REFRESH = true;
|
|
2888
|
-
var data =
|
|
2939
|
+
var data = Object.assign(
|
|
2889
2940
|
{
|
|
2890
2941
|
session_id: SESSION_ID,
|
|
2891
2942
|
dataSourceSessionGlobal: SESSION_OBJ[SESSION_ID].dataSourceSessionGlobal,
|
|
@@ -2940,7 +2991,7 @@ func.datasource.prepare = async function (SESSION_ID, prog_id, dataSourceNoP, pa
|
|
|
2940
2991
|
// &&
|
|
2941
2992
|
// glb.PARAMETER_NODES_ARR.includes(screenInfo.properties.menuType)
|
|
2942
2993
|
) {
|
|
2943
|
-
if (!
|
|
2994
|
+
if (!xu_isEmpty(screenInfo.properties.progParams)) {
|
|
2944
2995
|
_ds.in_parameters = {};
|
|
2945
2996
|
_ds.out_parameters = {};
|
|
2946
2997
|
|
|
@@ -3072,7 +3123,7 @@ func.datasource.prepare = async function (SESSION_ID, prog_id, dataSourceNoP, pa
|
|
|
3072
3123
|
_ds.refreshed = true;
|
|
3073
3124
|
|
|
3074
3125
|
if (_ds.watcher) {
|
|
3075
|
-
|
|
3126
|
+
xu_set(_ds, _ds.watcher.path, _ds.watcher.newValue);
|
|
3076
3127
|
}
|
|
3077
3128
|
try {
|
|
3078
3129
|
if (!_ds.v) _ds.v = {};
|
|
@@ -4059,7 +4110,7 @@ func.datasource.execute_field_init_events = async function (SESSION_ID, dataSour
|
|
|
4059
4110
|
var expression = undefined;
|
|
4060
4111
|
if (val.eventInfo.props.condition) expression = val.eventInfo.props.condition;
|
|
4061
4112
|
var expCond = {};
|
|
4062
|
-
if (expression && !
|
|
4113
|
+
if (expression && !xu_isEmpty(expression)) {
|
|
4063
4114
|
// check if expression exist
|
|
4064
4115
|
expCond = await func.expression.get(SESSION_ID, expression, dataSourceSession, 'condition', rowIdP, null, null, val.fieldId); // execute expression
|
|
4065
4116
|
cond = expCond.result;
|
|
@@ -4203,7 +4254,7 @@ func.datasource.get_view_events_count = async function (SESSION_ID, dataSourceSe
|
|
|
4203
4254
|
|
|
4204
4255
|
_ds.viewEventExec_arr[index] = [];
|
|
4205
4256
|
|
|
4206
|
-
if (!_prog.progEvents ||
|
|
4257
|
+
if (!_prog.progEvents || xu_isEmpty(_prog.progEvents)) return 0;
|
|
4207
4258
|
|
|
4208
4259
|
for (const event_obj of _prog.progEvents) {
|
|
4209
4260
|
if (event_obj.data.type !== typeP) continue; // was false?? changed to true 020317
|
|
@@ -4216,7 +4267,7 @@ func.datasource.get_view_events_count = async function (SESSION_ID, dataSourceSe
|
|
|
4216
4267
|
}
|
|
4217
4268
|
}
|
|
4218
4269
|
|
|
4219
|
-
if (
|
|
4270
|
+
if (xu_isEmpty(event_obj.workflow)) continue;
|
|
4220
4271
|
for (const trigger_obj of event_obj.workflow) {
|
|
4221
4272
|
if (trigger_obj.data.enabled) {
|
|
4222
4273
|
var expression;
|
|
@@ -4269,7 +4320,7 @@ func.datasource.execute_view_events = async function (SESSION_ID, dataSourceSess
|
|
|
4269
4320
|
var index = typeP;
|
|
4270
4321
|
if (eventIdP) index = typeP + '_' + eventIdP;
|
|
4271
4322
|
var arr = _ds.viewEventExec_arr[index];
|
|
4272
|
-
if (
|
|
4323
|
+
if (xu_isEmpty(arr)) return;
|
|
4273
4324
|
|
|
4274
4325
|
for await (const val of arr) {
|
|
4275
4326
|
if (!glb.IS_WORKER || !func.utils.is_onscreen_event(val.eventInfo.data.action) || (glb.IS_WORKER && _ds.v.run_at === 'server' && !func.utils.is_onscreen_event(val.eventInfo.data.action))) {
|
|
@@ -4401,12 +4452,12 @@ func.datasource.clean_all = function (SESSION_ID, dsP) {
|
|
|
4401
4452
|
|
|
4402
4453
|
var get_child_ds = function (ds) {
|
|
4403
4454
|
var arr = [];
|
|
4404
|
-
|
|
4455
|
+
for (const [key, val] of Object.entries(SESSION_OBJ[SESSION_ID].DS_GLB)) {
|
|
4405
4456
|
if (val.parentDataSourceNo == ds) {
|
|
4406
4457
|
arr.push(key);
|
|
4407
4458
|
arr = arr.concat(get_child_ds(key));
|
|
4408
4459
|
}
|
|
4409
|
-
}
|
|
4460
|
+
}
|
|
4410
4461
|
return arr;
|
|
4411
4462
|
};
|
|
4412
4463
|
|
|
@@ -4491,12 +4542,12 @@ func.datasource.del = function (SESSION_ID, dsP) {
|
|
|
4491
4542
|
|
|
4492
4543
|
var delete_pending_jobs = function () {
|
|
4493
4544
|
var arr = [];
|
|
4494
|
-
|
|
4545
|
+
for (const [key, val] of Object.entries(SESSION_OBJ[SESSION_ID].WORKER_OBJ.jobs)) {
|
|
4495
4546
|
if (val && val.dsSessionP == dsP) {
|
|
4496
4547
|
arr.push(key);
|
|
4497
4548
|
func.runtime.ui.clear_screen_blockers();
|
|
4498
4549
|
}
|
|
4499
|
-
}
|
|
4550
|
+
}
|
|
4500
4551
|
for (let val of arr.reverse()) {
|
|
4501
4552
|
SESSION_OBJ[SESSION_ID].WORKER_OBJ.jobs.splice(val, 1);
|
|
4502
4553
|
}
|
|
@@ -4624,7 +4675,7 @@ func.datasource.update = async function (SESSION_ID, datasource_changes, update_
|
|
|
4624
4675
|
for (const [field_id, value] of Object.entries(fields_data)) {
|
|
4625
4676
|
// mechanism to make update directly on the datasource object
|
|
4626
4677
|
if (record_id === 'datasource_main') {
|
|
4627
|
-
|
|
4678
|
+
xu_set(_ds, field_id, value);
|
|
4628
4679
|
const ret = update_xu_ref(dataSource);
|
|
4629
4680
|
if (ret) {
|
|
4630
4681
|
fields_changed.push(field_id);
|
|
@@ -4672,7 +4723,7 @@ func.datasource.update = async function (SESSION_ID, datasource_changes, update_
|
|
|
4672
4723
|
try {
|
|
4673
4724
|
const row_idx = func.common.find_ROWID_idx(_ds, record_id);
|
|
4674
4725
|
// if (_ds.data_feed.rows[row_idx][field_id] !== value) {
|
|
4675
|
-
if (!
|
|
4726
|
+
if (!xu_isEqual(_ds.data_feed.rows[row_idx][field_id], value)) {
|
|
4676
4727
|
_ds.data_feed.rows[row_idx][field_id] = value;
|
|
4677
4728
|
await set_fieldComputed_dependencies(dataSource, field_id, null);
|
|
4678
4729
|
|
|
@@ -4745,11 +4796,11 @@ func.datasource.update = async function (SESSION_ID, datasource_changes, update_
|
|
|
4745
4796
|
}
|
|
4746
4797
|
|
|
4747
4798
|
if (glb.IS_WORKER) {
|
|
4748
|
-
if (!update_local_scope_only && !
|
|
4799
|
+
if (!update_local_scope_only && !xu_isEmpty(client_datasource_changes)) {
|
|
4749
4800
|
func.utils.post_back_to_client(SESSION_ID, 'update_client_eventChangesResults_from_worker', _session.worker_id, client_datasource_changes);
|
|
4750
4801
|
}
|
|
4751
4802
|
} else {
|
|
4752
|
-
if (!update_local_scope_only && !
|
|
4803
|
+
if (!update_local_scope_only && !xu_isEmpty(server_datasource_changes)) {
|
|
4753
4804
|
const ret = await func.index.call_worker(SESSION_ID, {
|
|
4754
4805
|
service: 'update_datasource_changes_from_client',
|
|
4755
4806
|
data: {
|
|
@@ -5402,7 +5453,7 @@ func.datasource.get_viewLoops = async function (SESSION_ID, dataSourceSession, d
|
|
|
5402
5453
|
// var v = _ds.v;
|
|
5403
5454
|
var ret = default_limit;
|
|
5404
5455
|
|
|
5405
|
-
if (batch_source === 'db_data') ret =
|
|
5456
|
+
if (batch_source === 'db_data') ret = data.rows.length;
|
|
5406
5457
|
if (batch_source === 'array' || batch_source === 'csv') ret = data.length;
|
|
5407
5458
|
if (batch_source === 'json') ret = Object.keys(data).length;
|
|
5408
5459
|
if (_ds.progDataSource?.dataSourceLimit) {
|
|
@@ -5429,7 +5480,7 @@ func.datasource.set_VIEW_data = async function (SESSION_ID, args, _ds) {
|
|
|
5429
5480
|
};
|
|
5430
5481
|
_ds.viewEventExec_arr = {};
|
|
5431
5482
|
|
|
5432
|
-
var view =
|
|
5483
|
+
var view = klona.klona(await func.utils.VIEWS_OBJ.get(SESSION_ID, args.prog_id));
|
|
5433
5484
|
// var view = klona.klona(await func.utils.VIEWS_OBJ.get(SESSION_ID, args.prog_id));
|
|
5434
5485
|
|
|
5435
5486
|
_ds.v.dataSourceSrcType = view.dataSourceSrcType;
|
|
@@ -5475,11 +5526,11 @@ func.datasource.get_cast_val = async function (SESSION_ID, source, dsSession, va
|
|
|
5475
5526
|
if (error) {
|
|
5476
5527
|
return func.utils.debug_report(SESSION_ID, msg, '', 'W');
|
|
5477
5528
|
}
|
|
5478
|
-
func.utils.debug_report(SESSION_ID, msg + ' ' +
|
|
5529
|
+
func.utils.debug_report(SESSION_ID, msg + ' ' + (source.charAt(0).toUpperCase() + source.slice(1).toLowerCase()) + prog_info, '', 'E');
|
|
5479
5530
|
};
|
|
5480
5531
|
const report_conversion_warn = function (res) {
|
|
5481
5532
|
var msg = `type mismatch auto conversion from value ${valP} to ${typeP}`;
|
|
5482
|
-
func.utils.debug_report(SESSION_ID, msg + ' ' +
|
|
5533
|
+
func.utils.debug_report(SESSION_ID, msg + ' ' + (source.charAt(0).toUpperCase() + source.slice(1).toLowerCase()) + prog_info, '', 'W');
|
|
5483
5534
|
};
|
|
5484
5535
|
// var ret = valP;
|
|
5485
5536
|
if (error) {
|
|
@@ -5548,7 +5599,7 @@ func.datasource.update_changes_for_out_parameter = async function (SESSION_ID, d
|
|
|
5548
5599
|
}
|
|
5549
5600
|
}
|
|
5550
5601
|
}
|
|
5551
|
-
if (!
|
|
5602
|
+
if (!xu_isEmpty(data)) {
|
|
5552
5603
|
let datasource_changes = {
|
|
5553
5604
|
[calling_dsP]: { [_calling_ds.currentRecordId]: data },
|
|
5554
5605
|
};
|
|
@@ -5659,7 +5710,7 @@ func.utils.DOCS_OBJ.get = async function (SESSION_ID, idP) {
|
|
|
5659
5710
|
|
|
5660
5711
|
if (idP !== 'system') {
|
|
5661
5712
|
DOCS_OBJ[_app_id][idP] = await module.DOCS_OBJ_get(SESSION_ID, idP);
|
|
5662
|
-
if (DOCS_OBJ[_app_id][idP] &&
|
|
5713
|
+
if (DOCS_OBJ[_app_id][idP] && xu_isEmpty(DOCS_OBJ[_app_id][idP])) {
|
|
5663
5714
|
await func.utils.remove_cached_objects(SESSION_ID);
|
|
5664
5715
|
|
|
5665
5716
|
delete DOCS_OBJ[_app_id][idP];
|
|
@@ -5671,7 +5722,7 @@ func.utils.DOCS_OBJ.get = async function (SESSION_ID, idP) {
|
|
|
5671
5722
|
if (APP_OBJ[_app_id].app_imported_projects) {
|
|
5672
5723
|
for await (const imported_app_id of APP_OBJ[_app_id].app_imported_projects) {
|
|
5673
5724
|
var view_ret = await module.DOCS_OBJ_get(SESSION_ID, 'global_' + imported_app_id);
|
|
5674
|
-
DOCS_OBJ[_app_id][idP] =
|
|
5725
|
+
DOCS_OBJ[_app_id][idP] = Object.assign(DOCS_OBJ[_app_id][idP], view_ret);
|
|
5675
5726
|
}
|
|
5676
5727
|
}
|
|
5677
5728
|
return DOCS_OBJ[_app_id][idP];
|
|
@@ -5753,13 +5804,13 @@ func.utils.get_dateTime = async function (SESSION_ID, typeP, dateP) {
|
|
|
5753
5804
|
let ts = await get_server_ts();
|
|
5754
5805
|
sysDate = new Date(ts);
|
|
5755
5806
|
}
|
|
5756
|
-
var day =
|
|
5757
|
-
var month =
|
|
5807
|
+
var day = String(sysDate.getDate()).padStart(2, '0');
|
|
5808
|
+
var month = String(sysDate.getMonth() + 1).padStart(2, '0');
|
|
5758
5809
|
var year = sysDate.getFullYear();
|
|
5759
|
-
var week =
|
|
5760
|
-
var hour =
|
|
5761
|
-
var minute =
|
|
5762
|
-
var second =
|
|
5810
|
+
var week = String(getWeekNumber(sysDate)).padStart(2, '0');
|
|
5811
|
+
var hour = String(sysDate.getHours()).padStart(2, '0');
|
|
5812
|
+
var minute = String(sysDate.getMinutes()).padStart(2, '0');
|
|
5813
|
+
var second = String(sysDate.getSeconds()).padStart(2, '0');
|
|
5763
5814
|
if (typeP === 'SYS_DATE') return year + '-' + month + '-' + day;
|
|
5764
5815
|
if (typeP === 'SYS_DATE_TIME') return year + '-' + month + '-' + day + 'T' + hour + ':' + minute;
|
|
5765
5816
|
if (typeP === 'SYS_DATE_VALUE') return sysDate.valueOf();
|
|
@@ -5797,7 +5848,7 @@ func.utils.clean_returned_datasource = function (SESSION_ID, DS) {
|
|
|
5797
5848
|
var _session = SESSION_OBJ[SESSION_ID];
|
|
5798
5849
|
if (!_session.DS_GLB[DS]) return;
|
|
5799
5850
|
|
|
5800
|
-
var obj =
|
|
5851
|
+
var obj = { ..._session.DS_GLB[DS] };
|
|
5801
5852
|
|
|
5802
5853
|
delete obj.screen_params;
|
|
5803
5854
|
|
|
@@ -5817,7 +5868,7 @@ func.utils.clean_returned_datasource = function (SESSION_ID, DS) {
|
|
|
5817
5868
|
|
|
5818
5869
|
const clean_empty_objects = function () {
|
|
5819
5870
|
for (const [key, val] of Object.entries(obj)) {
|
|
5820
|
-
if (typeof val === 'object' && !Array.isArray(val) &&
|
|
5871
|
+
if (typeof val === 'object' && !Array.isArray(val) && xu_isEmpty(val)) {
|
|
5821
5872
|
delete obj[key];
|
|
5822
5873
|
}
|
|
5823
5874
|
}
|
|
@@ -6208,7 +6259,7 @@ func.utils.ws_worker.functions = {
|
|
|
6208
6259
|
});
|
|
6209
6260
|
},
|
|
6210
6261
|
update_datasource_changes_from_client: async function (params, promise_queue_id) {
|
|
6211
|
-
if (
|
|
6262
|
+
if (xu_isEmpty(SESSION_OBJ)) return;
|
|
6212
6263
|
var SESSION_ID = params.session_id;
|
|
6213
6264
|
var _session = SESSION_OBJ[SESSION_ID];
|
|
6214
6265
|
if (!_session) {
|
|
@@ -6779,7 +6830,7 @@ func.utils.alerts.popup = function (title, message, alert_type) {
|
|
|
6779
6830
|
},
|
|
6780
6831
|
];
|
|
6781
6832
|
|
|
6782
|
-
popup.create(
|
|
6833
|
+
popup.create(alert_type.charAt(0).toUpperCase() + alert_type.slice(1), title, message, buttons);
|
|
6783
6834
|
};
|
|
6784
6835
|
|
|
6785
6836
|
func.utils.get_system_error_msg = function () {
|
|
@@ -7426,7 +7477,7 @@ func.utils.call_plugin_api = function (SESSION_ID, plugin_nameP, dataP) {
|
|
|
7426
7477
|
app_token: _session.app_token,
|
|
7427
7478
|
};
|
|
7428
7479
|
|
|
7429
|
-
data =
|
|
7480
|
+
data = Object.assign(data, dataP);
|
|
7430
7481
|
|
|
7431
7482
|
fetch(`https://xuda.ai/ppi/${plugin_nameP}`, {
|
|
7432
7483
|
method: 'POST',
|
|
@@ -7584,7 +7635,7 @@ func.utils.get_resource_filename = function (build, filename) {
|
|
|
7584
7635
|
};
|
|
7585
7636
|
|
|
7586
7637
|
func.utils.set_SYS_GLOBAL_OBJ_WIDGET_INFO = async function (SESSION_ID, docP) {
|
|
7587
|
-
var obj =
|
|
7638
|
+
var obj = { ...docP };
|
|
7588
7639
|
obj.date = await func.utils.get_dateTime(SESSION_ID, 'SYS_DATE', docP.date);
|
|
7589
7640
|
obj.time = await func.utils.get_dateTime(SESSION_ID, 'SYS_TIME', docP.date);
|
|
7590
7641
|
|
|
@@ -7699,7 +7750,7 @@ func.events.validate = async function (SESSION_ID, triggerP, dsSessionP, eventId
|
|
|
7699
7750
|
|
|
7700
7751
|
let value = await func.common.get_cast_val(SESSION_ID, 'events', fieldId, field_info.props.fieldType, args[fieldId].value);
|
|
7701
7752
|
|
|
7702
|
-
if (!
|
|
7753
|
+
if (!xu_isEmpty(args[fieldId].fx)) {
|
|
7703
7754
|
const fx_ret = await func.expression.get(SESSION_ID, args[fieldId].fx, dsSessionP, 'update');
|
|
7704
7755
|
value = fx_ret.result;
|
|
7705
7756
|
}
|
|
@@ -7721,7 +7772,7 @@ func.events.validate = async function (SESSION_ID, triggerP, dsSessionP, eventId
|
|
|
7721
7772
|
if (_event.workflow) {
|
|
7722
7773
|
// check if event property exist
|
|
7723
7774
|
|
|
7724
|
-
if (!_event.workflow ||
|
|
7775
|
+
if (!_event.workflow || xu_isEmpty(_event.workflow)) return;
|
|
7725
7776
|
// check events has rows
|
|
7726
7777
|
for (const trigger_obj of _event.workflow) {
|
|
7727
7778
|
//run events rows
|
|
@@ -7940,12 +7991,12 @@ func.events.find_job_index = function (SESSION_ID, jobNoP) {
|
|
|
7940
7991
|
var _session = SESSION_OBJ[SESSION_ID];
|
|
7941
7992
|
var ret = null;
|
|
7942
7993
|
if (!_session.WORKER_OBJ) return ret;
|
|
7943
|
-
|
|
7994
|
+
for (const [key, val] of Object.entries(_session.WORKER_OBJ.jobs)) {
|
|
7944
7995
|
if (val && val.job_num == jobNoP) {
|
|
7945
7996
|
ret = key;
|
|
7946
|
-
|
|
7997
|
+
break;
|
|
7947
7998
|
}
|
|
7948
|
-
}
|
|
7999
|
+
}
|
|
7949
8000
|
return ret;
|
|
7950
8001
|
};
|
|
7951
8002
|
func.events.execute = async function (
|
|
@@ -8218,7 +8269,7 @@ func.events.execute = async function (
|
|
|
8218
8269
|
var _session = SESSION_OBJ[SESSION_ID];
|
|
8219
8270
|
|
|
8220
8271
|
const set_SYS_GLOBAL_OBJ_WIDGET_INFO = async function (docP) {
|
|
8221
|
-
var obj =
|
|
8272
|
+
var obj = { ...docP };
|
|
8222
8273
|
obj.date = await func.utils.get_dateTime(SESSION_ID, 'SYS_DATE', docP.date);
|
|
8223
8274
|
obj.time = await func.utils.get_dateTime(SESSION_ID, 'SYS_TIME', docP.date);
|
|
8224
8275
|
|
|
@@ -8505,7 +8556,7 @@ func.events.execute = async function (
|
|
|
8505
8556
|
|
|
8506
8557
|
let _ds_new = _session.DS_GLB[ret.dsSessionP];
|
|
8507
8558
|
let parameters = args?.calling_trigger_prop?.data?.name?.parameters;
|
|
8508
|
-
if (parameters && !
|
|
8559
|
+
if (parameters && !xu_isEmpty(parameters)) {
|
|
8509
8560
|
await func.datasource.update_changes_for_out_parameter(SESSION_ID, _ds_new.dsSession, _ds.dsSession);
|
|
8510
8561
|
}
|
|
8511
8562
|
|
|
@@ -8524,7 +8575,7 @@ func.events.execute = async function (
|
|
|
8524
8575
|
},
|
|
8525
8576
|
update: async function () {
|
|
8526
8577
|
const obj_values_to_update = func.datasource.get_viewFields_for_update_function(SESSION_ID, calling_trigger_prop, null, dsSessionP);
|
|
8527
|
-
if (!obj_values_to_update ||
|
|
8578
|
+
if (!obj_values_to_update || xu_isEmpty(obj_values_to_update)) {
|
|
8528
8579
|
func.utils.debug_report(SESSION_ID, 'Update values object is empty', '', 'W');
|
|
8529
8580
|
if (jobNoP) func.events.delete_job(SESSION_ID, jobNoP);
|
|
8530
8581
|
return;
|
|
@@ -8716,11 +8767,11 @@ func.events.execute = async function (
|
|
|
8716
8767
|
if (error) {
|
|
8717
8768
|
return func.utils.debug_report(SESSION_ID, msg, '', 'W');
|
|
8718
8769
|
}
|
|
8719
|
-
func.utils.debug_report(SESSION_ID, msg + ' ' +
|
|
8770
|
+
func.utils.debug_report(SESSION_ID, msg + ' ' + (source.charAt(0).toUpperCase() + source.slice(1).toLowerCase()) + prog_info, '', 'E');
|
|
8720
8771
|
};
|
|
8721
8772
|
const report_conversion_warn = function (res) {
|
|
8722
8773
|
var msg = `${elementP} >${triggerP} >${functionP} > type mismatch auto conversion from value ${valP} to ${typeP}`;
|
|
8723
|
-
func.utils.debug_report(SESSION_ID, msg + ' ' +
|
|
8774
|
+
func.utils.debug_report(SESSION_ID, msg + ' ' + (source.charAt(0).toUpperCase() + source.slice(1).toLowerCase()) + prog_info, '', 'W');
|
|
8724
8775
|
};
|
|
8725
8776
|
// var ret = valP;
|
|
8726
8777
|
if (error) {
|
|
@@ -8735,8 +8786,7 @@ func.events.execute = async function (
|
|
|
8735
8786
|
// report_conversion_warn
|
|
8736
8787
|
// );
|
|
8737
8788
|
|
|
8738
|
-
var payload =
|
|
8739
|
-
payload_arr,
|
|
8789
|
+
var payload = payload_arr.reduce(
|
|
8740
8790
|
(ret, val, key) => {
|
|
8741
8791
|
ret[val.key] = module.cast(val.type, val.val, report_conversion_error, report_conversion_warn);
|
|
8742
8792
|
|
|
@@ -8853,12 +8903,12 @@ func.events.check_jobs_idle = async function (SESSION_ID, jobsP) {
|
|
|
8853
8903
|
var listener = setInterval(function () {
|
|
8854
8904
|
var found;
|
|
8855
8905
|
for (const [key, val] of Object.entries(jobsP)) {
|
|
8856
|
-
|
|
8906
|
+
for (const [key2, val2] of Object.entries(_session.WORKER_OBJ.jobs)) {
|
|
8857
8907
|
if (key2 === val) {
|
|
8858
8908
|
found = true;
|
|
8859
|
-
|
|
8909
|
+
break;
|
|
8860
8910
|
}
|
|
8861
|
-
}
|
|
8911
|
+
}
|
|
8862
8912
|
}
|
|
8863
8913
|
if (!found) {
|
|
8864
8914
|
do_callback();
|
|
@@ -8927,7 +8977,7 @@ func.events.invoke = async function (event_id) {
|
|
|
8927
8977
|
var ds;
|
|
8928
8978
|
for await (const [ds_key, val] of Object.entries(_session.DS_GLB)) {
|
|
8929
8979
|
const _view_obj = await func.utils.VIEWS_OBJ.get(SESSION_ID, val.prog_id);
|
|
8930
|
-
if (
|
|
8980
|
+
if (xu_isEmpty(_view_obj.progEvents)) continue;
|
|
8931
8981
|
if (ds) break;
|
|
8932
8982
|
for await (const [key, val] of Object.entries(_view_obj.progEvents)) {
|
|
8933
8983
|
if (val?.data?.type === 'user_defined' && val.data.event_name === event_id) {
|
|
@@ -8984,7 +9034,7 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
|
|
|
8984
9034
|
}
|
|
8985
9035
|
}
|
|
8986
9036
|
|
|
8987
|
-
ret = ret.replace(/\&/g, '&');
|
|
9037
|
+
if (ret.includes('&')) ret = ret.replace(/\&/g, '&');
|
|
8988
9038
|
ret = func.utils.replace_studio_drive_url(SESSION_ID, ret);
|
|
8989
9039
|
|
|
8990
9040
|
const end_results = function () {
|
|
@@ -9048,13 +9098,13 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
|
|
|
9048
9098
|
const variable_not_exist = async function () {
|
|
9049
9099
|
try {
|
|
9050
9100
|
if (sourceP !== 'arguments') {
|
|
9051
|
-
if (ret && ret.
|
|
9052
|
-
ret = ret.
|
|
9101
|
+
if (ret && ret.startsWith('_DATE_')) {
|
|
9102
|
+
ret = ret.slice(6);
|
|
9053
9103
|
} else if (
|
|
9054
|
-
|
|
9055
|
-
ret === '
|
|
9104
|
+
ret === 'self' || // bypass eval for 'self'
|
|
9105
|
+
(ret && ret.length === 10 && ret[4] === '-' && ret[7] === '-') // bypass eval for date 2017-03-22
|
|
9056
9106
|
) {
|
|
9057
|
-
|
|
9107
|
+
// date or 'self' — skip eval, return as-is
|
|
9058
9108
|
} else {
|
|
9059
9109
|
ret = await func.expression.secure_eval(SESSION_ID, sourceP, ret, jobNo, dsSessionP, js_script_callback);
|
|
9060
9110
|
}
|
|
@@ -9074,13 +9124,8 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
|
|
|
9074
9124
|
return await variable_not_exist();
|
|
9075
9125
|
}
|
|
9076
9126
|
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
return glb.emailRegex.test(ret);
|
|
9081
|
-
};
|
|
9082
|
-
|
|
9083
|
-
if (await validate_email()) {
|
|
9127
|
+
// Fast-path: test raw string for email pattern before expensive eval
|
|
9128
|
+
if (glb.emailRegex.test(valP)) {
|
|
9084
9129
|
return await variable_not_exist();
|
|
9085
9130
|
}
|
|
9086
9131
|
|
|
@@ -9088,8 +9133,10 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
|
|
|
9088
9133
|
var var_Arr = [];
|
|
9089
9134
|
const split = func.expression.parse(ret) || [];
|
|
9090
9135
|
// console.log(valP, split);
|
|
9091
|
-
|
|
9136
|
+
const split_entries = Object.entries(split);
|
|
9137
|
+
for (let entry_i = 0; entry_i < split_entries.length; entry_i++) {
|
|
9092
9138
|
// run each field
|
|
9139
|
+
const [arr_key, val] = split_entries[entry_i];
|
|
9093
9140
|
const key = Number(arr_key);
|
|
9094
9141
|
var_Arr[key] = {};
|
|
9095
9142
|
var_Arr[key].value = val.value;
|
|
@@ -9134,14 +9181,16 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
|
|
|
9134
9181
|
var prevData = var_Arr[key - 1].value;
|
|
9135
9182
|
var_Arr[key].value = prevData[data]; // @objB[@var]
|
|
9136
9183
|
if (val.value.indexOf('.') > -1) {
|
|
9137
|
-
|
|
9184
|
+
const props_split = await func.expression.get_property(val.value);
|
|
9185
|
+
property2 = props_split.property2;
|
|
9138
9186
|
if (prevData[data]) set_value(prevData[data][property2]);
|
|
9139
9187
|
// var_Arr[key].value = prevData[data][property2]; //@objB[@var].property
|
|
9140
9188
|
}
|
|
9141
9189
|
delete var_Arr[key - 1];
|
|
9142
9190
|
} else {
|
|
9143
|
-
|
|
9144
|
-
|
|
9191
|
+
const props = await func.expression.get_property(val.value);
|
|
9192
|
+
property1 = props.property1;
|
|
9193
|
+
property2 = props.property2;
|
|
9145
9194
|
if (property1) {
|
|
9146
9195
|
var_Arr[key].value = data[property1]; // @var["value"] or @var.property
|
|
9147
9196
|
if (property2) {
|
|
@@ -9189,7 +9238,7 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
|
|
|
9189
9238
|
var exp_exist;
|
|
9190
9239
|
var var_error_found;
|
|
9191
9240
|
// merge arr values
|
|
9192
|
-
|
|
9241
|
+
var_Arr.forEach(function (val, key) {
|
|
9193
9242
|
if (sourceP === 'UI Property EXP') {
|
|
9194
9243
|
let ret = func.utils.get_drive_url(SESSION_ID, val.value, true);
|
|
9195
9244
|
if (ret.changed) {
|
|
@@ -9265,7 +9314,7 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
|
|
|
9265
9314
|
if (exp.res) res = exp.res;
|
|
9266
9315
|
// do second pass when exp exist
|
|
9267
9316
|
else res = [exp.result];
|
|
9268
|
-
fields =
|
|
9317
|
+
fields = Object.assign(exp.fields, fieldsP);
|
|
9269
9318
|
}
|
|
9270
9319
|
var result = join(res);
|
|
9271
9320
|
|
|
@@ -9587,9 +9636,15 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
|
|
|
9587
9636
|
// return res;
|
|
9588
9637
|
// };
|
|
9589
9638
|
|
|
9639
|
+
func.expression._parse_cache = new Map();
|
|
9640
|
+
|
|
9590
9641
|
func.expression.parse = function (input) {
|
|
9591
9642
|
if (typeof input !== 'string') return [];
|
|
9592
9643
|
|
|
9644
|
+
if (func.expression._parse_cache.has(input)) {
|
|
9645
|
+
return func.expression._parse_cache.get(input).map(function (s) { return Object.assign({}, s); });
|
|
9646
|
+
}
|
|
9647
|
+
|
|
9593
9648
|
const segments = [];
|
|
9594
9649
|
let pos = 0;
|
|
9595
9650
|
|
|
@@ -9612,7 +9667,14 @@ func.expression.parse = function (input) {
|
|
|
9612
9667
|
pos += part.length;
|
|
9613
9668
|
}
|
|
9614
9669
|
|
|
9615
|
-
|
|
9670
|
+
// Evict oldest entry if cache exceeds limit
|
|
9671
|
+
if (func.expression._parse_cache.size >= 500) {
|
|
9672
|
+
const firstKey = func.expression._parse_cache.keys().next().value;
|
|
9673
|
+
func.expression._parse_cache.delete(firstKey);
|
|
9674
|
+
}
|
|
9675
|
+
func.expression._parse_cache.set(input, segments);
|
|
9676
|
+
|
|
9677
|
+
return segments.map(function (s) { return Object.assign({}, s); });
|
|
9616
9678
|
};
|
|
9617
9679
|
|
|
9618
9680
|
func.expression.get_property = async function (valP) {
|