@xuda.io/xuda-worker-bundle 1.3.2636 → 1.3.2638

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +150 -89
  2. 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) => !_.isEqual(item, value_from_getter));
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 = _.cloneDeep(dataset_arr.ret.value);
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 (!_.isObject(normalized_resource) && _.isString(normalized_resource)) {
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 (!_.isObject(normalized_resource)) {
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 = _.cloneDeep(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 && _.isArray(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 _.find(arr, function (e) {
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 _.find(arr, function (e) {
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 = _.cloneDeep(dataP);
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
- _.forEach(data, function (val, key) {
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, _.capitalize(source), errorP, 'W');
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, _.capitalize(source), msg, 'E');
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, _.capitalize(source), msg, 'W');
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
- const module_ret = await import(src);
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);
@@ -1700,7 +1751,6 @@ func.common.get_module = async function (SESSION_ID, module, paramsP = {}) {
1700
1751
  PROJECT_OBJ,
1701
1752
  DOCS_OBJ,
1702
1753
  SESSION_OBJ,
1703
- _,
1704
1754
  ...paramsP,
1705
1755
  };
1706
1756
  if (typeof IS_PROCESS_SERVER !== 'undefined') params.IS_PROCESS_SERVER = IS_PROCESS_SERVER;
@@ -1734,7 +1784,7 @@ func.common.get_module = async function (SESSION_ID, module, paramsP = {}) {
1734
1784
  }
1735
1785
 
1736
1786
  const rep = function () {
1737
- return _.endsWith(module, '.js') ? module.replace('.js', '.min.js') : module.replace('.mjs', '.min.mjs');
1787
+ return module.endsWith('.js') ? module.replace('.js', '.min.js') : module.replace('.mjs', '.min.mjs');
1738
1788
  };
1739
1789
 
1740
1790
  if (typeof IS_DOCKER !== 'undefined' || typeof IS_PROCESS_SERVER !== 'undefined') {
@@ -1892,7 +1942,7 @@ func.api.watch = function (path, cb, opt = {}) {
1892
1942
  _session.watchers[path] = { ...opt, handler: cb };
1893
1943
 
1894
1944
  if (opt.immediate) {
1895
- const value = _.get(SESSION_OBJ[SESSION_ID].DS_GLB[0], path);
1945
+ const value = xu_get(SESSION_OBJ[SESSION_ID].DS_GLB[0], path);
1896
1946
  cb({ path, newValue: value, oldValue: value, timestamp: Date.now(), opt });
1897
1947
 
1898
1948
  if (opt.once) {
@@ -2538,7 +2588,7 @@ func.runtime.ui.get_node_snapshot = function (nodeP) {
2538
2588
  if (func.runtime.ui.node_snapshot_cache.has(nodeP)) {
2539
2589
  return func.runtime.ui.node_snapshot_cache.get(nodeP);
2540
2590
  }
2541
- const snapshot = typeof _ !== 'undefined' ? _.cloneDeep(nodeP) : JSON.parse(JSON.stringify(nodeP));
2591
+ const snapshot = typeof klona !== 'undefined' ? klona.klona(nodeP) : JSON.parse(JSON.stringify(nodeP));
2542
2592
  func.runtime.ui.node_snapshot_cache.set(nodeP, snapshot);
2543
2593
  return snapshot;
2544
2594
  };
@@ -2885,7 +2935,7 @@ func.datasource.create = async function (
2885
2935
  }
2886
2936
  // vvvv run at worker vvvv
2887
2937
  if (_ds) IS_DATASOURCE_REFRESH = true;
2888
- var data = _.assignIn(
2938
+ var data = Object.assign(
2889
2939
  {
2890
2940
  session_id: SESSION_ID,
2891
2941
  dataSourceSessionGlobal: SESSION_OBJ[SESSION_ID].dataSourceSessionGlobal,
@@ -2940,7 +2990,7 @@ func.datasource.prepare = async function (SESSION_ID, prog_id, dataSourceNoP, pa
2940
2990
  // &&
2941
2991
  // glb.PARAMETER_NODES_ARR.includes(screenInfo.properties.menuType)
2942
2992
  ) {
2943
- if (!_.isEmpty(screenInfo.properties.progParams)) {
2993
+ if (!xu_isEmpty(screenInfo.properties.progParams)) {
2944
2994
  _ds.in_parameters = {};
2945
2995
  _ds.out_parameters = {};
2946
2996
 
@@ -3072,7 +3122,7 @@ func.datasource.prepare = async function (SESSION_ID, prog_id, dataSourceNoP, pa
3072
3122
  _ds.refreshed = true;
3073
3123
 
3074
3124
  if (_ds.watcher) {
3075
- _.set(_ds, _ds.watcher.path, _ds.watcher.newValue);
3125
+ xu_set(_ds, _ds.watcher.path, _ds.watcher.newValue);
3076
3126
  }
3077
3127
  try {
3078
3128
  if (!_ds.v) _ds.v = {};
@@ -4059,7 +4109,7 @@ func.datasource.execute_field_init_events = async function (SESSION_ID, dataSour
4059
4109
  var expression = undefined;
4060
4110
  if (val.eventInfo.props.condition) expression = val.eventInfo.props.condition;
4061
4111
  var expCond = {};
4062
- if (expression && !_.isEmpty(expression)) {
4112
+ if (expression && !xu_isEmpty(expression)) {
4063
4113
  // check if expression exist
4064
4114
  expCond = await func.expression.get(SESSION_ID, expression, dataSourceSession, 'condition', rowIdP, null, null, val.fieldId); // execute expression
4065
4115
  cond = expCond.result;
@@ -4203,7 +4253,7 @@ func.datasource.get_view_events_count = async function (SESSION_ID, dataSourceSe
4203
4253
 
4204
4254
  _ds.viewEventExec_arr[index] = [];
4205
4255
 
4206
- if (!_prog.progEvents || _.isEmpty(_prog.progEvents)) return 0;
4256
+ if (!_prog.progEvents || xu_isEmpty(_prog.progEvents)) return 0;
4207
4257
 
4208
4258
  for (const event_obj of _prog.progEvents) {
4209
4259
  if (event_obj.data.type !== typeP) continue; // was false?? changed to true 020317
@@ -4216,7 +4266,7 @@ func.datasource.get_view_events_count = async function (SESSION_ID, dataSourceSe
4216
4266
  }
4217
4267
  }
4218
4268
 
4219
- if (_.isEmpty(event_obj.workflow)) continue;
4269
+ if (xu_isEmpty(event_obj.workflow)) continue;
4220
4270
  for (const trigger_obj of event_obj.workflow) {
4221
4271
  if (trigger_obj.data.enabled) {
4222
4272
  var expression;
@@ -4269,7 +4319,7 @@ func.datasource.execute_view_events = async function (SESSION_ID, dataSourceSess
4269
4319
  var index = typeP;
4270
4320
  if (eventIdP) index = typeP + '_' + eventIdP;
4271
4321
  var arr = _ds.viewEventExec_arr[index];
4272
- if (_.isEmpty(arr)) return;
4322
+ if (xu_isEmpty(arr)) return;
4273
4323
 
4274
4324
  for await (const val of arr) {
4275
4325
  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 +4451,12 @@ func.datasource.clean_all = function (SESSION_ID, dsP) {
4401
4451
 
4402
4452
  var get_child_ds = function (ds) {
4403
4453
  var arr = [];
4404
- _.forEach(SESSION_OBJ[SESSION_ID].DS_GLB, function (val, key) {
4454
+ for (const [key, val] of Object.entries(SESSION_OBJ[SESSION_ID].DS_GLB)) {
4405
4455
  if (val.parentDataSourceNo == ds) {
4406
4456
  arr.push(key);
4407
4457
  arr = arr.concat(get_child_ds(key));
4408
4458
  }
4409
- });
4459
+ }
4410
4460
  return arr;
4411
4461
  };
4412
4462
 
@@ -4491,12 +4541,12 @@ func.datasource.del = function (SESSION_ID, dsP) {
4491
4541
 
4492
4542
  var delete_pending_jobs = function () {
4493
4543
  var arr = [];
4494
- _.forEach(SESSION_OBJ[SESSION_ID].WORKER_OBJ.jobs, function (val, key) {
4544
+ for (const [key, val] of Object.entries(SESSION_OBJ[SESSION_ID].WORKER_OBJ.jobs)) {
4495
4545
  if (val && val.dsSessionP == dsP) {
4496
4546
  arr.push(key);
4497
4547
  func.runtime.ui.clear_screen_blockers();
4498
4548
  }
4499
- });
4549
+ }
4500
4550
  for (let val of arr.reverse()) {
4501
4551
  SESSION_OBJ[SESSION_ID].WORKER_OBJ.jobs.splice(val, 1);
4502
4552
  }
@@ -4624,7 +4674,7 @@ func.datasource.update = async function (SESSION_ID, datasource_changes, update_
4624
4674
  for (const [field_id, value] of Object.entries(fields_data)) {
4625
4675
  // mechanism to make update directly on the datasource object
4626
4676
  if (record_id === 'datasource_main') {
4627
- _.set(_ds, field_id, value);
4677
+ xu_set(_ds, field_id, value);
4628
4678
  const ret = update_xu_ref(dataSource);
4629
4679
  if (ret) {
4630
4680
  fields_changed.push(field_id);
@@ -4672,7 +4722,7 @@ func.datasource.update = async function (SESSION_ID, datasource_changes, update_
4672
4722
  try {
4673
4723
  const row_idx = func.common.find_ROWID_idx(_ds, record_id);
4674
4724
  // if (_ds.data_feed.rows[row_idx][field_id] !== value) {
4675
- if (!_.isEqual(_ds.data_feed.rows[row_idx][field_id], value)) {
4725
+ if (!xu_isEqual(_ds.data_feed.rows[row_idx][field_id], value)) {
4676
4726
  _ds.data_feed.rows[row_idx][field_id] = value;
4677
4727
  await set_fieldComputed_dependencies(dataSource, field_id, null);
4678
4728
 
@@ -4745,11 +4795,11 @@ func.datasource.update = async function (SESSION_ID, datasource_changes, update_
4745
4795
  }
4746
4796
 
4747
4797
  if (glb.IS_WORKER) {
4748
- if (!update_local_scope_only && !_.isEmpty(client_datasource_changes)) {
4798
+ if (!update_local_scope_only && !xu_isEmpty(client_datasource_changes)) {
4749
4799
  func.utils.post_back_to_client(SESSION_ID, 'update_client_eventChangesResults_from_worker', _session.worker_id, client_datasource_changes);
4750
4800
  }
4751
4801
  } else {
4752
- if (!update_local_scope_only && !_.isEmpty(server_datasource_changes)) {
4802
+ if (!update_local_scope_only && !xu_isEmpty(server_datasource_changes)) {
4753
4803
  const ret = await func.index.call_worker(SESSION_ID, {
4754
4804
  service: 'update_datasource_changes_from_client',
4755
4805
  data: {
@@ -5402,7 +5452,7 @@ func.datasource.get_viewLoops = async function (SESSION_ID, dataSourceSession, d
5402
5452
  // var v = _ds.v;
5403
5453
  var ret = default_limit;
5404
5454
 
5405
- if (batch_source === 'db_data') ret = _.size(data.rows);
5455
+ if (batch_source === 'db_data') ret = data.rows.length;
5406
5456
  if (batch_source === 'array' || batch_source === 'csv') ret = data.length;
5407
5457
  if (batch_source === 'json') ret = Object.keys(data).length;
5408
5458
  if (_ds.progDataSource?.dataSourceLimit) {
@@ -5429,7 +5479,7 @@ func.datasource.set_VIEW_data = async function (SESSION_ID, args, _ds) {
5429
5479
  };
5430
5480
  _ds.viewEventExec_arr = {};
5431
5481
 
5432
- var view = _.cloneDeep(await func.utils.VIEWS_OBJ.get(SESSION_ID, args.prog_id));
5482
+ var view = klona.klona(await func.utils.VIEWS_OBJ.get(SESSION_ID, args.prog_id));
5433
5483
  // var view = klona.klona(await func.utils.VIEWS_OBJ.get(SESSION_ID, args.prog_id));
5434
5484
 
5435
5485
  _ds.v.dataSourceSrcType = view.dataSourceSrcType;
@@ -5475,11 +5525,11 @@ func.datasource.get_cast_val = async function (SESSION_ID, source, dsSession, va
5475
5525
  if (error) {
5476
5526
  return func.utils.debug_report(SESSION_ID, msg, '', 'W');
5477
5527
  }
5478
- func.utils.debug_report(SESSION_ID, msg + ' ' + _.capitalize(source) + prog_info, '', 'E');
5528
+ func.utils.debug_report(SESSION_ID, msg + ' ' + (source.charAt(0).toUpperCase() + source.slice(1).toLowerCase()) + prog_info, '', 'E');
5479
5529
  };
5480
5530
  const report_conversion_warn = function (res) {
5481
5531
  var msg = `type mismatch auto conversion from value ${valP} to ${typeP}`;
5482
- func.utils.debug_report(SESSION_ID, msg + ' ' + _.capitalize(source) + prog_info, '', 'W');
5532
+ func.utils.debug_report(SESSION_ID, msg + ' ' + (source.charAt(0).toUpperCase() + source.slice(1).toLowerCase()) + prog_info, '', 'W');
5483
5533
  };
5484
5534
  // var ret = valP;
5485
5535
  if (error) {
@@ -5548,7 +5598,7 @@ func.datasource.update_changes_for_out_parameter = async function (SESSION_ID, d
5548
5598
  }
5549
5599
  }
5550
5600
  }
5551
- if (!_.isEmpty(data)) {
5601
+ if (!xu_isEmpty(data)) {
5552
5602
  let datasource_changes = {
5553
5603
  [calling_dsP]: { [_calling_ds.currentRecordId]: data },
5554
5604
  };
@@ -5659,7 +5709,7 @@ func.utils.DOCS_OBJ.get = async function (SESSION_ID, idP) {
5659
5709
 
5660
5710
  if (idP !== 'system') {
5661
5711
  DOCS_OBJ[_app_id][idP] = await module.DOCS_OBJ_get(SESSION_ID, idP);
5662
- if (DOCS_OBJ[_app_id][idP] && _.isEmpty(DOCS_OBJ[_app_id][idP])) {
5712
+ if (DOCS_OBJ[_app_id][idP] && xu_isEmpty(DOCS_OBJ[_app_id][idP])) {
5663
5713
  await func.utils.remove_cached_objects(SESSION_ID);
5664
5714
 
5665
5715
  delete DOCS_OBJ[_app_id][idP];
@@ -5671,7 +5721,7 @@ func.utils.DOCS_OBJ.get = async function (SESSION_ID, idP) {
5671
5721
  if (APP_OBJ[_app_id].app_imported_projects) {
5672
5722
  for await (const imported_app_id of APP_OBJ[_app_id].app_imported_projects) {
5673
5723
  var view_ret = await module.DOCS_OBJ_get(SESSION_ID, 'global_' + imported_app_id);
5674
- DOCS_OBJ[_app_id][idP] = _.merge(DOCS_OBJ[_app_id][idP], view_ret);
5724
+ DOCS_OBJ[_app_id][idP] = Object.assign(DOCS_OBJ[_app_id][idP], view_ret);
5675
5725
  }
5676
5726
  }
5677
5727
  return DOCS_OBJ[_app_id][idP];
@@ -5753,13 +5803,13 @@ func.utils.get_dateTime = async function (SESSION_ID, typeP, dateP) {
5753
5803
  let ts = await get_server_ts();
5754
5804
  sysDate = new Date(ts);
5755
5805
  }
5756
- var day = _.padStart(sysDate.getDate(), 2, '0');
5757
- var month = _.padStart(sysDate.getMonth() + 1, 2, '0');
5806
+ var day = String(sysDate.getDate()).padStart(2, '0');
5807
+ var month = String(sysDate.getMonth() + 1).padStart(2, '0');
5758
5808
  var year = sysDate.getFullYear();
5759
- var week = _.padStart(getWeekNumber(sysDate), 2, '0');
5760
- var hour = _.padStart(sysDate.getHours(), 2, '0');
5761
- var minute = _.padStart(sysDate.getMinutes(), 2, '0');
5762
- var second = _.padStart(sysDate.getSeconds(), 2, '0');
5809
+ var week = String(getWeekNumber(sysDate)).padStart(2, '0');
5810
+ var hour = String(sysDate.getHours()).padStart(2, '0');
5811
+ var minute = String(sysDate.getMinutes()).padStart(2, '0');
5812
+ var second = String(sysDate.getSeconds()).padStart(2, '0');
5763
5813
  if (typeP === 'SYS_DATE') return year + '-' + month + '-' + day;
5764
5814
  if (typeP === 'SYS_DATE_TIME') return year + '-' + month + '-' + day + 'T' + hour + ':' + minute;
5765
5815
  if (typeP === 'SYS_DATE_VALUE') return sysDate.valueOf();
@@ -5797,7 +5847,7 @@ func.utils.clean_returned_datasource = function (SESSION_ID, DS) {
5797
5847
  var _session = SESSION_OBJ[SESSION_ID];
5798
5848
  if (!_session.DS_GLB[DS]) return;
5799
5849
 
5800
- var obj = _.clone(_session.DS_GLB[DS]);
5850
+ var obj = { ..._session.DS_GLB[DS] };
5801
5851
 
5802
5852
  delete obj.screen_params;
5803
5853
 
@@ -5817,7 +5867,7 @@ func.utils.clean_returned_datasource = function (SESSION_ID, DS) {
5817
5867
 
5818
5868
  const clean_empty_objects = function () {
5819
5869
  for (const [key, val] of Object.entries(obj)) {
5820
- if (typeof val === 'object' && !Array.isArray(val) && _.isEmpty(val)) {
5870
+ if (typeof val === 'object' && !Array.isArray(val) && xu_isEmpty(val)) {
5821
5871
  delete obj[key];
5822
5872
  }
5823
5873
  }
@@ -6208,7 +6258,7 @@ func.utils.ws_worker.functions = {
6208
6258
  });
6209
6259
  },
6210
6260
  update_datasource_changes_from_client: async function (params, promise_queue_id) {
6211
- if (_.isEmpty(SESSION_OBJ)) return;
6261
+ if (xu_isEmpty(SESSION_OBJ)) return;
6212
6262
  var SESSION_ID = params.session_id;
6213
6263
  var _session = SESSION_OBJ[SESSION_ID];
6214
6264
  if (!_session) {
@@ -6779,7 +6829,7 @@ func.utils.alerts.popup = function (title, message, alert_type) {
6779
6829
  },
6780
6830
  ];
6781
6831
 
6782
- popup.create(_.upperFirst(alert_type), title, message, buttons);
6832
+ popup.create(alert_type.charAt(0).toUpperCase() + alert_type.slice(1), title, message, buttons);
6783
6833
  };
6784
6834
 
6785
6835
  func.utils.get_system_error_msg = function () {
@@ -7426,7 +7476,7 @@ func.utils.call_plugin_api = function (SESSION_ID, plugin_nameP, dataP) {
7426
7476
  app_token: _session.app_token,
7427
7477
  };
7428
7478
 
7429
- data = _.assignIn(data, dataP);
7479
+ data = Object.assign(data, dataP);
7430
7480
 
7431
7481
  fetch(`https://xuda.ai/ppi/${plugin_nameP}`, {
7432
7482
  method: 'POST',
@@ -7584,7 +7634,7 @@ func.utils.get_resource_filename = function (build, filename) {
7584
7634
  };
7585
7635
 
7586
7636
  func.utils.set_SYS_GLOBAL_OBJ_WIDGET_INFO = async function (SESSION_ID, docP) {
7587
- var obj = _.clone(docP);
7637
+ var obj = { ...docP };
7588
7638
  obj.date = await func.utils.get_dateTime(SESSION_ID, 'SYS_DATE', docP.date);
7589
7639
  obj.time = await func.utils.get_dateTime(SESSION_ID, 'SYS_TIME', docP.date);
7590
7640
 
@@ -7699,7 +7749,7 @@ func.events.validate = async function (SESSION_ID, triggerP, dsSessionP, eventId
7699
7749
 
7700
7750
  let value = await func.common.get_cast_val(SESSION_ID, 'events', fieldId, field_info.props.fieldType, args[fieldId].value);
7701
7751
 
7702
- if (!_.isEmpty(args[fieldId].fx)) {
7752
+ if (!xu_isEmpty(args[fieldId].fx)) {
7703
7753
  const fx_ret = await func.expression.get(SESSION_ID, args[fieldId].fx, dsSessionP, 'update');
7704
7754
  value = fx_ret.result;
7705
7755
  }
@@ -7721,7 +7771,7 @@ func.events.validate = async function (SESSION_ID, triggerP, dsSessionP, eventId
7721
7771
  if (_event.workflow) {
7722
7772
  // check if event property exist
7723
7773
 
7724
- if (!_event.workflow || _.isEmpty(_event.workflow)) return;
7774
+ if (!_event.workflow || xu_isEmpty(_event.workflow)) return;
7725
7775
  // check events has rows
7726
7776
  for (const trigger_obj of _event.workflow) {
7727
7777
  //run events rows
@@ -7940,12 +7990,12 @@ func.events.find_job_index = function (SESSION_ID, jobNoP) {
7940
7990
  var _session = SESSION_OBJ[SESSION_ID];
7941
7991
  var ret = null;
7942
7992
  if (!_session.WORKER_OBJ) return ret;
7943
- _.forEach(_session.WORKER_OBJ.jobs, function (val, key) {
7993
+ for (const [key, val] of Object.entries(_session.WORKER_OBJ.jobs)) {
7944
7994
  if (val && val.job_num == jobNoP) {
7945
7995
  ret = key;
7946
- return false;
7996
+ break;
7947
7997
  }
7948
- });
7998
+ }
7949
7999
  return ret;
7950
8000
  };
7951
8001
  func.events.execute = async function (
@@ -8218,7 +8268,7 @@ func.events.execute = async function (
8218
8268
  var _session = SESSION_OBJ[SESSION_ID];
8219
8269
 
8220
8270
  const set_SYS_GLOBAL_OBJ_WIDGET_INFO = async function (docP) {
8221
- var obj = _.clone(docP);
8271
+ var obj = { ...docP };
8222
8272
  obj.date = await func.utils.get_dateTime(SESSION_ID, 'SYS_DATE', docP.date);
8223
8273
  obj.time = await func.utils.get_dateTime(SESSION_ID, 'SYS_TIME', docP.date);
8224
8274
 
@@ -8505,7 +8555,7 @@ func.events.execute = async function (
8505
8555
 
8506
8556
  let _ds_new = _session.DS_GLB[ret.dsSessionP];
8507
8557
  let parameters = args?.calling_trigger_prop?.data?.name?.parameters;
8508
- if (parameters && !_.isEmpty(parameters)) {
8558
+ if (parameters && !xu_isEmpty(parameters)) {
8509
8559
  await func.datasource.update_changes_for_out_parameter(SESSION_ID, _ds_new.dsSession, _ds.dsSession);
8510
8560
  }
8511
8561
 
@@ -8524,7 +8574,7 @@ func.events.execute = async function (
8524
8574
  },
8525
8575
  update: async function () {
8526
8576
  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 || _.isEmpty(obj_values_to_update)) {
8577
+ if (!obj_values_to_update || xu_isEmpty(obj_values_to_update)) {
8528
8578
  func.utils.debug_report(SESSION_ID, 'Update values object is empty', '', 'W');
8529
8579
  if (jobNoP) func.events.delete_job(SESSION_ID, jobNoP);
8530
8580
  return;
@@ -8716,11 +8766,11 @@ func.events.execute = async function (
8716
8766
  if (error) {
8717
8767
  return func.utils.debug_report(SESSION_ID, msg, '', 'W');
8718
8768
  }
8719
- func.utils.debug_report(SESSION_ID, msg + ' ' + _.capitalize(source) + prog_info, '', 'E');
8769
+ func.utils.debug_report(SESSION_ID, msg + ' ' + (source.charAt(0).toUpperCase() + source.slice(1).toLowerCase()) + prog_info, '', 'E');
8720
8770
  };
8721
8771
  const report_conversion_warn = function (res) {
8722
8772
  var msg = `${elementP} >${triggerP} >${functionP} > type mismatch auto conversion from value ${valP} to ${typeP}`;
8723
- func.utils.debug_report(SESSION_ID, msg + ' ' + _.capitalize(source) + prog_info, '', 'W');
8773
+ func.utils.debug_report(SESSION_ID, msg + ' ' + (source.charAt(0).toUpperCase() + source.slice(1).toLowerCase()) + prog_info, '', 'W');
8724
8774
  };
8725
8775
  // var ret = valP;
8726
8776
  if (error) {
@@ -8735,8 +8785,7 @@ func.events.execute = async function (
8735
8785
  // report_conversion_warn
8736
8786
  // );
8737
8787
 
8738
- var payload = _.reduce(
8739
- payload_arr,
8788
+ var payload = payload_arr.reduce(
8740
8789
  (ret, val, key) => {
8741
8790
  ret[val.key] = module.cast(val.type, val.val, report_conversion_error, report_conversion_warn);
8742
8791
 
@@ -8853,12 +8902,12 @@ func.events.check_jobs_idle = async function (SESSION_ID, jobsP) {
8853
8902
  var listener = setInterval(function () {
8854
8903
  var found;
8855
8904
  for (const [key, val] of Object.entries(jobsP)) {
8856
- _.forEach(_session.WORKER_OBJ.jobs, function (val2, key2) {
8905
+ for (const [key2, val2] of Object.entries(_session.WORKER_OBJ.jobs)) {
8857
8906
  if (key2 === val) {
8858
8907
  found = true;
8859
- return false;
8908
+ break;
8860
8909
  }
8861
- });
8910
+ }
8862
8911
  }
8863
8912
  if (!found) {
8864
8913
  do_callback();
@@ -8927,7 +8976,7 @@ func.events.invoke = async function (event_id) {
8927
8976
  var ds;
8928
8977
  for await (const [ds_key, val] of Object.entries(_session.DS_GLB)) {
8929
8978
  const _view_obj = await func.utils.VIEWS_OBJ.get(SESSION_ID, val.prog_id);
8930
- if (_.isEmpty(_view_obj.progEvents)) continue;
8979
+ if (xu_isEmpty(_view_obj.progEvents)) continue;
8931
8980
  if (ds) break;
8932
8981
  for await (const [key, val] of Object.entries(_view_obj.progEvents)) {
8933
8982
  if (val?.data?.type === 'user_defined' && val.data.event_name === event_id) {
@@ -8984,7 +9033,7 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
8984
9033
  }
8985
9034
  }
8986
9035
 
8987
- ret = ret.replace(/\&amp;/g, '&');
9036
+ if (ret.includes('&amp;')) ret = ret.replace(/\&amp;/g, '&');
8988
9037
  ret = func.utils.replace_studio_drive_url(SESSION_ID, ret);
8989
9038
 
8990
9039
  const end_results = function () {
@@ -9048,13 +9097,13 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
9048
9097
  const variable_not_exist = async function () {
9049
9098
  try {
9050
9099
  if (sourceP !== 'arguments') {
9051
- if (ret && ret.substr(0, 6) === '_DATE_') {
9052
- ret = ret.substr(6);
9100
+ if (ret && ret.startsWith('_DATE_')) {
9101
+ ret = ret.slice(6);
9053
9102
  } else if (
9054
- (ret && ret.length === 10 && ret.substr(4, 1) === '-' && ret.substr(7, 1) === '-') ||
9055
- ret === 'self' // bypass eval for date 2017-03-22
9103
+ ret === 'self' || // bypass eval for 'self'
9104
+ (ret && ret.length === 10 && ret[4] === '-' && ret[7] === '-') // bypass eval for date 2017-03-22
9056
9105
  ) {
9057
- ret = ret;
9106
+ // date or 'self' — skip eval, return as-is
9058
9107
  } else {
9059
9108
  ret = await func.expression.secure_eval(SESSION_ID, sourceP, ret, jobNo, dsSessionP, js_script_callback);
9060
9109
  }
@@ -9074,13 +9123,8 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
9074
9123
  return await variable_not_exist();
9075
9124
  }
9076
9125
 
9077
- const validate_email = async function () {
9078
- const ret = await func.expression.secure_eval(SESSION_ID, sourceP, valP, jobNo, dsSessionP, js_script_callback, null, true);
9079
-
9080
- return glb.emailRegex.test(ret);
9081
- };
9082
-
9083
- if (await validate_email()) {
9126
+ // Fast-path: test raw string for email pattern before expensive eval
9127
+ if (glb.emailRegex.test(valP)) {
9084
9128
  return await variable_not_exist();
9085
9129
  }
9086
9130
 
@@ -9088,8 +9132,10 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
9088
9132
  var var_Arr = [];
9089
9133
  const split = func.expression.parse(ret) || [];
9090
9134
  // console.log(valP, split);
9091
- for await (const [arr_key, val] of Object.entries(split)) {
9135
+ const split_entries = Object.entries(split);
9136
+ for (let entry_i = 0; entry_i < split_entries.length; entry_i++) {
9092
9137
  // run each field
9138
+ const [arr_key, val] = split_entries[entry_i];
9093
9139
  const key = Number(arr_key);
9094
9140
  var_Arr[key] = {};
9095
9141
  var_Arr[key].value = val.value;
@@ -9134,14 +9180,16 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
9134
9180
  var prevData = var_Arr[key - 1].value;
9135
9181
  var_Arr[key].value = prevData[data]; // @objB[@var]
9136
9182
  if (val.value.indexOf('.') > -1) {
9137
- property2 = await func.expression.get_property(val.value).property2; //val.value.substr(val.value.indexOf(".") + 1, val.value.length); // get .
9183
+ const props_split = await func.expression.get_property(val.value);
9184
+ property2 = props_split.property2;
9138
9185
  if (prevData[data]) set_value(prevData[data][property2]);
9139
9186
  // var_Arr[key].value = prevData[data][property2]; //@objB[@var].property
9140
9187
  }
9141
9188
  delete var_Arr[key - 1];
9142
9189
  } else {
9143
- property1 = await func.expression.get_property(val.value).property1;
9144
- property2 = await func.expression.get_property(val.value).property2;
9190
+ const props = await func.expression.get_property(val.value);
9191
+ property1 = props.property1;
9192
+ property2 = props.property2;
9145
9193
  if (property1) {
9146
9194
  var_Arr[key].value = data[property1]; // @var["value"] or @var.property
9147
9195
  if (property2) {
@@ -9189,7 +9237,7 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
9189
9237
  var exp_exist;
9190
9238
  var var_error_found;
9191
9239
  // merge arr values
9192
- _.forEach(var_Arr, function (val, key) {
9240
+ var_Arr.forEach(function (val, key) {
9193
9241
  if (sourceP === 'UI Property EXP') {
9194
9242
  let ret = func.utils.get_drive_url(SESSION_ID, val.value, true);
9195
9243
  if (ret.changed) {
@@ -9265,7 +9313,7 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
9265
9313
  if (exp.res) res = exp.res;
9266
9314
  // do second pass when exp exist
9267
9315
  else res = [exp.result];
9268
- fields = _.assignIn(exp.fields, fieldsP);
9316
+ fields = Object.assign(exp.fields, fieldsP);
9269
9317
  }
9270
9318
  var result = join(res);
9271
9319
 
@@ -9587,9 +9635,15 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
9587
9635
  // return res;
9588
9636
  // };
9589
9637
 
9638
+ func.expression._parse_cache = new Map();
9639
+
9590
9640
  func.expression.parse = function (input) {
9591
9641
  if (typeof input !== 'string') return [];
9592
9642
 
9643
+ if (func.expression._parse_cache.has(input)) {
9644
+ return func.expression._parse_cache.get(input).map(function (s) { return Object.assign({}, s); });
9645
+ }
9646
+
9593
9647
  const segments = [];
9594
9648
  let pos = 0;
9595
9649
 
@@ -9612,7 +9666,14 @@ func.expression.parse = function (input) {
9612
9666
  pos += part.length;
9613
9667
  }
9614
9668
 
9615
- return segments;
9669
+ // Evict oldest entry if cache exceeds limit
9670
+ if (func.expression._parse_cache.size >= 500) {
9671
+ const firstKey = func.expression._parse_cache.keys().next().value;
9672
+ func.expression._parse_cache.delete(firstKey);
9673
+ }
9674
+ func.expression._parse_cache.set(input, segments);
9675
+
9676
+ return segments.map(function (s) { return Object.assign({}, s); });
9616
9677
  };
9617
9678
 
9618
9679
  func.expression.get_property = async function (valP) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xuda.io/xuda-worker-bundle",
3
- "version": "1.3.2636",
3
+ "version": "1.3.2638",
4
4
  "description": "xuda framework",
5
5
  "main": "index.js",
6
6
  "scripts": {