@xuda.io/runtime-bundle 1.0.1249 → 1.0.1251

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.
@@ -24676,27 +24676,40 @@ func.common.get_data_from_websocket = async function (SESSION_ID, serviceP, data
24676
24676
  });
24677
24677
  };
24678
24678
 
24679
- func.common.sha256 = async function (inputString) {
24680
- // 1. Create a hash buffer from the input string using SHA-256.
24681
- // This part remains the same as it provides a strong, unique cryptographic starting point.
24682
- const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(inputString));
24683
-
24684
- // 2. Interpret the first 8 bytes (64 bits) of the hash as one big number.
24685
- const view = new DataView(buffer);
24686
- const bigInt = view.getBigUint64(0, false); // `false` for big-endian
24687
-
24688
- // 3. Convert the BigInt to a Base36 string.
24689
- // The .toString(36) method handles the conversion to an alphanumeric representation (0-9, a-z).
24690
- const base36Hash = bigInt.toString(36);
24691
-
24692
- // 4. Take the first 10 characters. If it's shorter, it will just return the whole string.
24693
- // For a 64-bit integer, the Base36 representation will be about 13 characters long,
24694
- // so slicing is a reliable way to get a fixed length.
24695
- const shortHash = base36Hash.slice(0, 10);
24696
-
24697
- // 5. Pad the start in the unlikely case the hash is shorter than 10 characters.
24698
- // This ensures the output is always exactly 10 characters long.
24699
- return shortHash.padStart(10, '0');
24679
+ // func.common.sha256 = async function (inputString) {
24680
+ // // 1. Create a hash buffer from the input string using SHA-256.
24681
+ // // This part remains the same as it provides a strong, unique cryptographic starting point.
24682
+ // const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(inputString));
24683
+
24684
+ // // 2. Interpret the first 8 bytes (64 bits) of the hash as one big number.
24685
+ // const view = new DataView(buffer);
24686
+ // const bigInt = view.getBigUint64(0, false); // `false` for big-endian
24687
+
24688
+ // // 3. Convert the BigInt to a Base36 string.
24689
+ // // The .toString(36) method handles the conversion to an alphanumeric representation (0-9, a-z).
24690
+ // const base36Hash = bigInt.toString(36);
24691
+
24692
+ // // 4. Take the first 10 characters. If it's shorter, it will just return the whole string.
24693
+ // // For a 64-bit integer, the Base36 representation will be about 13 characters long,
24694
+ // // so slicing is a reliable way to get a fixed length.
24695
+ // const shortHash = base36Hash.slice(0, 10);
24696
+
24697
+ // // 5. Pad the start in the unlikely case the hash is shorter than 10 characters.
24698
+ // // This ensures the output is always exactly 10 characters long.
24699
+ // return shortHash.padStart(10, '0');
24700
+ // };
24701
+
24702
+ func.common.fastHash = function (inputString) {
24703
+ let hash = 0x811c9dc5; // FNV offset basis
24704
+
24705
+ for (let i = 0; i < inputString.length; i++) {
24706
+ hash ^= inputString.charCodeAt(i);
24707
+ // FNV prime multiplication with 32-bit overflow
24708
+ hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
24709
+ }
24710
+
24711
+ // Convert to base36 and pad to 10 characters
24712
+ return ((hash >>> 0).toString(36) + '0000000000').slice(0, 10);
24700
24713
  };
24701
24714
 
24702
24715
  glb.new_xu_render = false;
@@ -34482,162 +34495,312 @@ func.UI.screen.panel_post_render_handler = async function (
34482
34495
  return jobNoP;
34483
34496
  };
34484
34497
 
