@xuda.io/runtime-bundle 1.0.1430 → 1.0.1432

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.
@@ -17819,8 +17819,23 @@ func.runtime.render.handle_xu_bind = async function (options) {
17819
17819
  };
17820
17820
  func.runtime.render.apply_xu_class = async function (options) {
17821
17821
  try {
17822
- const classes_obj = typeof options.val.value === 'string' ? JSON.parse(options.val.value) : Object.assign({}, {}, options.val.value);
17822
+ const raw_value = options?.val?.value;
17823
17823
  const xuData = func.runtime.ui.get_data(options.$elm)?.xuData;
17824
+ if (typeof raw_value === 'string') {
17825
+ const trimmed = raw_value.trim();
17826
+ const looks_like_object = trimmed.startsWith('{') && trimmed.endsWith('}');
17827
+
17828
+ if (!looks_like_object) {
17829
+ func.runtime.render.apply_expression_class(options.$elm, raw_value);
17830
+ xuData.debug_info.attribute_stat['xu-class'] = func.runtime.ui.get_first_node(options.$elm)?.className || func.runtime.ui.get_attr(options.$elm, 'class');
17831
+ return {};
17832
+ }
17833
+ }
17834
+
17835
+ const classes_obj = typeof raw_value === 'string' ? JSON5.parse(raw_value) : Object.assign({}, {}, raw_value);
17836
+ if (typeof classes_obj !== 'object' || classes_obj === null || Array.isArray(classes_obj)) {
17837
+ throw new Error('xu-class expects an object map or a class string');
17838
+ }
17824
17839
  const class_names = Object.keys(classes_obj);
17825
17840
 
17826
17841
  for (let index = 0; index < class_names.length; index++) {
@@ -17849,7 +17864,18 @@ func.runtime.render.apply_xu_class = async function (options) {
17849
17864
  xuData.debug_info.attribute_stat['xu-class'] = func.runtime.ui.get_first_node(options.$elm)?.className || func.runtime.ui.get_attr(options.$elm, 'class');
17850
17865
  return {};
17851
17866
  } catch (e) {
17852
- console.warn('parse error:' + options.val.value);
17867
+ await func.runtime.render.report_xu_runtime_error(
17868
+ {
17869
+ ...options,
17870
+ xu_func: 'xu-class',
17871
+ val: {
17872
+ key: 'xu-class',
17873
+ value: options?.val?.value,
17874
+ },
17875
+ },
17876
+ e,
17877
+ 'xu-class has invalid syntax',
17878
+ );
17853
17879
  return { abort: true };
17854
17880
  }
17855
17881
  };
@@ -18530,14 +18556,43 @@ func.runtime.widgets = func.runtime.widgets || {};
18530
18556
  // Browser-only common xu handler factories live here so registry composition can stay small.
18531
18557
 
18532
18558
  func.runtime.render.build_base_xu_handlers = function (options, _ds) {
18559
+ const parse_object_value = function (attr_name, val, shape = 'object') {
18560
+ let parsed_value = val?.value;
18561
+ if (typeof parsed_value === 'string') {
18562
+ try {
18563
+ parsed_value = JSON5.parse(parsed_value);
18564
+ } catch (error) {
18565
+ throw func.runtime.render.build_xu_runtime_error(
18566
+ { ...options, xu_func: attr_name, val: { key: attr_name, value: val?.value } },
18567
+ error,
18568
+ `${attr_name} has invalid ${shape} syntax`,
18569
+ );
18570
+ }
18571
+ }
18572
+
18573
+ const valid =
18574
+ shape === 'array'
18575
+ ? Array.isArray(parsed_value)
18576
+ : typeof parsed_value === 'object' && parsed_value !== null && !Array.isArray(parsed_value);
18577
+
18578
+ if (!valid) {
18579
+ throw func.runtime.render.build_xu_runtime_error(
18580
+ { ...options, xu_func: attr_name, val: { key: attr_name, value: val?.value } },
18581
+ null,
18582
+ `${attr_name} expects a ${shape} value`,
18583
+ );
18584
+ }
18585
+
18586
+ return parsed_value;
18587
+ };
18533
18588
  return {
18534
18589
  'xu-attrs': async function ($elm, val) {
18535
18590
  if (!val.value) return {};
18536
- if (!(typeof val.value === 'object' && val.value !== null)) throw 'xu-attrs value us not an object';
18537
- const attr_keys = Object.keys(val.value);
18591
+ const attrs_obj = parse_object_value('xu-attrs', val, 'object');
18592
+ const attr_keys = Object.keys(attrs_obj);
18538
18593
  for (let index = 0; index < attr_keys.length; index++) {
18539
18594
  const attr_key = attr_keys[index];
18540
- options.nodeP.attributes[attr_key] = val.value[attr_key];
18595
+ options.nodeP.attributes[attr_key] = attrs_obj[attr_key];
18541
18596
  }
18542
18597
  return {};
18543
18598
  },
@@ -18657,7 +18712,7 @@ func.runtime.render.build_base_xu_handlers = function (options, _ds) {
18657
18712
  return {};
18658
18713
  },
18659
18714
  'xu-cdn': async function ($elm, val) {
18660
- const resources_obj = val.value || {};
18715
+ const resources_obj = parse_object_value('xu-cdn', val, 'object');
18661
18716
  const resource_keys = Object.keys(resources_obj);
18662
18717
  for (let index = 0; index < resource_keys.length; index++) {
18663
18718
  const resource = resources_obj[resource_keys[index]];
@@ -18666,7 +18721,7 @@ func.runtime.render.build_base_xu_handlers = function (options, _ds) {
18666
18721
  return {};
18667
18722
  },
18668
18723
  'xu-ui-plugin': async function ($elm, val) {
18669
- const plugins_obj = val.value || {};
18724
+ const plugins_obj = parse_object_value('xu-ui-plugin', val, 'object');
18670
18725
  const plugin_names = Object.keys(plugins_obj);
18671
18726
  for (let index = 0; index < plugin_names.length; index++) {
18672
18727
  const plugin_name = plugin_names[index];
@@ -18677,14 +18732,14 @@ func.runtime.render.build_base_xu_handlers = function (options, _ds) {
18677
18732
  },
18678
18733
  'xu-store': async function ($elm, val) {
18679
18734
  try {
18680
- const fields_obj = JSON5.parse(val.value);
18735
+ const fields_obj = parse_object_value('xu-store', val, 'object');
18681
18736
  const field_ids = Object.keys(fields_obj);
18682
18737
  for (let index = 0; index < field_ids.length; index++) {
18683
18738
  const field_id = field_ids[index];
18684
18739
  func.datasource.add_dynamic_field_to_ds(options.SESSION_ID, options.paramsP.dsSessionP, field_id, fields_obj[field_id]);
18685
18740
  }
18686
18741
  } catch (err) {
18687
- console.error(err);
18742
+ throw err;
18688
18743
  }
18689
18744
  return {};
18690
18745
  },
@@ -18807,6 +18862,36 @@ func.runtime.render = func.runtime.render || {};
18807
18862
  func.runtime.widgets = func.runtime.widgets || {};
18808
18863
 
18809
18864
  // Browser-only xu-attribute dispatch lives here so the attribute phase engine can stay focused.
18865
+ func.runtime.render.build_xu_runtime_error = function (options, error, fallback_message) {
18866
+ const raw_message = error?.message || error || fallback_message || 'Unknown runtime error';
18867
+ const err = error instanceof Error ? error : new Error(raw_message);
18868
+ err.xu_func = options?.xu_func;
18869
+ err.node_tag = options?.nodeP?.tagName;
18870
+ err.raw_value = options?.val?.value;
18871
+ err.ui_id = func.runtime?.ui?.get_attr ? func.runtime.ui.get_attr(options?.$elm, 'xu-ui-id') : null;
18872
+ return err;
18873
+ };
18874
+ func.runtime.render.report_xu_runtime_error = async function (options, error, fallback_message) {
18875
+ const err = func.runtime.render.build_xu_runtime_error(options, error, fallback_message);
18876
+ const attr_name = options?.val?.key || options?.xu_func || 'xu-*';
18877
+ const tag_name = options?.nodeP?.tagName || 'unknown';
18878
+ const raw_value = typeof err.raw_value === 'string' ? err.raw_value : JSON.stringify(err.raw_value);
18879
+ const message = [`${attr_name} failed on <${tag_name}>`, err.message];
18880
+
18881
+ if (raw_value) {
18882
+ message.push(`Value: ${raw_value}`);
18883
+ }
18884
+
18885
+ if (err.ui_id) {
18886
+ message.push(`xu-ui-id: ${err.ui_id}`);
18887
+ }
18888
+
18889
+ console.error('XUDA RUNTIME', message.join(' | '), err);
18890
+ if (func.utils?.debug_report) {
18891
+ await func.utils.debug_report(options?.SESSION_ID, 'Slim runtime', message.join(' | '), 'E', err);
18892
+ }
18893
+ return {};
18894
+ };
18810
18895
  func.runtime.render.execute_xu_function = async function (options) {
18811
18896
  if (options.is_skeleton) return;
18812
18897
 
@@ -18838,13 +18923,13 @@ func.runtime.render.execute_xu_function = async function (options) {
18838
18923
 
18839
18924
  try {
18840
18925
  if (!common_fx[options.xu_func]) {
18841
- console.warn('invalid xu-tag', options.xu_func);
18926
+ await func.runtime.render.report_xu_runtime_error(options, null, `Unknown xu directive: ${options.xu_func}`);
18842
18927
  return {};
18843
18928
  }
18844
18929
 
18845
18930
  return await common_fx[options.xu_func](options.$elm, options.val);
18846
18931
  } catch (error) {
18847
- debugger;
18932
+ return await func.runtime.render.report_xu_runtime_error(options, error);
18848
18933
  }
18849
18934
  };
18850
18935
  func.events = {};
@@ -17745,8 +17745,23 @@ func.runtime.render.handle_xu_bind = async function (options) {
17745
17745
  };
17746
17746
  func.runtime.render.apply_xu_class = async function (options) {
17747
17747
  try {
17748
- const classes_obj = typeof options.val.value === 'string' ? JSON.parse(options.val.value) : Object.assign({}, {}, options.val.value);
17748
+ const raw_value = options?.val?.value;
17749
17749
  const xuData = func.runtime.ui.get_data(options.$elm)?.xuData;
17750
+ if (typeof raw_value === 'string') {
17751
+ const trimmed = raw_value.trim();
17752
+ const looks_like_object = trimmed.startsWith('{') && trimmed.endsWith('}');
17753
+
17754
+ if (!looks_like_object) {
17755
+ func.runtime.render.apply_expression_class(options.$elm, raw_value);
17756
+ xuData.debug_info.attribute_stat['xu-class'] = func.runtime.ui.get_first_node(options.$elm)?.className || func.runtime.ui.get_attr(options.$elm, 'class');
17757
+ return {};
17758
+ }
17759
+ }
17760
+
17761
+ const classes_obj = typeof raw_value === 'string' ? JSON5.parse(raw_value) : Object.assign({}, {}, raw_value);
17762
+ if (typeof classes_obj !== 'object' || classes_obj === null || Array.isArray(classes_obj)) {
17763
+ throw new Error('xu-class expects an object map or a class string');
17764
+ }
17750
17765
  const class_names = Object.keys(classes_obj);
17751
17766
 
17752
17767
  for (let index = 0; index < class_names.length; index++) {
@@ -17775,7 +17790,18 @@ func.runtime.render.apply_xu_class = async function (options) {
17775
17790
  xuData.debug_info.attribute_stat['xu-class'] = func.runtime.ui.get_first_node(options.$elm)?.className || func.runtime.ui.get_attr(options.$elm, 'class');
17776
17791
  return {};
17777
17792
  } catch (e) {
17778
- console.warn('parse error:' + options.val.value);
17793
+ await func.runtime.render.report_xu_runtime_error(
17794
+ {
17795
+ ...options,
17796
+ xu_func: 'xu-class',
17797
+ val: {
17798
+ key: 'xu-class',
17799
+ value: options?.val?.value,
17800
+ },
17801
+ },
17802
+ e,
17803
+ 'xu-class has invalid syntax',
17804
+ );
17779
17805
  return { abort: true };
17780
17806
  }
17781
17807
  };
@@ -18456,14 +18482,43 @@ func.runtime.widgets = func.runtime.widgets || {};
18456
18482
  // Browser-only common xu handler factories live here so registry composition can stay small.
18457
18483
 
18458
18484
  func.runtime.render.build_base_xu_handlers = function (options, _ds) {
18485
+ const parse_object_value = function (attr_name, val, shape = 'object') {
18486
+ let parsed_value = val?.value;
18487
+ if (typeof parsed_value === 'string') {
18488
+ try {
18489
+ parsed_value = JSON5.parse(parsed_value);
18490
+ } catch (error) {
18491
+ throw func.runtime.render.build_xu_runtime_error(
18492
+ { ...options, xu_func: attr_name, val: { key: attr_name, value: val?.value } },
18493
+ error,
18494
+ `${attr_name} has invalid ${shape} syntax`,
18495
+ );
18496
+ }
18497
+ }
18498
+
18499
+ const valid =
18500
+ shape === 'array'
18501
+ ? Array.isArray(parsed_value)
18502
+ : typeof parsed_value === 'object' && parsed_value !== null && !Array.isArray(parsed_value);
18503
+
18504
+ if (!valid) {
18505
+ throw func.runtime.render.build_xu_runtime_error(
18506
+ { ...options, xu_func: attr_name, val: { key: attr_name, value: val?.value } },
18507
+ null,
18508
+ `${attr_name} expects a ${shape} value`,
18509
+ );
18510
+ }
18511
+
18512
+ return parsed_value;
18513
+ };
18459
18514
  return {
18460
18515
  'xu-attrs': async function ($elm, val) {
18461
18516
  if (!val.value) return {};
18462
- if (!(typeof val.value === 'object' && val.value !== null)) throw 'xu-attrs value us not an object';
18463
- const attr_keys = Object.keys(val.value);
18517
+ const attrs_obj = parse_object_value('xu-attrs', val, 'object');
18518
+ const attr_keys = Object.keys(attrs_obj);
18464
18519
  for (let index = 0; index < attr_keys.length; index++) {
18465
18520
  const attr_key = attr_keys[index];
18466
- options.nodeP.attributes[attr_key] = val.value[attr_key];
18521
+ options.nodeP.attributes[attr_key] = attrs_obj[attr_key];
18467
18522
  }
18468
18523
  return {};
18469
18524
  },
@@ -18583,7 +18638,7 @@ func.runtime.render.build_base_xu_handlers = function (options, _ds) {
18583
18638
  return {};
18584
18639
  },
18585
18640
  'xu-cdn': async function ($elm, val) {
18586
- const resources_obj = val.value || {};
18641
+ const resources_obj = parse_object_value('xu-cdn', val, 'object');
18587
18642
  const resource_keys = Object.keys(resources_obj);
18588
18643
  for (let index = 0; index < resource_keys.length; index++) {
18589
18644
  const resource = resources_obj[resource_keys[index]];
@@ -18592,7 +18647,7 @@ func.runtime.render.build_base_xu_handlers = function (options, _ds) {
18592
18647
  return {};
18593
18648
  },
18594
18649
  'xu-ui-plugin': async function ($elm, val) {
18595
- const plugins_obj = val.value || {};
18650
+ const plugins_obj = parse_object_value('xu-ui-plugin', val, 'object');
18596
18651
  const plugin_names = Object.keys(plugins_obj);
18597
18652
  for (let index = 0; index < plugin_names.length; index++) {
18598
18653
  const plugin_name = plugin_names[index];
@@ -18603,14 +18658,14 @@ func.runtime.render.build_base_xu_handlers = function (options, _ds) {
18603
18658
  },
18604
18659
  'xu-store': async function ($elm, val) {
18605
18660
  try {
18606
- const fields_obj = JSON5.parse(val.value);
18661
+ const fields_obj = parse_object_value('xu-store', val, 'object');
18607
18662
  const field_ids = Object.keys(fields_obj);
18608
18663
  for (let index = 0; index < field_ids.length; index++) {
18609
18664
  const field_id = field_ids[index];
18610
18665
  func.datasource.add_dynamic_field_to_ds(options.SESSION_ID, options.paramsP.dsSessionP, field_id, fields_obj[field_id]);
18611
18666
  }
18612
18667
  } catch (err) {
18613
- console.error(err);
18668
+ throw err;
18614
18669
  }
18615
18670
  return {};
18616
18671
  },
@@ -18733,6 +18788,36 @@ func.runtime.render = func.runtime.render || {};
18733
18788
  func.runtime.widgets = func.runtime.widgets || {};
18734
18789
 
18735
18790
  // Browser-only xu-attribute dispatch lives here so the attribute phase engine can stay focused.
18791
+ func.runtime.render.build_xu_runtime_error = function (options, error, fallback_message) {
18792
+ const raw_message = error?.message || error || fallback_message || 'Unknown runtime error';
18793
+ const err = error instanceof Error ? error : new Error(raw_message);
18794
+ err.xu_func = options?.xu_func;
18795
+ err.node_tag = options?.nodeP?.tagName;
18796
+ err.raw_value = options?.val?.value;
18797
+ err.ui_id = func.runtime?.ui?.get_attr ? func.runtime.ui.get_attr(options?.$elm, 'xu-ui-id') : null;
18798
+ return err;
18799
+ };
18800
+ func.runtime.render.report_xu_runtime_error = async function (options, error, fallback_message) {
18801
+ const err = func.runtime.render.build_xu_runtime_error(options, error, fallback_message);
18802
+ const attr_name = options?.val?.key || options?.xu_func || 'xu-*';
18803
+ const tag_name = options?.nodeP?.tagName || 'unknown';
18804
+ const raw_value = typeof err.raw_value === 'string' ? err.raw_value : JSON.stringify(err.raw_value);
18805
+ const message = [`${attr_name} failed on <${tag_name}>`, err.message];
18806
+
18807
+ if (raw_value) {
18808
+ message.push(`Value: ${raw_value}`);
18809
+ }
18810
+
18811
+ if (err.ui_id) {
18812
+ message.push(`xu-ui-id: ${err.ui_id}`);
18813
+ }
18814
+
18815
+ console.error('XUDA RUNTIME', message.join(' | '), err);
18816
+ if (func.utils?.debug_report) {
18817
+ await func.utils.debug_report(options?.SESSION_ID, 'Slim runtime', message.join(' | '), 'E', err);
18818
+ }
18819
+ return {};
18820
+ };
18736
18821
  func.runtime.render.execute_xu_function = async function (options) {
18737
18822
  if (options.is_skeleton) return;
18738
18823
 
@@ -18764,13 +18849,13 @@ func.runtime.render.execute_xu_function = async function (options) {
18764
18849
 
18765
18850
  try {
18766
18851
  if (!common_fx[options.xu_func]) {
18767
- console.warn('invalid xu-tag', options.xu_func);
18852
+ await func.runtime.render.report_xu_runtime_error(options, null, `Unknown xu directive: ${options.xu_func}`);
18768
18853
  return {};
18769
18854
  }
18770
18855
 
18771
18856
  return await common_fx[options.xu_func](options.$elm, options.val);
18772
18857
  } catch (error) {
18773
- debugger;
18858
+ return await func.runtime.render.report_xu_runtime_error(options, error);
18774
18859
  }
18775
18860
  };
18776
18861
  func.UI.screen = {};