@xuda.io/runtime-bundle 1.0.1413 → 1.0.1414

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.
@@ -2187,7 +2187,7 @@ func.runtime.bind.build_datasource_changes = function (dsSessionP, currentRecord
2187
2187
  },
2188
2188
  };
2189
2189
  };
2190
- func.runtime.bind.resolve_field = async function (SESSION_ID, prog_id, dsSessionP, field_id) {
2190
+ func.runtime.bind.resolve_field = async function (SESSION_ID, prog_id, dsSessionP, field_id, iterate_info) {
2191
2191
  let _prog_id = prog_id;
2192
2192
  let _dsP = dsSessionP;
2193
2193
  let is_dynamic_field = false;
@@ -2203,7 +2203,20 @@ func.runtime.bind.resolve_field = async function (SESSION_ID, prog_id, dsSession
2203
2203
 
2204
2204
  if (['_FOR_VAL', '_FOR_KEY'].includes(field_id)) {
2205
2205
  is_dynamic_field = true;
2206
- field_prop = SESSION_OBJ[SESSION_ID]?.DS_GLB?.[_dsP]?.dynamic_fields?.[field_id];
2206
+ if (iterate_info && (iterate_info.iterator_val === field_id || iterate_info.iterator_key === field_id)) {
2207
+ const iter_value = iterate_info.iterator_val === field_id ? iterate_info._val : iterate_info._key;
2208
+ const toType = function (obj) {
2209
+ return {}.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
2210
+ };
2211
+ field_prop = {
2212
+ id: field_id,
2213
+ data: { type: 'virtual', field_id },
2214
+ props: { fieldType: typeof iter_value !== 'undefined' ? toType(iter_value) : 'string' },
2215
+ value: iter_value,
2216
+ };
2217
+ } else {
2218
+ field_prop = SESSION_OBJ[SESSION_ID]?.DS_GLB?.[_dsP]?.dynamic_fields?.[field_id];
2219
+ }
2207
2220
  } else {
2208
2221
  field_prop = await find_in_view(field_id, _prog_id);
2209
2222
  if (!field_prop) {
@@ -2287,7 +2300,7 @@ func.runtime.bind.update_reference_source_array = async function (options) {
2287
2300
  if (field_type === 'object' && options.val_is_reference_field) {
2288
2301
  let obj_item = new_arr[arr_idx];
2289
2302
  let e_exp = options.expression_value.replace(options.bind_field_id, 'obj_item');
2290
- eval(e_exp + (options.input_field_type === 'string' ? `="${options.value}"` : `=${options.value}`));
2303
+ eval(e_exp + `=${JSON.stringify(options.value)}`);
2291
2304
  new_arr[arr_idx] = obj_item;
2292
2305
  } else {
2293
2306
  new_arr[arr_idx] = options.value;
@@ -11214,7 +11227,6 @@ func.UI.worker.execute = async function (SESSION_ID, queue_obj) {
11214
11227
  const perf_end = func.runtime?.perf?.start?.(SESSION_ID, 'execute_xu_render_attributes');
11215
11228
  const live_context = fx.get_live_element_context(queue_obj.paramsP?.elem_key, queue_obj.elementP || queue_obj.paramsP?.elem_val?.$elm, queue_obj.paramsP);
11216
11229
  const _data = live_context.data;
11217
- console.log('[xu-render EXEC]', { attr_value: queue_obj.paramsP.attr_value, has_data: !!_data?.xuData?.paramsP, elem_key: queue_obj.paramsP?.elem_key, tagName: live_context.$elm?.[0]?.tagName, elm_length: live_context.$elm?.length });
11218
11230
  try {
11219
11231
  if (_data?.xuData?.paramsP) {
11220
11232
  const live_xu_data = _data.xuData;
@@ -12154,7 +12166,7 @@ func.runtime.ui.init_screen = async function (options) {
12154
12166
  $rootFrame.css('display', 'contents');
12155
12167
  }
12156
12168
 
12157
- func.UI.utils.indicator.screen.busy();
12169
+ if (!is_panelP) func.UI.utils.indicator.screen.busy();
12158
12170
 
12159
12171
  const ret = await func.datasource.create(
12160
12172
  SESSION_ID,
@@ -12170,7 +12182,7 @@ func.runtime.ui.init_screen = async function (options) {
12170
12182
  null,
12171
12183
  null,
12172
12184
  null,
12173
- null,
12185
+ is_panelP,
12174
12186
  parameters_obj_inP,
12175
12187
  );
12176
12188
 
@@ -12197,7 +12209,7 @@ func.runtime.ui.init_screen = async function (options) {
12197
12209
  if (!node.length) return console.warn('ui node empty');
12198
12210
  const ret_render_$container = await func.runtime.render.render_ui_tree(SESSION_ID, $rootFrame, node[0], null, params, jobNoP, null, null, null, null, null, $rootFrame);
12199
12211
 
12200
- func.UI.utils.indicator.screen.normal();
12212
+ if (!is_panelP) func.UI.utils.indicator.screen.normal();
12201
12213
 
12202
12214
  return await func.runtime.ui.screen_loading_done({
12203
12215
  SESSION_ID,
@@ -12722,6 +12734,7 @@ func.runtime.render = func.runtime.render || {};
12722
12734
  // Browser-only panel rendering helpers live here so generic view rendering can stay focused.
12723
12735
 
12724
12736
  func.runtime.ui.render_panel_node = async function (options) {
12737
+
12725
12738
  const $wrapper = $('<div>');
12726
12739
  const $div = await func.runtime.ui.create_container({
12727
12740
  SESSION_ID: options.SESSION_ID,
@@ -13295,7 +13308,7 @@ func.runtime.ui.normalize_refresh_field_reference = function (field_ref) {
13295
13308
 
13296
13309
  return [...normalized].filter(Boolean);
13297
13310
  };
13298
- func.runtime.ui.extract_expression_refresh_fields = function (elm_data, expression_text, without_var) {
13311
+ func.runtime.ui.extract_expression_refresh_fields = function (elm_data, expression_text, without_var, _visited) {
13299
13312
  const fields = new Set();
13300
13313
  if (!expression_text) {
13301
13314
  return fields;
@@ -13326,8 +13339,12 @@ func.runtime.ui.extract_expression_refresh_fields = function (elm_data, expressi
13326
13339
 
13327
13340
  const parameters_raw_obj = elm_data?.xuData?.paramsP?.parameters_raw_obj || {};
13328
13341
  const parameter_keys = Object.keys(parameters_raw_obj);
13342
+ const visited = _visited || new Set();
13329
13343
  for (let index = 0; index < parameter_keys.length; index++) {
13330
13344
  const param_key = parameter_keys[index];
13345
+ if (visited.has(param_key)) {
13346
+ continue;
13347
+ }
13331
13348
  const param_val = parameters_raw_obj[param_key];
13332
13349
  if (!param_val?.includes?.('@')) {
13333
13350
  continue;
@@ -13336,7 +13353,8 @@ func.runtime.ui.extract_expression_refresh_fields = function (elm_data, expressi
13336
13353
  if (!text.includes(param_token)) {
13337
13354
  continue;
13338
13355
  }
13339
- const nested_fields = func.runtime.ui.extract_expression_refresh_fields(elm_data, param_val, false);
13356
+ visited.add(param_key);
13357
+ const nested_fields = func.runtime.ui.extract_expression_refresh_fields(elm_data, param_val, false, visited);
13340
13358
  nested_fields.forEach(function (field_id) {
13341
13359
  add_field(field_id);
13342
13360
  });
@@ -16987,7 +17005,7 @@ func.runtime.render.handle_xu_bind = async function (options) {
16987
17005
  };
16988
17006
 
16989
17007
  try {
16990
- const bind_field = await func.runtime.bind.resolve_field(options.SESSION_ID, _prog_id, _dsP, bind_expression.split('.')[0]);
17008
+ const bind_field = await func.runtime.bind.resolve_field(options.SESSION_ID, _prog_id, _dsP, bind_expression.split('.')[0], xuData.iterate_info);
16991
17009
  bind_field_id = bind_field.bind_field_id;
16992
17010
  field_prop = bind_field.field_prop;
16993
17011
  is_dynamic_field = bind_field.is_dynamic_field;
@@ -17063,11 +17081,16 @@ func.runtime.render.handle_xu_bind = async function (options) {
17063
17081
  let value;
17064
17082
  try {
17065
17083
  if (val_is_reference_field) {
17066
- const resolved_value = await func.datasource.get_value(options.SESSION_ID, bind_field_id, _dsP, target_record_id);
17067
- if (resolved_value?.found) {
17068
- value = resolved_value.ret.value;
17084
+ const iter = xuData.iterate_info;
17085
+ if (iter && is_dynamic_field && (iter.iterator_val === bind_field_id || iter.iterator_key === bind_field_id)) {
17086
+ value = iter.iterator_val === bind_field_id ? iter._val : iter._key;
17069
17087
  } else {
17070
- value = func.runtime.bind.get_source_value(_ds, bind_field_id, is_dynamic_field);
17088
+ const resolved_value = await func.datasource.get_value(options.SESSION_ID, bind_field_id, _dsP, target_record_id);
17089
+ if (resolved_value?.found) {
17090
+ value = resolved_value.ret.value;
17091
+ } else {
17092
+ value = func.runtime.bind.get_source_value(_ds, bind_field_id, is_dynamic_field);
17093
+ }
17071
17094
  }
17072
17095
  value = func.runtime.bind.format_display_value($elm, field_prop, bind_field_id, bind_expression, value, input_field_type);
17073
17096
  } else {
@@ -17421,7 +17444,11 @@ func.runtime.render.handle_modern_xu_render = async function (options) {
17421
17444
  };
17422
17445
 
17423
17446
  const post_render = async function () {
17424
- const nodeP = func.runtime.ui.get_data(options.$container).xuData.node.children[options.keyP];
17447
+ const container_data = func.runtime.ui.get_data(options.$container);
17448
+ if (!container_data?.xuData?.node?.children?.[options.keyP]) {
17449
+ return;
17450
+ }
17451
+ const nodeP = container_data.xuData.node.children[options.keyP];
17425
17452
  nodeP.xu_render_made = value;
17426
17453
  if (value) {
17427
17454
  try {
@@ -17472,7 +17499,6 @@ func.runtime.render.handle_modern_xu_render = async function (options) {
17472
17499
  func.runtime.ui.remove(options.$elm);
17473
17500
  }
17474
17501
  } catch (error) {
17475
- console.error('[xu-render post_render ERROR]', error, { keyP: options.keyP, container_tag: options.$container?.[0]?.tagName, has_node: !!nodeP, xu_ui_id: func.runtime.ui.get_attr(options.$elm, 'xu-ui-id') });
17476
17502
  func.events.delete_job(options.SESSION_ID, options.jobNoP);
17477
17503
  }
17478
17504
  return;
@@ -2188,7 +2188,7 @@ func.runtime.bind.build_datasource_changes = function (dsSessionP, currentRecord
2188
2188
  },
2189
2189
  };
2190
2190
  };
2191
- func.runtime.bind.resolve_field = async function (SESSION_ID, prog_id, dsSessionP, field_id) {
2191
+ func.runtime.bind.resolve_field = async function (SESSION_ID, prog_id, dsSessionP, field_id, iterate_info) {
2192
2192
  let _prog_id = prog_id;
2193
2193
  let _dsP = dsSessionP;
2194
2194
  let is_dynamic_field = false;
@@ -2204,7 +2204,20 @@ func.runtime.bind.resolve_field = async function (SESSION_ID, prog_id, dsSession
2204
2204
 
2205
2205
  if (['_FOR_VAL', '_FOR_KEY'].includes(field_id)) {
2206
2206
  is_dynamic_field = true;
2207
- field_prop = SESSION_OBJ[SESSION_ID]?.DS_GLB?.[_dsP]?.dynamic_fields?.[field_id];
2207
+ if (iterate_info && (iterate_info.iterator_val === field_id || iterate_info.iterator_key === field_id)) {
2208
+ const iter_value = iterate_info.iterator_val === field_id ? iterate_info._val : iterate_info._key;
2209
+ const toType = function (obj) {
2210
+ return {}.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
2211
+ };
2212
+ field_prop = {
2213
+ id: field_id,
2214
+ data: { type: 'virtual', field_id },
2215
+ props: { fieldType: typeof iter_value !== 'undefined' ? toType(iter_value) : 'string' },
2216
+ value: iter_value,
2217
+ };
2218
+ } else {
2219
+ field_prop = SESSION_OBJ[SESSION_ID]?.DS_GLB?.[_dsP]?.dynamic_fields?.[field_id];
2220
+ }
2208
2221
  } else {
2209
2222
  field_prop = await find_in_view(field_id, _prog_id);
2210
2223
  if (!field_prop) {
@@ -2288,7 +2301,7 @@ func.runtime.bind.update_reference_source_array = async function (options) {
2288
2301
  if (field_type === 'object' && options.val_is_reference_field) {
2289
2302
  let obj_item = new_arr[arr_idx];
2290
2303
  let e_exp = options.expression_value.replace(options.bind_field_id, 'obj_item');
2291
- eval(e_exp + (options.input_field_type === 'string' ? `="${options.value}"` : `=${options.value}`));
2304
+ eval(e_exp + `=${JSON.stringify(options.value)}`);
2292
2305
  new_arr[arr_idx] = obj_item;
2293
2306
  } else {
2294
2307
  new_arr[arr_idx] = options.value;
@@ -11215,7 +11228,6 @@ func.UI.worker.execute = async function (SESSION_ID, queue_obj) {
11215
11228
  const perf_end = func.runtime?.perf?.start?.(SESSION_ID, 'execute_xu_render_attributes');
11216
11229
  const live_context = fx.get_live_element_context(queue_obj.paramsP?.elem_key, queue_obj.elementP || queue_obj.paramsP?.elem_val?.$elm, queue_obj.paramsP);
11217
11230
  const _data = live_context.data;
11218
- console.log('[xu-render EXEC]', { attr_value: queue_obj.paramsP.attr_value, has_data: !!_data?.xuData?.paramsP, elem_key: queue_obj.paramsP?.elem_key, tagName: live_context.$elm?.[0]?.tagName, elm_length: live_context.$elm?.length });
11219
11231
  try {
11220
11232
  if (_data?.xuData?.paramsP) {
11221
11233
  const live_xu_data = _data.xuData;
@@ -12155,7 +12167,7 @@ func.runtime.ui.init_screen = async function (options) {
12155
12167
  $rootFrame.css('display', 'contents');
12156
12168
  }
12157
12169
 
12158
- func.UI.utils.indicator.screen.busy();
12170
+ if (!is_panelP) func.UI.utils.indicator.screen.busy();
12159
12171
 
12160
12172
  const ret = await func.datasource.create(
12161
12173
  SESSION_ID,
@@ -12171,7 +12183,7 @@ func.runtime.ui.init_screen = async function (options) {
12171
12183
  null,
12172
12184
  null,
12173
12185
  null,
12174
- null,
12186
+ is_panelP,
12175
12187
  parameters_obj_inP,
12176
12188
  );
12177
12189
 
@@ -12198,7 +12210,7 @@ func.runtime.ui.init_screen = async function (options) {
12198
12210
  if (!node.length) return console.warn('ui node empty');
12199
12211
  const ret_render_$container = await func.runtime.render.render_ui_tree(SESSION_ID, $rootFrame, node[0], null, params, jobNoP, null, null, null, null, null, $rootFrame);
12200
12212
 
12201
- func.UI.utils.indicator.screen.normal();
12213
+ if (!is_panelP) func.UI.utils.indicator.screen.normal();
12202
12214
 
12203
12215
  return await func.runtime.ui.screen_loading_done({
12204
12216
  SESSION_ID,
@@ -12723,6 +12735,7 @@ func.runtime.render = func.runtime.render || {};
12723
12735
  // Browser-only panel rendering helpers live here so generic view rendering can stay focused.
12724
12736
 
12725
12737
  func.runtime.ui.render_panel_node = async function (options) {
12738
+
12726
12739
  const $wrapper = $('<div>');
12727
12740
  const $div = await func.runtime.ui.create_container({
12728
12741
  SESSION_ID: options.SESSION_ID,
@@ -13296,7 +13309,7 @@ func.runtime.ui.normalize_refresh_field_reference = function (field_ref) {
13296
13309
 
13297
13310
  return [...normalized].filter(Boolean);
13298
13311
  };
13299
- func.runtime.ui.extract_expression_refresh_fields = function (elm_data, expression_text, without_var) {
13312
+ func.runtime.ui.extract_expression_refresh_fields = function (elm_data, expression_text, without_var, _visited) {
13300
13313
  const fields = new Set();
13301
13314
  if (!expression_text) {
13302
13315
  return fields;
@@ -13327,8 +13340,12 @@ func.runtime.ui.extract_expression_refresh_fields = function (elm_data, expressi
13327
13340
 
13328
13341
  const parameters_raw_obj = elm_data?.xuData?.paramsP?.parameters_raw_obj || {};
13329
13342
  const parameter_keys = Object.keys(parameters_raw_obj);
13343
+ const visited = _visited || new Set();
13330
13344
  for (let index = 0; index < parameter_keys.length; index++) {
13331
13345
  const param_key = parameter_keys[index];
13346
+ if (visited.has(param_key)) {
13347
+ continue;
13348
+ }
13332
13349
  const param_val = parameters_raw_obj[param_key];
13333
13350
  if (!param_val?.includes?.('@')) {
13334
13351
  continue;
@@ -13337,7 +13354,8 @@ func.runtime.ui.extract_expression_refresh_fields = function (elm_data, expressi
13337
13354
  if (!text.includes(param_token)) {
13338
13355
  continue;
13339
13356
  }
13340
- const nested_fields = func.runtime.ui.extract_expression_refresh_fields(elm_data, param_val, false);
13357
+ visited.add(param_key);
13358
+ const nested_fields = func.runtime.ui.extract_expression_refresh_fields(elm_data, param_val, false, visited);
13341
13359
  nested_fields.forEach(function (field_id) {
13342
13360
  add_field(field_id);
13343
13361
  });
@@ -16988,7 +17006,7 @@ func.runtime.render.handle_xu_bind = async function (options) {
16988
17006
  };
16989
17007
 
16990
17008
  try {
16991
- const bind_field = await func.runtime.bind.resolve_field(options.SESSION_ID, _prog_id, _dsP, bind_expression.split('.')[0]);
17009
+ const bind_field = await func.runtime.bind.resolve_field(options.SESSION_ID, _prog_id, _dsP, bind_expression.split('.')[0], xuData.iterate_info);
16992
17010
  bind_field_id = bind_field.bind_field_id;
16993
17011
  field_prop = bind_field.field_prop;
16994
17012
  is_dynamic_field = bind_field.is_dynamic_field;
@@ -17064,11 +17082,16 @@ func.runtime.render.handle_xu_bind = async function (options) {
17064
17082
  let value;
17065
17083
  try {
17066
17084
  if (val_is_reference_field) {
17067
- const resolved_value = await func.datasource.get_value(options.SESSION_ID, bind_field_id, _dsP, target_record_id);
17068
- if (resolved_value?.found) {
17069
- value = resolved_value.ret.value;
17085
+ const iter = xuData.iterate_info;
17086
+ if (iter && is_dynamic_field && (iter.iterator_val === bind_field_id || iter.iterator_key === bind_field_id)) {
17087
+ value = iter.iterator_val === bind_field_id ? iter._val : iter._key;
17070
17088
  } else {
17071
- value = func.runtime.bind.get_source_value(_ds, bind_field_id, is_dynamic_field);
17089
+ const resolved_value = await func.datasource.get_value(options.SESSION_ID, bind_field_id, _dsP, target_record_id);
17090
+ if (resolved_value?.found) {
17091
+ value = resolved_value.ret.value;
17092
+ } else {
17093
+ value = func.runtime.bind.get_source_value(_ds, bind_field_id, is_dynamic_field);
17094
+ }
17072
17095
  }
17073
17096
  value = func.runtime.bind.format_display_value($elm, field_prop, bind_field_id, bind_expression, value, input_field_type);
17074
17097
  } else {
@@ -17422,7 +17445,11 @@ func.runtime.render.handle_modern_xu_render = async function (options) {
17422
17445
  };
17423
17446
 
17424
17447
  const post_render = async function () {
17425
- const nodeP = func.runtime.ui.get_data(options.$container).xuData.node.children[options.keyP];
17448
+ const container_data = func.runtime.ui.get_data(options.$container);
17449
+ if (!container_data?.xuData?.node?.children?.[options.keyP]) {
17450
+ return;
17451
+ }
17452
+ const nodeP = container_data.xuData.node.children[options.keyP];
17426
17453
  nodeP.xu_render_made = value;
17427
17454
  if (value) {
17428
17455
  try {
@@ -17473,7 +17500,6 @@ func.runtime.render.handle_modern_xu_render = async function (options) {
17473
17500
  func.runtime.ui.remove(options.$elm);
17474
17501
  }
17475
17502
  } catch (error) {
17476
- console.error('[xu-render post_render ERROR]', error, { keyP: options.keyP, container_tag: options.$container?.[0]?.tagName, has_node: !!nodeP, xu_ui_id: func.runtime.ui.get_attr(options.$elm, 'xu-ui-id') });
17477
17503
  func.events.delete_job(options.SESSION_ID, options.jobNoP);
17478
17504
  }
17479
17505
  return;