34498
+ // const generate_xu_ui_id = async function (SESSION_ID, nodeP, $container, paramsP, keyP) {
34499
+ // // const _paramsP = _.cloneDeep(paramsP);
34500
+ // const _paramsP = klona.klona(paramsP);
34501
+ // var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
34502
+
34503
+ // const currentRecordId = $container?.data?.()?.xuData?.recordid || (_ds ? _ds.currentRecordId : '');
34504
+ // const key_path = `${$container?.data()?.xuData?.key_path || '0'}-${keyP || '0'}`;
34505
+ // const elem_key = `${nodeP.xu_tree_id || nodeP.id}-${key_path}-${currentRecordId}`;
34506
+ // let ui_id = `${nodeP.id}-${elem_key}-${_paramsP?.dsSessionP?.toString() || ''}`; //nodeP.xu_tree_id ||
34507
+
34508
+ // const new_ui_id = await func.common.sha256(ui_id);
34509
+ // return new_ui_id;
34510
+ // };
34511
+
34485
34512
  const generate_xu_ui_id = async function (SESSION_ID, nodeP, $container, paramsP, keyP) {
34486
- // const _paramsP = _.cloneDeep(paramsP);
34487
- const _paramsP = klona.klona(paramsP);
34488
- var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
34513
+ // Avoid cloning if we only need dsSessionP
34514
+ const dsSessionP = paramsP.dsSessionP;
34515
+ const _ds = SESSION_OBJ[SESSION_ID].DS_GLB[dsSessionP];
34516
+
34517
+ // Cache container data access
34518
+ const containerXuData = $container?.data?.()?.xuData;
34519
+ const currentRecordId = containerXuData?.recordid || _ds?.currentRecordId || '';
34489
34520
 
34490
- const currentRecordId = $container?.data?.()?.xuData?.recordid || (_ds ? _ds.currentRecordId : '');
34491
- const key_path = `${$container?.data()?.xuData?.key_path || '0'}-${keyP || '0'}`;
34492
- const elem_key = `${nodeP.xu_tree_id || nodeP.id}-${key_path}-${currentRecordId}`;
34493
- let ui_id = `${nodeP.id}-${elem_key}-${_paramsP?.dsSessionP?.toString() || ''}`; //nodeP.xu_tree_id ||
34521
+ // Build strings efficiently
34522
+ const key_path = `${containerXuData?.key_path || '0'}-${keyP || '0'}`;
34523
+ const nodeId = nodeP.xu_tree_id || nodeP.id;
34524
+ const elem_key = `${nodeId}-${key_path}-${currentRecordId}`;
34525
+ const ui_id = `${nodeP.id}-${elem_key}-${dsSessionP?.toString() || ''}`;
34494
34526
 
34495
- const new_ui_id = await func.common.sha256(ui_id);
34496
- return new_ui_id;
34527
+ return await func.common.fastHash(ui_id);
34497
34528
  };
34498
34529
 
