@xuda.io/xuda-worker-bundle 1.3.2636 → 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.
Files changed (2) hide show
  1. package/index.js +150 -88
  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);
@@ -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 _.endsWith(module, '.js') ? module.replace('.js', '.min.js') : module.replace('.mjs', '.min.mjs');
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 = _.get(SESSION_OBJ[SESSION_ID].DS_GLB[0], path);
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 _ !== 'undefined' ? _.cloneDeep(nodeP) : JSON.parse(JSON.stringify(nodeP));
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 = _.assignIn(
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 (!_.isEmpty(screenInfo.properties.progParams)) {
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
- _.set(_ds, _ds.watcher.path, _ds.watcher.newValue);
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 && !_.isEmpty(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 || _.isEmpty(_prog.progEvents)) return 0;
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 (_.isEmpty(event_obj.workflow)) continue;
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 (_.isEmpty(arr)) return;
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
- _.forEach(SESSION_OBJ[SESSION_ID].DS_GLB, function (val, key) {
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
- _.forEach(SESSION_OBJ[SESSION_ID].WORKER_OBJ.jobs, function (val, key) {
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
- _.set(_ds, field_id, value);
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 (!_.isEqual(_ds.data_feed.rows[row_idx][field_id], value)) {
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 && !_.isEmpty(client_datasource_changes)) {
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 && !_.isEmpty(server_datasource_changes)) {
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 = _.size(data.rows);
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 = _.cloneDeep(await func.utils.VIEWS_OBJ.get(SESSION_ID, args.prog_id));
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 + ' ' + _.capitalize(source) + prog_info, '', 'E');
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 + ' ' + _.capitalize(source) + prog_info, '', 'W');
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 (!_.isEmpty(data)) {
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] && _.isEmpty(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] = _.merge(DOCS_OBJ[_app_id][idP], view_ret);
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 = _.padStart(sysDate.getDate(), 2, '0');
5757
- var month = _.padStart(sysDate.getMonth() + 1, 2, '0');
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 = _.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');
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 = _.clone(_session.DS_GLB[DS]);
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) && _.isEmpty(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 (_.isEmpty(SESSION_OBJ)) return;
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(_.upperFirst(alert_type), title, message, buttons);
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 = _.assignIn(data, dataP);
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 = _.clone(docP);
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 (!_.isEmpty(args[fieldId].fx)) {
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 || _.isEmpty(_event.workflow)) return;
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
- _.forEach(_session.WORKER_OBJ.jobs, function (val, key) {
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
- return false;
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 = _.clone(docP);
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 && !_.isEmpty(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 || _.isEmpty(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 + ' ' + _.capitalize(source) + prog_info, '', 'E');
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 + ' ' + _.capitalize(source) + prog_info, '', 'W');
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 = _.reduce(
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
- _.forEach(_session.WORKER_OBJ.jobs, function (val2, key2) {
8906
+ for (const [key2, val2] of Object.entries(_session.WORKER_OBJ.jobs)) {
8857
8907
  if (key2 === val) {
8858
8908
  found = true;
8859
- return false;
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 (_.isEmpty(_view_obj.progEvents)) continue;
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(/\&amp;/g, '&');
9037
+ if (ret.includes('&amp;')) ret = ret.replace(/\&amp;/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.substr(0, 6) === '_DATE_') {
9052
- ret = ret.substr(6);
9101
+ if (ret && ret.startsWith('_DATE_')) {
9102
+ ret = ret.slice(6);
9053
9103
  } 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
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
- ret = ret;
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
- 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()) {
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
- for await (const [arr_key, val] of Object.entries(split)) {
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
- property2 = await func.expression.get_property(val.value).property2; //val.value.substr(val.value.indexOf(".") + 1, val.value.length); // get .
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
- property1 = await func.expression.get_property(val.value).property1;
9144
- property2 = await func.expression.get_property(val.value).property2;
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
- _.forEach(var_Arr, function (val, key) {
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 = _.assignIn(exp.fields, fieldsP);
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
- return segments;
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) {
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.2637",
4
4
  "description": "xuda framework",
5
5
  "main": "index.js",
6
6
  "scripts": {