@vortexm/vjt 0.1.18 → 0.1.19

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.
package/dist/index.js CHANGED
@@ -5130,7 +5130,7 @@ var ActionRuntime = class {
5130
5130
  this.getInlineActions = options.getInlineActions;
5131
5131
  this.isWidgetEnabled = options.isWidgetEnabled;
5132
5132
  }
5133
- async dispatchWidgetEvent(node, eventName, key, inputValue = null, pointer = null) {
5133
+ async dispatchWidgetEvent(node, eventName, key, inputValue = null, pointer = null, options = {}) {
5134
5134
  try {
5135
5135
  if ((eventName === "onClick" || eventName === "onUserValueChange" || eventName === "onEnter" || eventName === "onShiftEnter" || eventName === "onControlEnter") && !this.isWidgetEnabled(node, key)) {
5136
5136
  return;
@@ -5140,7 +5140,9 @@ var ActionRuntime = class {
5140
5140
  return;
5141
5141
  }
5142
5142
  await this.runActions(actions, inputValue, { currentValue: inputValue, pointer });
5143
- await this.rerenderRoot();
5143
+ if (options.rerender !== false) {
5144
+ await this.rerenderRoot();
5145
+ }
5144
5146
  } catch (error) {
5145
5147
  logRuntimeError("dispatchWidgetEvent", error, {
5146
5148
  eventName,
@@ -7910,7 +7912,6 @@ function samePath(left, right) {
7910
7912
  // src/lib/render.ts
7911
7913
  var DEFAULT_DATE_FORMAT = "dd.MM.yyyy";
7912
7914
  var MOBILE_RATIO_THRESHOLD = 1.15;
7913
- var SCROLL_END_DEBOUNCE_MS = 140;
7914
7915
  var globalErrorLoggingAttached = false;
7915
7916
  function escapeHtml(value) {
7916
7917
  return String(value).replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
@@ -8089,7 +8090,7 @@ var RuntimeRenderer = class {
8089
8090
  activeScrollAnimationFrameId = null;
8090
8091
  pendingCursorReference = null;
8091
8092
  pendingCursorFrameId = null;
8092
- scrollEndTimeoutIds = /* @__PURE__ */ new Map();
8093
+ scrollEventFrameIds = /* @__PURE__ */ new Map();
8093
8094
  constructor(description, options = {}) {
8094
8095
  this.description = deepClone(description);
8095
8096
  this.resourceManager = options.resourceManager ?? null;
@@ -8329,10 +8330,10 @@ var RuntimeRenderer = class {
8329
8330
  window.clearTimeout(timeoutId);
8330
8331
  }
8331
8332
  this.toastTimeoutIds.clear();
8332
- for (const timeoutId of this.scrollEndTimeoutIds.values()) {
8333
- window.clearTimeout(timeoutId);
8333
+ for (const frameId of this.scrollEventFrameIds.values()) {
8334
+ window.cancelAnimationFrame(frameId);
8334
8335
  }
8335
- this.scrollEndTimeoutIds.clear();
8336
+ this.scrollEventFrameIds.clear();
8336
8337
  this.voiceRuntime.dispose();
8337
8338
  };
8338
8339
  }
@@ -9522,7 +9523,7 @@ var RuntimeRenderer = class {
9522
9523
  }
9523
9524
  element.addEventListener("scroll", () => {
9524
9525
  this.syncScrollStateForElement(element, key);
9525
- this.scheduleScrollEndEvent(element, node, key);
9526
+ this.dispatchScrollEvent(element, node, key);
9526
9527
  }, { passive: true });
9527
9528
  }
9528
9529
  }
@@ -9844,7 +9845,6 @@ var RuntimeRenderer = class {
9844
9845
  if (typeof window === "undefined") {
9845
9846
  initialElement.scrollTop = Math.max(0, Math.min(targetTop, getMaxScrollTop(initialElement)));
9846
9847
  this.syncScrollStateForReference(reference, initialElement);
9847
- this.scheduleProgrammaticScrollEndForReference(reference);
9848
9848
  return;
9849
9849
  }
9850
9850
  if (this.activeScrollAnimationFrameId !== null) {
@@ -9857,7 +9857,6 @@ var RuntimeRenderer = class {
9857
9857
  if (Math.abs(delta) < 1) {
9858
9858
  initialElement.scrollTop = clampedTargetTop;
9859
9859
  this.syncScrollStateForReference(reference, initialElement);
9860
- this.scheduleProgrammaticScrollEndForReference(reference);
9861
9860
  return;
9862
9861
  }
9863
9862
  const durationMs = 300;
@@ -9879,7 +9878,6 @@ var RuntimeRenderer = class {
9879
9878
  } else {
9880
9879
  liveElement.scrollTop = liveTargetTop;
9881
9880
  this.syncScrollStateForReference(reference, liveElement);
9882
- this.scheduleProgrammaticScrollEndForReference(reference);
9883
9881
  this.activeScrollAnimationFrameId = null;
9884
9882
  }
9885
9883
  };
@@ -9975,40 +9973,91 @@ var RuntimeRenderer = class {
9975
9973
  state.isScrolledToTop = element.scrollTop <= 1;
9976
9974
  state.isScrolledToBottom = element.scrollTop >= maxScrollTop - 1;
9977
9975
  }
9978
- scheduleScrollEndEvent(element, node, key) {
9976
+ dispatchScrollEvent(element, node, key) {
9979
9977
  if (!node.events?.onScroll?.length || typeof window === "undefined") {
9980
9978
  return;
9981
9979
  }
9982
- const existingTimeoutId = this.scrollEndTimeoutIds.get(key);
9983
- if (existingTimeoutId !== void 0) {
9984
- window.clearTimeout(existingTimeoutId);
9980
+ const existingFrameId = this.scrollEventFrameIds.get(key);
9981
+ if (existingFrameId !== void 0) {
9982
+ return;
9985
9983
  }
9986
- const timeoutId = window.setTimeout(() => {
9987
- this.scrollEndTimeoutIds.delete(key);
9984
+ const frameId = window.requestAnimationFrame(() => {
9985
+ this.scrollEventFrameIds.delete(key);
9988
9986
  void this.actionRuntime.dispatchWidgetEvent(
9989
9987
  node,
9990
9988
  "onScroll",
9991
9989
  key,
9992
9990
  getActionInputValueForElement(element, node, this.stateByKey),
9993
- null
9994
- );
9995
- }, SCROLL_END_DEBOUNCE_MS);
9996
- this.scrollEndTimeoutIds.set(key, timeoutId);
9991
+ null,
9992
+ { rerender: false }
9993
+ ).then(() => {
9994
+ this.syncSimpleDomState();
9995
+ });
9996
+ });
9997
+ this.scrollEventFrameIds.set(key, frameId);
9997
9998
  }
9998
- scheduleProgrammaticScrollEndForReference(reference) {
9999
- const element = this.findScrollableWidgetElement(reference);
10000
- if (!(element instanceof HTMLElement)) {
10001
- return;
10002
- }
10003
- const key = element.dataset.widgetKey ?? reference.split(".")[0]?.trim() ?? "";
10004
- if (!key) {
9999
+ syncSimpleDomState() {
10000
+ if (!(this.root instanceof HTMLElement)) {
10005
10001
  return;
10006
10002
  }
10007
- const node = this.nodeByKey.get(key) ?? this.nodeById.get(key);
10008
- if (!node || !isScrollableWidgetNode(node)) {
10009
- return;
10003
+ for (const [key, node] of this.nodeByKey.entries()) {
10004
+ const state = this.stateByKey.get(key);
10005
+ if (!state) {
10006
+ continue;
10007
+ }
10008
+ const element = this.root.querySelector(`[data-widget-key="${CSS.escape(key)}"]`);
10009
+ if (!element) {
10010
+ continue;
10011
+ }
10012
+ switch (node.widget) {
10013
+ case "static-text": {
10014
+ const nextText = this.resolveTextValue(state.text ?? node.text, null);
10015
+ if (element.textContent !== nextText) {
10016
+ element.textContent = nextText;
10017
+ }
10018
+ break;
10019
+ }
10020
+ case "button": {
10021
+ if (element instanceof HTMLButtonElement) {
10022
+ const nextText = this.resolveTextValue(state.text ?? node.text, null);
10023
+ if (element.textContent !== nextText) {
10024
+ element.textContent = nextText;
10025
+ }
10026
+ element.disabled = !(state.enabled ?? normalizeBoolean(node.enabled, true));
10027
+ }
10028
+ break;
10029
+ }
10030
+ case "link": {
10031
+ if (element instanceof HTMLAnchorElement) {
10032
+ const nextText = this.resolveTextValue(state.text ?? node.text, null);
10033
+ if (element.textContent !== nextText) {
10034
+ element.textContent = nextText;
10035
+ }
10036
+ }
10037
+ break;
10038
+ }
10039
+ case "edit": {
10040
+ if (element instanceof HTMLInputElement) {
10041
+ const nextValue = this.resolveTextValue(state.text ?? node.text, null);
10042
+ if (element.value !== nextValue) {
10043
+ element.value = nextValue;
10044
+ }
10045
+ }
10046
+ break;
10047
+ }
10048
+ case "textarea": {
10049
+ if (element instanceof HTMLTextAreaElement) {
10050
+ const nextValue = this.resolveTextValue(state.text ?? node.text, null);
10051
+ if (element.value !== nextValue) {
10052
+ element.value = nextValue;
10053
+ }
10054
+ }
10055
+ break;
10056
+ }
10057
+ default:
10058
+ break;
10059
+ }
10010
10060
  }
10011
- this.scheduleScrollEndEvent(element, node, key);
10012
10061
  }
10013
10062
  toScrollableIndex(value) {
10014
10063
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -121,7 +121,9 @@ export declare class ActionRuntime {
121
121
  dispatchWidgetEvent(node: DescriptionNode, eventName: WidgetEventName, key: string, inputValue?: unknown, pointer?: {
122
122
  x: number;
123
123
  y: number;
124
- } | null): Promise<void>;
124
+ } | null, options?: {
125
+ rerender?: boolean;
126
+ }): Promise<void>;
125
127
  runActions(actions: ActionDefinition[], inputValue: unknown, context: ActionExecutionContext): Promise<unknown>;
126
128
  getInlineActionsForNode(node: DescriptionNode): ActionDefinition[] | undefined;
127
129
  private runSingleAction;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vortexm/vjt",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",