34530
+ // func.UI.screen.create_container = async function (SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, classP, elem_propP, div_typeP, $appendToP, attr_str, is_placeholder) {
34531
+ // // const _paramsP = _.cloneDeep(paramsP);
34532
+ // const _paramsP = klona.klona(paramsP);
34533
+ // var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
34534
+ // var $appendTo = $container;
34535
+ // if ($appendToP) $appendTo = $appendToP;
34536
+ // if (!$appendTo || !$appendTo.length) return null; // screen closed or not exist abort build
34537
+ // var div = 'div';
34538
+ // if (div_typeP) div = div_typeP;
34539
+ // var items = [];
34540
+ // if (nodeP.children)
34541
+ // items = nodeP.children.map(function (val) {
34542
+ // return val.xu_tree_id || val.id;
34543
+ // });
34544
+ // var currentRecordId = $container?.data?.()?.xuData?.recordid || (_ds ? _ds.currentRecordId : '');
34545
+ // // var xu_id = (glb.screen_num++).toString();
34546
+ // // xu_id = xu_id += '_' + currentRecordId;
34547
+
34548
+ // try {
34549
+ // const key_path = `${$container?.data()?.xuData?.key_path || '0'}-${keyP || '0'}`;
34550
+ // const elem_key = `${nodeP.xu_tree_id || nodeP.id}-${key_path}-${currentRecordId}`;
34551
+ // // let ui_id = `${nodeP.id}-${elem_key}-${_paramsP?.dsSessionP?.toString() || ''}`; //nodeP.xu_tree_id ||
34552
+
34553
+ // /////////////////////////////////
34554
+
34555
+ // var $div;
34556
+
34557
+ // if (div === 'svg') {
34558
+ // const draw_svg = function (element) {
34559
+ // const get_tag_str = function (element, prop, val) {
34560
+ // let class_str = '';
34561
+ // let attr_str = '';
34562
+ // for (const [key, val] of Object.entries(prop)) {
34563
+ // if (key.substr(0, 2) !== 'xu') {
34564
+ // attr_str += ` ${key}="${val}" `;
34565
+ // }
34566
+ // }
34567
+ // if (element === 'svg') {
34568
+ // return `<${element} ${attr_str} > `;
34569
+ // }
34570
+ // let ret = '';
34571
+ // if (val?.children?.length) {
34572
+ // ret = iterate_svg(val);
34573
+ // }
34574
+
34575
+ // return `<${element} ${class_str} ${attr_str} > ${ret} </${element}>`;
34576
+ // };
34577
+ // let svg_str = get_tag_str(element, prop);
34578
+ // let inner_str = '';
34579
+ // const iterate_svg = function (node) {
34580
+ // let ret = '';
34581
+ // if (node.children) {
34582
+ // for (let val of node.children) {
34583
+ // let prop = val.attributes;
34584
+ // ret += get_tag_str(val.tagName, prop, val);
34585
+ // }
34586
+ // }
34587
+ // return ret;
34588
+ // };
34589
+ // inner_str = iterate_svg(nodeP);
34590
+
34591
+ // $div = $(svg_str + inner_str + '</svg>').appendTo($appendTo);
34592
+ // };
34593
+
34594
+ // draw_svg(div_typeP);
34595
+ // } else {
34596
+ // $div = $(`<${div} ${attr_str ? attr_str : ''}>`);
34597
+ // }
34598
+
34599
+ // // // Returns a 32-bit unsigned integer hash of a string (FNV-1a)
34600
+ // // function hash32(str) {
34601
+ // // let h = 0x811c9dc5; // FNV offset basis
34602
+ // // for (let i = 0; i < str.length; i++) {
34603
+ // // h ^= str.charCodeAt(i);
34604
+ // // // multiply by FNV prime (2^24 + 2^8 + 0x93) with 32-bit overflow
34605
+ // // h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
34606
+ // // }
34607
+ // // // Convert to unsigned 32-bit
34608
+ // // return h >>> 0;
34609
+ // // }
34610
+
34611
+ // // function hash32hex(str) {
34612
+ // // return (hash32(str) >>> 0).toString(16).padStart(8, '0');
34613
+ // // }
34614
+
34615
+ // // const new_ui_id = hash32hex(ui_id);
34616
+ // // const new_ui_id = await func.common.sha256(ui_id);
34617
+ // const new_ui_id = await generate_xu_ui_id(SESSION_ID, nodeP, $container, paramsP, keyP);
34618
+
34619
+ // $div
34620
+ // .attr('xu-ui-id', new_ui_id)
34621
+ // // .attr('xu-node-id', nodeP.id)
34622
+ // .data({
34623
+ // xuData: {
34624
+ // prog_id: _paramsP.prog_id,
34625
+ // nodeid: nodeP.id,
34626
+ // ui_type: nodeP.tagName,
34627
+ // // xu_id,
34628
+ // recordid: currentRecordId,
34629
+ // paramsP: _paramsP,
34630
+ // key: keyP,
34631
+ // key_path, //:($container?.data()?.xuData?.key || "0") + "-" + (keyP || "0"),
34632
+ // screenId: _paramsP.screenId,
34633
+ // parent_container: $container?.attr('id'),
34634
+ // elem_key,
34635
+ // properties: prop,
34636
+ // node: nodeP,
34637
+ // node_org: _.cloneDeep(nodeP),
34638
+ // is_panelP: _paramsP.is_panelP,
34639
+ // ui_id: new_ui_id,
34640
+ // elem_prop: elem_propP,
34641
+ // debug_info: {
34642
+ // id: nodeP.id,
34643
+ // parent_id: $container?.data()?.xuData?.ui_id,
34644
+ // items: items,
34645
+ // },
34646
+ // parent_node: parent_nodeP,
34647
+ // currentRecordId: currentRecordId,
34648
+ // $root_container: $root_container,
34649
+ // parent_element_ui_id: $container?.data()?.xuData?.ui_id,
34650
+ // },
34651
+ // xuAttributes: {},
34652
+ // });
34653
+ // if (is_placeholder) {
34654
+ // $div.addClass('display_none');
34655
+ // }
34656
+
34657
+ // if (div_typeP !== 'svg') {
34658
+ // $div.appendTo($appendTo);
34659
+ // }
34660
+ // } catch (e) {
34661
+ // console.error(e);
34662
+ // }
34663
+
34664
+ // if (parent_infoP?.iterate_info) {
34665
+ // $div.data().xuData.iterate_info = parent_infoP.iterate_info;
34666
+ // }
34667
+
34668
+ // if (classP) $div.addClass(classP);
34669
+
34670
+ // return $div;
34671
+ // };
34672
+
34499
34673
  func.UI.screen.create_container = async function (SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, classP, elem_propP, div_typeP, $appendToP, attr_str, is_placeholder) {
34500
- // const _paramsP = _.cloneDeep(paramsP);
34501
34674
  const _paramsP = klona.klona(paramsP);
34502
- var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
34503
- var $appendTo = $container;
34504
- if ($appendToP) $appendTo = $appendToP;
34505
- if (!$appendTo || !$appendTo.length) return null; // screen closed or not exist abort build
34506
- var div = 'div';
34507
- if (div_typeP) div = div_typeP;
34508
- var items = [];
34509
- if (nodeP.children)
34510
- items = nodeP.children.map(function (val) {
34511
- return val.xu_tree_id || val.id;
34512
- });
34513
- var currentRecordId = $container?.data?.()?.xuData?.recordid || (_ds ? _ds.currentRecordId : '');
34514
- // var xu_id = (glb.screen_num++).toString();
34515
- // xu_id = xu_id += '_' + currentRecordId;
34675
+ const _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
34676
+ const $appendTo = $appendToP || $container;
34677
+
34678
+ // Early exit if container doesn't exist
34679
+ if (!$appendTo?.length) return null;
34680
+
34681
+ const div = div_typeP || 'div';
34682
+
34683
+ // Cache container data to avoid repeated access
34684
+ const containerData = $container?.data?.();
34685
+ const containerXuData = containerData?.xuData;
34686
+ const currentRecordId = containerXuData?.recordid || (_ds ? _ds.currentRecordId : '');
34687
+
34688
+ // Pre-compute items array
34689
+ const items = nodeP.children ? nodeP.children.map((val) => val.xu_tree_id || val.id) : [];
34516
34690
 
34517
34691
  try {
34518
- const key_path = `${$container?.data()?.xuData?.key_path || '0'}-${keyP || '0'}`;
34692
+ const key_path = `${containerXuData?.key_path || '0'}-${keyP || '0'}`;
34519
34693
  const elem_key = `${nodeP.xu_tree_id || nodeP.id}-${key_path}-${currentRecordId}`;
34520
- // let ui_id = `${nodeP.id}-${elem_key}-${_paramsP?.dsSessionP?.toString() || ''}`; //nodeP.xu_tree_id ||
34521
34694
 
34522
- /////////////////////////////////
34523
-
34524
- var $div;
34695
+ let $div;
34525
34696
 
34697
+ // Handle SVG creation
34526
34698
  if (div === 'svg') {
34527
34699
  const draw_svg = function (element) {
34528
34700
  const get_tag_str = function (element, prop, val) {
34529
- let class_str = '';
34530
- let attr_str = '';
34531
- for (const [key, val] of Object.entries(prop)) {
34532
- if (key.substr(0, 2) !== 'xu') {
34533
- attr_str += ` ${key}="${val}" `;
34701
+ const attrs = [];
34702
+
34703
+ for (const [key, value] of Object.entries(prop)) {
34704
+ if (!key.startsWith('xu')) {
34705
+ attrs.push(`${key}="${value}"`);
34534
34706
  }
34535
34707
  }
34708
+
34709
+ const attr_str = attrs.join(' ');
34710
+
34536
34711
  if (element === 'svg') {
34537
- return `<${element} ${attr_str} > `;
34538
- }
34539
- let ret = '';
34540
- if (val?.children?.length) {
34541
- ret = iterate_svg(val);
34712
+ return `<${element} ${attr_str}>`;
34542
34713
  }
34543
34714
 
34544
- return `<${element} ${class_str} ${attr_str} > ${ret} </${element}>`;
34715
+ const inner = val?.children?.length ? iterate_svg(val) : '';
34716
+ return `<${element} ${attr_str}>${inner}</${element}>`;
34545
34717
  };
34546
- let svg_str = get_tag_str(element, prop);
34547
- let inner_str = '';
34718
+
34548
34719
  const iterate_svg = function (node) {
34549
- let ret = '';
34550
- if (node.children) {
34551
- for (let val of node.children) {
34552
- let prop = val.attributes;
34553
- ret += get_tag_str(val.tagName, prop, val);
34554
- }
34555
- }
34556
- return ret;
34720
+ if (!node.children) return '';
34721
+
34722
+ return node.children.map((val) => get_tag_str(val.tagName, val.attributes, val)).join('');
34557
34723
  };
34558
- inner_str = iterate_svg(nodeP);
34724
+
34725
+ const svg_str = get_tag_str(element, prop);
34726
+ const inner_str = iterate_svg(nodeP);
34559
34727
 
34560
34728
  $div = $(svg_str + inner_str + '</svg>').appendTo($appendTo);
34561
34729
  };
34562
34730
 
34563
34731
  draw_svg(div_typeP);
34564
34732
  } else {
34565
- $div = $(`<${div} ${attr_str ? attr_str : ''}>`);
34733
+ $div = $(`<${div}${attr_str ? ' ' + attr_str : ''}>`);
34566
34734
  }
34567
34735
 
34568
- // // Returns a 32-bit unsigned integer hash of a string (FNV-1a)
34569
- // function hash32(str) {
34570
- // let h = 0x811c9dc5; // FNV offset basis
34571
- // for (let i = 0; i < str.length; i++) {
34572
- // h ^= str.charCodeAt(i);
34573
- // // multiply by FNV prime (2^24 + 2^8 + 0x93) with 32-bit overflow
34574
- // h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
34575
- // }
34576
- // // Convert to unsigned 32-bit
34577
- // return h >>> 0;
34578
- // }
34736
+ // Generate UI ID
34737
+ const new_ui_id = await generate_xu_ui_id(SESSION_ID, nodeP, $container, paramsP, keyP);
34579
34738
 
34580
- // function hash32hex(str) {
34581
- // return (hash32(str) >>> 0).toString(16).padStart(8, '0');
34582
- // }
34739
+ // Set attributes and data in one go
34740
+ $div.attr('xu-ui-id', new_ui_id);
34741
+
34742
+ // Build xuData object efficiently
34743
+ const xuData = {
34744
+ prog_id: _paramsP.prog_id,
34745
+ nodeid: nodeP.id,
34746
+ ui_type: nodeP.tagName,
34747
+ recordid: currentRecordId,
34748
+ paramsP: _paramsP,
34749
+ key: keyP,
34750
+ key_path,
34751
+ screenId: _paramsP.screenId,
34752
+ parent_container: containerData?.id,
34753
+ elem_key,
34754
+ properties: prop,
34755
+ node: nodeP,
34756
+ node_org: _.cloneDeep(nodeP),
34757
+ is_panelP: _paramsP.is_panelP,
34758
+ ui_id: new_ui_id,
34759
+ elem_prop: elem_propP,
34760
+ debug_info: {
34761
+ id: nodeP.id,
34762
+ parent_id: containerXuData?.ui_id,
34763
+ items: items,
34764
+ },
34765
+ parent_node: parent_nodeP,
34766
+ currentRecordId: currentRecordId,
34767
+ $root_container: $root_container,
34768
+ parent_element_ui_id: containerXuData?.ui_id,
34769
+ };
34583
34770
 
34584
- // const new_ui_id = hash32hex(ui_id);
34585
- // const new_ui_id = await func.common.sha256(ui_id);
34586
- const new_ui_id = await generate_xu_ui_id(SESSION_ID, nodeP, $container, paramsP, keyP);
34771
+ // Add iterate_info if present
34772
+ if (parent_infoP?.iterate_info) {
34773
+ xuData.iterate_info = parent_infoP.iterate_info;
34774
+ }
34587
34775
 
34588
- $div
34589
- .attr('xu-ui-id', new_ui_id)
34590
- // .attr('xu-node-id', nodeP.id)
34591
- .data({
34592
- xuData: {
34593
- prog_id: _paramsP.prog_id,
34594
- nodeid: nodeP.id,
34595
- ui_type: nodeP.tagName,
34596
- // xu_id,
34597
- recordid: currentRecordId,
34598
- paramsP: _paramsP,
34599
- key: keyP,
34600
- key_path, //:($container?.data()?.xuData?.key || "0") + "-" + (keyP || "0"),
34601
- screenId: _paramsP.screenId,
34602
- parent_container: $container?.attr('id'),
34603
- elem_key,
34604
- properties: prop,
34605
- node: nodeP,
34606
- node_org: _.cloneDeep(nodeP),
34607
- is_panelP: _paramsP.is_panelP,
34608
- ui_id: new_ui_id,
34609
- elem_prop: elem_propP,
34610
- debug_info: {
34611
- id: nodeP.id,
34612
- parent_id: $container?.data()?.xuData?.ui_id,
34613
- items: items,
34614
- },
34615
- parent_node: parent_nodeP,
34616
- currentRecordId: currentRecordId,
34617
- $root_container: $root_container,
34618
- parent_element_ui_id: $container?.data()?.xuData?.ui_id,
34619
- },
34620
- xuAttributes: {},
34621
- });
34776
+ // Set data once
34777
+ $div.data({
34778
+ xuData: xuData,
34779
+ xuAttributes: {},
34780
+ });
34781
+
34782
+ // Apply placeholder class if needed
34622
34783
  if (is_placeholder) {
34623
34784
  $div.addClass('display_none');
34624
34785
  }
34625
34786
 
34787
+ // Apply custom class if provided
34788
+ if (classP) {
34789
+ $div.addClass(classP);
34790
+ }
34791
+
34792
+ // Append to DOM (only for non-SVG elements)
34626
34793
  if (div_typeP !== 'svg') {
34627
34794
  $div.appendTo($appendTo);
34628
34795
  }
34629
- } catch (e) {
34630
- console.error(e);
34631
- }
34632
34796
 
34633
- if (parent_infoP?.iterate_info) {
34634
- $div.data().xuData.iterate_info = parent_infoP.iterate_info;
34797
+ return $div;
34798
+ } catch (e) {
34799
+ console.error('create_container error:', e);
34800
+ return null;
34635
34801
  }
34636
-
34637
- if (classP) $div.addClass(classP);
34638
-
34639
- return $div;
34640
34802
  };
34803
+
34641
34804
  func.UI.screen.execute_screen_ready_events = async function (SESSION_ID, paramsP, sourceP, $div, jobNoP, $div_objP) {
34642
34805
  var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
34643
34806
  if (!_ds) return;