@aemforms/af-core 0.22.137 → 0.22.139

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.
@@ -205,6 +205,103 @@ const isRepeatable$1 = (obj) => {
205
205
  (obj.maxOccur !== undefined && obj.maxOccur !== 0))) || false);
206
206
  };
207
207
 
208
+ class PropertiesManager {
209
+ constructor(host) {
210
+ this.host = host;
211
+ this._definedProperties = new Set();
212
+ this._propertiesWrapper = {};
213
+ this._initialized = false;
214
+ }
215
+ get properties() {
216
+ if (!this._initialized) {
217
+ this._setupInitialProperties();
218
+ this._initialized = true;
219
+ }
220
+ return this._propertiesWrapper;
221
+ }
222
+ set properties(p) {
223
+ const oldProperties = this.host._jsonModel.properties || {};
224
+ const newProperties = { ...p };
225
+ this.host._jsonModel.properties = newProperties;
226
+ Object.keys(newProperties).forEach(prop => {
227
+ this._ensurePropertyDescriptor(prop);
228
+ });
229
+ Object.keys({ ...oldProperties, ...newProperties }).forEach(prop => {
230
+ if (oldProperties[prop] !== newProperties[prop]) {
231
+ const changeAction = propertyChange(`properties.${prop}`, newProperties[prop], oldProperties[prop]);
232
+ this.host.notifyDependents(changeAction);
233
+ }
234
+ });
235
+ }
236
+ ensurePropertyDescriptor(propertyName) {
237
+ this._ensurePropertyDescriptor(propertyName);
238
+ }
239
+ _setupInitialProperties() {
240
+ const properties = this.host._jsonModel.properties || {};
241
+ Object.keys(properties).forEach(prop => {
242
+ this._ensurePropertyDescriptor(prop);
243
+ });
244
+ if (!this.host._jsonModel.properties) {
245
+ this.host._jsonModel.properties = {};
246
+ }
247
+ }
248
+ _ensurePropertyDescriptor(prop) {
249
+ if (this._definedProperties.has(prop)) {
250
+ return;
251
+ }
252
+ Object.defineProperty(this._propertiesWrapper, prop, {
253
+ get: () => {
254
+ if (!prop.startsWith('fd:')) {
255
+ this.host.ruleEngine.trackDependency(this.host, `properties.${prop}`);
256
+ }
257
+ const properties = this.host._jsonModel.properties || {};
258
+ return properties[prop];
259
+ },
260
+ set: (value) => {
261
+ const properties = this.host._jsonModel.properties || {};
262
+ const oldValue = properties[prop];
263
+ if (oldValue !== value) {
264
+ const updatedProperties = { ...properties, [prop]: value };
265
+ this.host._jsonModel.properties = updatedProperties;
266
+ const changeAction = propertyChange(`properties.${prop}`, value, oldValue);
267
+ this.host.notifyDependents(changeAction);
268
+ }
269
+ },
270
+ enumerable: true,
271
+ configurable: true
272
+ });
273
+ this._definedProperties.add(prop);
274
+ }
275
+ updateNestedProperty(propertyPath, value) {
276
+ const parts = propertyPath.split('.');
277
+ const topLevelProp = parts[0];
278
+ this._ensurePropertyDescriptor(topLevelProp);
279
+ const properties = this.host._jsonModel.properties || {};
280
+ const updatedProperties = JSON.parse(JSON.stringify(properties));
281
+ const currentObj = updatedProperties[topLevelProp] || {};
282
+ updatedProperties[topLevelProp] = currentObj;
283
+ let parentObj = currentObj;
284
+ for (let i = 1; i < parts.length - 1; i++) {
285
+ if (!parentObj[parts[i]]) {
286
+ parentObj[parts[i]] = {};
287
+ } else if (typeof parentObj[parts[i]] !== 'object') {
288
+ parentObj[parts[i]] = {};
289
+ }
290
+ parentObj = parentObj[parts[i]];
291
+ }
292
+ const finalProp = parts[parts.length - 1];
293
+ const oldValue = parentObj[finalProp];
294
+ parentObj[finalProp] = value;
295
+ this.host._jsonModel.properties = updatedProperties;
296
+ const changeAction = propertyChange(`properties.${propertyPath}`, value, oldValue);
297
+ this.host.notifyDependents(changeAction);
298
+ }
299
+ updateSimpleProperty(propertyName, value) {
300
+ this._ensurePropertyDescriptor(propertyName);
301
+ this._propertiesWrapper[propertyName] = value;
302
+ }
303
+ }
304
+
208
305
  class DataValue {
209
306
  $_name;
210
307
  $_value;
@@ -1277,7 +1374,7 @@ function dependencyTracked() {
1277
1374
  const get = descriptor.get;
1278
1375
  if (get != undefined) {
1279
1376
  descriptor.get = function () {
1280
- this.ruleEngine.trackDependency(this);
1377
+ this.ruleEngine.trackDependency(this, propertyKey);
1281
1378
  return get.call(this);
1282
1379
  };
1283
1380
  }
@@ -1315,6 +1412,7 @@ class BaseNode {
1315
1412
  _eventSource = EventSource.CODE;
1316
1413
  _fragment = '$form';
1317
1414
  _idSet;
1415
+ _propertiesManager;
1318
1416
  createIdSet() {
1319
1417
  return new Set();
1320
1418
  }
@@ -1335,6 +1433,7 @@ class BaseNode {
1335
1433
  else if (this.parent?.fragment) {
1336
1434
  this._fragment = this.parent.fragment;
1337
1435
  }
1436
+ this._propertiesManager = new PropertiesManager(this);
1338
1437
  }
1339
1438
  get fragment() {
1340
1439
  return this._fragment;
@@ -1450,7 +1549,11 @@ class BaseNode {
1450
1549
  return this._jsonModel.label;
1451
1550
  }
1452
1551
  set label(l) {
1453
- if (l !== this._jsonModel.label) {
1552
+ const isLabelSame = (l !== null && this._jsonModel.label !== null &&
1553
+ typeof l === 'object' && typeof this._jsonModel.label === 'object') ?
1554
+ JSON.stringify(l) === JSON.stringify(this._jsonModel.label) :
1555
+ l === this._jsonModel.label;
1556
+ if (!isLabelSame) {
1454
1557
  const changeAction = propertyChange('label', l, this._jsonModel.label);
1455
1558
  this._jsonModel = {
1456
1559
  ...this._jsonModel,
@@ -1467,29 +1570,31 @@ class BaseNode {
1467
1570
  return !this._jsonModel.name && !isNonTransparent;
1468
1571
  }
1469
1572
  getDependents() {
1470
- return this._dependents.map(x => x.node.id);
1573
+ return this._dependents.map(x => ({ id: x.node.id, propertyName: x.propertyName }));
1471
1574
  }
1472
1575
  getState(forRestore = false) {
1473
- return {
1474
- ...this._jsonModel,
1475
- properties: this.properties,
1476
- index: this.index,
1477
- parent: undefined,
1478
- qualifiedName: this.qualifiedName,
1479
- ...(this.repeatable === true ? {
1480
- repeatable: true,
1481
- minOccur: this.parent.minItems,
1482
- maxOccur: this.parent.maxItems
1483
- } : {}),
1484
- ':type': this[':type'],
1485
- ...(forRestore ? {
1486
- _dependents: this._dependents.length ? this.getDependents() : undefined,
1487
- allowedComponents: undefined,
1488
- columnClassNames: undefined,
1489
- columnCount: undefined,
1490
- gridClassNames: undefined
1491
- } : {})
1492
- };
1576
+ return this.withDependencyTrackingControl(true, () => {
1577
+ return {
1578
+ ...this._jsonModel,
1579
+ properties: this.properties,
1580
+ index: this.index,
1581
+ parent: undefined,
1582
+ qualifiedName: this.qualifiedName,
1583
+ ...(this.repeatable === true ? {
1584
+ repeatable: true,
1585
+ minOccur: this.parent.minItems,
1586
+ maxOccur: this.parent.maxItems
1587
+ } : {}),
1588
+ ':type': this[':type'],
1589
+ ...(forRestore ? {
1590
+ _dependents: this._dependents.length ? this.getDependents() : undefined,
1591
+ allowedComponents: undefined,
1592
+ columnClassNames: undefined,
1593
+ columnCount: undefined,
1594
+ gridClassNames: undefined
1595
+ } : {})
1596
+ };
1597
+ });
1493
1598
  }
1494
1599
  subscribe(callback, eventName = 'change') {
1495
1600
  this._callbacks[eventName] = this._callbacks[eventName] || [];
@@ -1500,13 +1605,14 @@ class BaseNode {
1500
1605
  }
1501
1606
  };
1502
1607
  }
1503
- _addDependent(dependent) {
1608
+ _addDependent(dependent, propertyName) {
1504
1609
  if (this._dependents.find(({ node }) => node === dependent) === undefined) {
1505
1610
  const subscription = this.subscribe((change) => {
1506
1611
  const changes = change.payload.changes;
1507
1612
  const propsToLook = [...dynamicProps, 'items'];
1508
1613
  const isPropChanged = changes.findIndex(x => {
1509
- return propsToLook.indexOf(x.propertyName) > -1;
1614
+ const changedPropertyName = x.propertyName;
1615
+ return propsToLook.includes(changedPropertyName) || (changedPropertyName.startsWith('properties.') && propertyName === changedPropertyName);
1510
1616
  }) > -1;
1511
1617
  if (isPropChanged) {
1512
1618
  if (this.form.changeEventBehaviour === 'deps') {
@@ -1517,7 +1623,7 @@ class BaseNode {
1517
1623
  }
1518
1624
  }
1519
1625
  });
1520
- this._dependents.push({ node: dependent, subscription });
1626
+ this._dependents.push({ node: dependent, propertyName, subscription });
1521
1627
  }
1522
1628
  }
1523
1629
  removeDependent(dependent) {
@@ -1553,9 +1659,9 @@ class BaseNode {
1553
1659
  const depsToRestore = this._jsonModel._dependents;
1554
1660
  if (depsToRestore) {
1555
1661
  depsToRestore.forEach((x) => {
1556
- const node = this.form.getElement(x);
1662
+ const node = this.form.getElement(x.id);
1557
1663
  if (node) {
1558
- this._addDependent(node);
1664
+ this._addDependent(node, x.propertyName);
1559
1665
  }
1560
1666
  });
1561
1667
  this._jsonModel._dependents = undefined;
@@ -1682,10 +1788,13 @@ class BaseNode {
1682
1788
  return this._lang;
1683
1789
  }
1684
1790
  get properties() {
1685
- return this._jsonModel.properties || {};
1791
+ return this._propertiesManager.properties;
1686
1792
  }
1687
1793
  set properties(p) {
1688
- this._setProperty('properties', { ...p });
1794
+ this._propertiesManager.properties = p;
1795
+ }
1796
+ getPropertiesManager() {
1797
+ return this._propertiesManager;
1689
1798
  }
1690
1799
  getNonTransparentParent() {
1691
1800
  let nonTransparentParent = this.parent;
@@ -1776,9 +1885,6 @@ __decorate([
1776
1885
  __decorate([
1777
1886
  dependencyTracked()
1778
1887
  ], BaseNode.prototype, "label", null);
1779
- __decorate([
1780
- dependencyTracked()
1781
- ], BaseNode.prototype, "properties", null);
1782
1888
 
1783
1889
  class Scriptable extends BaseNode {
1784
1890
  _events = {};
@@ -2086,19 +2192,21 @@ class Container extends Scriptable {
2086
2192
  }
2087
2193
  }
2088
2194
  getState(isRepeatableChild = false, forRestore = false) {
2089
- return {
2090
- ...super.getState(forRestore),
2091
- ...(forRestore ? {
2092
- ':items': undefined,
2093
- ':itemsOrder': undefined
2094
- } : {}),
2095
- items: this.getItemsState(isRepeatableChild, forRestore),
2096
- ...((this._jsonModel.type === 'array' || isRepeatable$1(this._jsonModel)) && this._itemTemplate ? {
2097
- _itemTemplate: { ...this._itemTemplate }
2098
- } : {}),
2099
- enabled: this.enabled,
2100
- readOnly: this.readOnly
2101
- };
2195
+ return this.withDependencyTrackingControl(true, () => {
2196
+ return {
2197
+ ...super.getState(forRestore),
2198
+ ...(forRestore ? {
2199
+ ':items': undefined,
2200
+ ':itemsOrder': undefined
2201
+ } : {}),
2202
+ items: this.getItemsState(isRepeatableChild, forRestore),
2203
+ ...((this._jsonModel.type === 'array' || isRepeatable$1(this._jsonModel)) && this._itemTemplate ? {
2204
+ _itemTemplate: { ...this._itemTemplate }
2205
+ } : {}),
2206
+ enabled: this.enabled,
2207
+ readOnly: this.readOnly
2208
+ };
2209
+ });
2102
2210
  }
2103
2211
  _createChild(child, options) {
2104
2212
  return this.fieldFactory.createField(child, options);
@@ -2136,10 +2244,10 @@ class Container extends Scriptable {
2136
2244
  Object.defineProperty(parent._childrenReference, name, {
2137
2245
  get: () => {
2138
2246
  if (child.isContainer && child.hasDynamicItems()) {
2139
- self.ruleEngine.trackDependency(child);
2247
+ self.ruleEngine.trackDependency(child, 'items');
2140
2248
  }
2141
2249
  if (self.hasDynamicItems()) {
2142
- self.ruleEngine.trackDependency(self);
2250
+ self.ruleEngine.trackDependency(self, 'items');
2143
2251
  if (this._children[name] !== undefined) {
2144
2252
  return this._children[name].getRuleNode();
2145
2253
  }
@@ -2390,9 +2498,8 @@ class Container extends Scriptable {
2390
2498
  if (items2Remove > 0) {
2391
2499
  for (let i = 0; i < items2Remove; i++) {
2392
2500
  this._childrenReference.pop();
2393
- this._children.pop();
2501
+ result.removed.push(this._children.pop());
2394
2502
  }
2395
- result.removed.push(...this._children);
2396
2503
  }
2397
2504
  }
2398
2505
  this._children.forEach(x => {
@@ -2536,6 +2643,9 @@ class Logger {
2536
2643
  console[level](msg);
2537
2644
  }
2538
2645
  }
2646
+ isLevelEnabled(level) {
2647
+ return this.logLevel !== 0 && this.logLevel <= levels[level];
2648
+ }
2539
2649
  logLevel;
2540
2650
  constructor(logLevel = 'off') {
2541
2651
  this.logLevel = levels[logLevel];
@@ -2596,7 +2706,18 @@ class EventQueue {
2596
2706
  const evntNode = new EventNode(node, e);
2597
2707
  const counter = this._runningEventCount[evntNode.valueOf()] || 0;
2598
2708
  if (counter < EventQueue.MAX_EVENT_CYCLE_COUNT) {
2599
- this.logger.info(`Queued event : ${e.type} node: ${node.id} - ${node.name}`);
2709
+ let payloadAsStr = '';
2710
+ if (e?.type === 'change' && !e?.payload?.changes.map(_ => _.propertyName).includes('activeChild')) {
2711
+ payloadAsStr = JSON.stringify(e.payload.changes, null, 2);
2712
+ }
2713
+ else if (e?.type.includes('setProperty')) {
2714
+ payloadAsStr = JSON.stringify(e.payload, null, 2);
2715
+ }
2716
+ if (this.logger.isLevelEnabled('info')) {
2717
+ node.withDependencyTrackingControl(true, () => {
2718
+ this.logger.info(`Queued event : ${e.type} node: ${node.id} - ${node.qualifiedName} - ${payloadAsStr}`);
2719
+ });
2720
+ }
2600
2721
  if (priority) {
2601
2722
  const index = this._isProcessing ? 1 : 0;
2602
2723
  this._pendingEvents.splice(index, 0, evntNode);
@@ -2689,6 +2810,13 @@ const convertQueryString = (endpoint, payload) => {
2689
2810
  return endpoint.includes('?') ? `${endpoint}&${params.join('&')}` : `${endpoint}?${params.join('&')}`;
2690
2811
  };
2691
2812
 
2813
+ function parsePropertyPath(keyStr) {
2814
+ return keyStr
2815
+ .replace(/\[/g, '.')
2816
+ .replace(/\]/g, '')
2817
+ .split('.')
2818
+ .filter(Boolean);
2819
+ }
2692
2820
  const getCustomEventName = (name) => {
2693
2821
  const eName = name;
2694
2822
  if (eName.length > 0 && eName.startsWith('custom:')) {
@@ -3074,21 +3202,23 @@ class FunctionRuntimeImpl {
3074
3202
  },
3075
3203
  importData: {
3076
3204
  _func: (args, data, interpreter) => {
3077
- const inputData = args[0];
3078
- const qualifiedName = args[1];
3079
- if (typeof inputData === 'object' && inputData !== null && !qualifiedName) {
3080
- interpreter.globals.form.importData(inputData);
3081
- }
3082
- else {
3083
- const field = interpreter.globals.form.resolveQualifiedName(qualifiedName);
3084
- if (field?.isContainer) {
3085
- field.importData(inputData, qualifiedName);
3205
+ return interpreter.globals.form.withDependencyTrackingControl(true, () => {
3206
+ const inputData = args[0];
3207
+ const qualifiedName = args[1];
3208
+ if (typeof inputData === 'object' && inputData !== null && !qualifiedName) {
3209
+ interpreter.globals.form.importData(inputData);
3086
3210
  }
3087
3211
  else {
3088
- interpreter.globals.form.logger.error('Invalid argument passed in importData. A container is expected');
3212
+ const field = interpreter.globals.form.resolveQualifiedName(qualifiedName);
3213
+ if (field?.isContainer) {
3214
+ field.importData(inputData, qualifiedName);
3215
+ }
3216
+ else {
3217
+ interpreter.globals.form.logger.error('Invalid argument passed in importData. A container is expected');
3218
+ }
3089
3219
  }
3090
- }
3091
- return {};
3220
+ return {};
3221
+ });
3092
3222
  },
3093
3223
  _signature: []
3094
3224
  },
@@ -3153,6 +3283,49 @@ class FunctionRuntimeImpl {
3153
3283
  },
3154
3284
  _signature: []
3155
3285
  },
3286
+ setVariable: {
3287
+ _func: (args, data, interpreter) => {
3288
+ const variableName = toString(args[0]);
3289
+ let variableValue = args[1];
3290
+ const normalFieldOrPanel = args[2] || interpreter.globals.form;
3291
+ if (variableValue && typeof variableValue === 'object' && '$qualifiedName' in variableValue) {
3292
+ const variableValueElement = interpreter.globals.form.getElement(variableValue.$id);
3293
+ variableValue = variableValueElement._jsonModel.value;
3294
+ }
3295
+ const target = normalFieldOrPanel.$id ? interpreter.globals.form.getElement(normalFieldOrPanel.$id) : interpreter.globals.form;
3296
+ const propertiesManager = target.getPropertiesManager();
3297
+ propertiesManager.updateSimpleProperty(variableName, variableValue);
3298
+ return {};
3299
+ },
3300
+ _signature: []
3301
+ },
3302
+ getVariable: {
3303
+ _func: (args, data, interpreter) => {
3304
+ const variableName = toString(args[0]);
3305
+ const normalFieldOrPanel = args[1] || interpreter.globals.form;
3306
+ if (!variableName) {
3307
+ return undefined;
3308
+ }
3309
+ const target = normalFieldOrPanel.$id ? interpreter.globals.form.getElement(normalFieldOrPanel.$id) : interpreter.globals.form;
3310
+ const propertiesManager = target.getPropertiesManager();
3311
+ if (variableName.includes('.')) {
3312
+ const properties = parsePropertyPath(variableName);
3313
+ let value = propertiesManager.properties;
3314
+ for (const prop of properties) {
3315
+ if (value === undefined || value === null) {
3316
+ return undefined;
3317
+ }
3318
+ value = value[prop];
3319
+ }
3320
+ return value;
3321
+ }
3322
+ else {
3323
+ propertiesManager.ensurePropertyDescriptor(variableName);
3324
+ return propertiesManager.properties[variableName];
3325
+ }
3326
+ },
3327
+ _signature: []
3328
+ },
3156
3329
  request: {
3157
3330
  _func: (args, data, interpreter) => {
3158
3331
  const uri = toString(args[0]);
@@ -3982,9 +4155,9 @@ class RuleEngine {
3982
4155
  this._context = oldContext;
3983
4156
  return finalRes;
3984
4157
  }
3985
- trackDependency(subscriber) {
4158
+ trackDependency(subscriber, propertyName) {
3986
4159
  if (this.dependencyTracking && this._context && this._context.field !== undefined && this._context.field !== subscriber) {
3987
- subscriber._addDependent(this._context.field);
4160
+ subscriber._addDependent(this._context.field, propertyName);
3988
4161
  }
3989
4162
  }
3990
4163
  setDependencyTracking(track) {
@@ -4483,7 +4656,7 @@ class Field extends Scriptable {
4483
4656
  valueOf() {
4484
4657
  const obj = this[target];
4485
4658
  const actualField = obj === undefined ? this : obj;
4486
- actualField.ruleEngine.trackDependency(actualField);
4659
+ actualField.ruleEngine.trackDependency(actualField, 'value');
4487
4660
  return actualField._jsonModel.value || null;
4488
4661
  }
4489
4662
  toString() {
@@ -1,4 +1,5 @@
1
1
  import { Action, BaseJson, BaseModel, callbackFn, ContainerModel, FormCreationMode, FormModel, Primitives, ValidationError, EventSource } from './types/index';
2
+ import { PropertiesManager } from './PropertiesManager.js';
2
3
  import DataGroup from './data/DataGroup';
3
4
  import DataValue from './data/DataValue';
4
5
  export declare const editableProperties: string[];
@@ -22,6 +23,7 @@ export declare abstract class BaseNode<T extends BaseJson> implements BaseModel
22
23
  _eventSource: EventSource;
23
24
  protected _fragment: string;
24
25
  protected _idSet: Set<string> | undefined;
26
+ private _propertiesManager;
25
27
  protected createIdSet(): Set<string> | undefined;
26
28
  get isContainer(): boolean;
27
29
  constructor(params: T, _options: {
@@ -56,9 +58,15 @@ export declare abstract class BaseNode<T extends BaseJson> implements BaseModel
56
58
  set label(l: import("./types/Json").Label | undefined);
57
59
  get uniqueItems(): boolean | undefined;
58
60
  isTransparent(): boolean;
59
- getDependents(): string[];
61
+ getDependents(): {
62
+ id: string;
63
+ propertyName: string | undefined;
64
+ }[];
60
65
  getState(forRestore?: boolean): T & {
61
- _dependents?: string[] | undefined;
66
+ _dependents?: {
67
+ id: string;
68
+ propertyName: string | undefined;
69
+ }[] | undefined;
62
70
  allowedComponents?: undefined;
63
71
  columnClassNames?: undefined;
64
72
  columnCount?: undefined;
@@ -78,7 +86,7 @@ export declare abstract class BaseNode<T extends BaseJson> implements BaseModel
78
86
  subscribe(callback: callbackFn, eventName?: string): {
79
87
  unsubscribe: () => void;
80
88
  };
81
- _addDependent(dependent: BaseModel): void;
89
+ _addDependent(dependent: BaseModel, propertyName?: string): void;
82
90
  removeDependent(dependent: BaseModel): void;
83
91
  abstract validate(): Array<ValidationError>;
84
92
  abstract executeAction(action: Action): any;
@@ -98,6 +106,7 @@ export declare abstract class BaseNode<T extends BaseJson> implements BaseModel
98
106
  set properties(p: {
99
107
  [key: string]: any;
100
108
  });
109
+ getPropertiesManager(): PropertiesManager;
101
110
  abstract defaultDataModel(name: string | number): DataValue | undefined;
102
111
  abstract syncDataAndFormModel(a?: DataValue | DataGroup): any;
103
112
  getNonTransparentParent(): ContainerModel;
@@ -129,6 +129,8 @@ declare class Checkbox extends Field {
129
129
  errorMessage?: string | undefined;
130
130
  properties: {
131
131
  [key: string]: any;
132
+ } & {
133
+ [key: string]: any;
132
134
  };
133
135
  repeatable?: boolean | undefined;
134
136
  screenReaderText?: string | undefined;
@@ -144,7 +146,10 @@ declare class Checkbox extends Field {
144
146
  value?: any;
145
147
  displayValueExpression?: string | undefined;
146
148
  emptyValue?: "" | "undefined" | "null" | undefined;
147
- _dependents?: string[] | undefined;
149
+ _dependents?: {
150
+ id: string;
151
+ propertyName: string | undefined;
152
+ }[] | undefined;
148
153
  allowedComponents?: undefined;
149
154
  columnClassNames?: undefined;
150
155
  columnCount?: undefined;
@@ -145,7 +145,10 @@ declare abstract class Container<T extends ContainerJson & RulesJson> extends Sc
145
145
  items: any[];
146
146
  ':items'?: undefined;
147
147
  ':itemsOrder'?: undefined;
148
- _dependents?: string[] | undefined;
148
+ _dependents?: {
149
+ id: string;
150
+ propertyName: string | undefined;
151
+ }[] | undefined;
149
152
  allowedComponents?: undefined;
150
153
  columnClassNames?: undefined;
151
154
  columnCount?: undefined;
@@ -197,6 +197,8 @@ declare class Field extends Scriptable<FieldJson> implements FieldModel {
197
197
  errorMessage?: string | undefined;
198
198
  properties: {
199
199
  [key: string]: any;
200
+ } & {
201
+ [key: string]: any;
200
202
  };
201
203
  repeatable?: boolean | undefined;
202
204
  screenReaderText?: string | undefined;
@@ -213,7 +215,10 @@ declare class Field extends Scriptable<FieldJson> implements FieldModel {
213
215
  displayValueExpression?: string | undefined;
214
216
  emptyValue?: "" | "undefined" | "null" | undefined;
215
217
  checked?: boolean | undefined;
216
- _dependents?: string[] | undefined;
218
+ _dependents?: {
219
+ id: string;
220
+ propertyName: string | undefined;
221
+ }[] | undefined;
217
222
  allowedComponents?: undefined;
218
223
  columnClassNames?: undefined;
219
224
  columnCount?: undefined;
@@ -213,7 +213,10 @@ declare class Form extends Container<FormJson> implements FormModel {
213
213
  items: any[];
214
214
  ':items'?: undefined;
215
215
  ':itemsOrder'?: undefined;
216
- _dependents?: string[] | undefined;
216
+ _dependents?: {
217
+ id: string;
218
+ propertyName: string | undefined;
219
+ }[] | undefined;
217
220
  allowedComponents?: undefined;
218
221
  columnClassNames?: undefined;
219
222
  columnCount?: undefined;
@@ -6,6 +6,7 @@ export declare class Logger {
6
6
  warn(msg: string): void;
7
7
  error(msg: string): void;
8
8
  log(msg: string, level: LogFunction): void;
9
+ isLevelEnabled(level: LogFunction): boolean;
9
10
  private logLevel;
10
11
  constructor(logLevel?: LogLevel);
11
12
  }
@@ -33,7 +33,7 @@ declare class FunctionRuntimeImpl {
33
33
  _signature: never[];
34
34
  };
35
35
  importData: {
36
- _func: (args: Array<unknown>, data: unknown, interpreter: any) => {};
36
+ _func: (args: Array<unknown>, data: unknown, interpreter: any) => any;
37
37
  _signature: never[];
38
38
  };
39
39
  submitForm: {
@@ -44,6 +44,14 @@ declare class FunctionRuntimeImpl {
44
44
  _func: (args: Array<unknown>, data: unknown, interpreter: any) => {};
45
45
  _signature: never[];
46
46
  };
47
+ setVariable: {
48
+ _func: (args: Array<unknown>, data: unknown, interpreter: any) => {};
49
+ _signature: never[];
50
+ };
51
+ getVariable: {
52
+ _func: (args: Array<unknown>, data: unknown, interpreter: any) => any;
53
+ _signature: never[];
54
+ };
47
55
  request: {
48
56
  _func: (args: Array<unknown>, data: unknown, interpreter: any) => Promise<any>;
49
57
  _signature: never[];
@@ -12,7 +12,7 @@ declare class RuleEngine {
12
12
  ast: any;
13
13
  };
14
14
  execute(node: any, data: any, globals: any, useValueOf: boolean | undefined, eString: string): any;
15
- trackDependency(subscriber: BaseModel): void;
15
+ trackDependency(subscriber: BaseModel, propertyName?: string): void;
16
16
  setDependencyTracking(track: boolean): void;
17
17
  getDependencyTracking(): boolean;
18
18
  }
@@ -79,7 +79,7 @@ export interface BaseModel extends ConstraintsJson, WithController {
79
79
  getRuleNode(): any;
80
80
  ruleNodeReference(): any;
81
81
  _initialize(mode?: FormCreationMode): any;
82
- _addDependent(dependent: BaseModel): any;
82
+ _addDependent(dependent: BaseModel, propertyName?: string): any;
83
83
  _eventSource: EventSource;
84
84
  readonly fragment: string;
85
85
  }
package/lib/BaseNode.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Action, BaseJson, BaseModel, callbackFn, ContainerModel, FormCreationMode, FormModel, Primitives, ValidationError, EventSource } from './types/index';
2
+ import { PropertiesManager } from './PropertiesManager.js';
2
3
  import DataGroup from './data/DataGroup';
3
4
  import DataValue from './data/DataValue';
4
5
  export declare const editableProperties: string[];
@@ -22,6 +23,7 @@ export declare abstract class BaseNode<T extends BaseJson> implements BaseModel
22
23
  _eventSource: EventSource;
23
24
  protected _fragment: string;
24
25
  protected _idSet: Set<string> | undefined;
26
+ private _propertiesManager;
25
27
  protected createIdSet(): Set<string> | undefined;
26
28
  get isContainer(): boolean;
27
29
  constructor(params: T, _options: {
@@ -56,9 +58,15 @@ export declare abstract class BaseNode<T extends BaseJson> implements BaseModel
56
58
  set label(l: import("./types/Json").Label | undefined);
57
59
  get uniqueItems(): boolean | undefined;
58
60
  isTransparent(): boolean;
59
- getDependents(): string[];
61
+ getDependents(): {
62
+ id: string;
63
+ propertyName: string | undefined;
64
+ }[];
60
65
  getState(forRestore?: boolean): T & {
61
- _dependents?: string[] | undefined;
66
+ _dependents?: {
67
+ id: string;
68
+ propertyName: string | undefined;
69
+ }[] | undefined;
62
70
  allowedComponents?: undefined;
63
71
  columnClassNames?: undefined;
64
72
  columnCount?: undefined;
@@ -78,7 +86,7 @@ export declare abstract class BaseNode<T extends BaseJson> implements BaseModel
78
86
  subscribe(callback: callbackFn, eventName?: string): {
79
87
  unsubscribe: () => void;
80
88
  };
81
- _addDependent(dependent: BaseModel): void;
89
+ _addDependent(dependent: BaseModel, propertyName?: string): void;
82
90
  removeDependent(dependent: BaseModel): void;
83
91
  abstract validate(): Array<ValidationError>;
84
92
  abstract executeAction(action: Action): any;
@@ -98,6 +106,7 @@ export declare abstract class BaseNode<T extends BaseJson> implements BaseModel
98
106
  set properties(p: {
99
107
  [key: string]: any;
100
108
  });
109
+ getPropertiesManager(): PropertiesManager;
101
110
  abstract defaultDataModel(name: string | number): DataValue | undefined;
102
111
  abstract syncDataAndFormModel(a?: DataValue | DataGroup): any;
103
112
  getNonTransparentParent(): ContainerModel;
package/lib/BaseNode.js CHANGED
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.BaseNode = exports.exclude = exports.include = exports.dependencyTracked = exports.qualifiedName = exports.target = exports.staticFields = exports.dynamicProps = exports.editableProperties = void 0;
13
13
  const index_1 = require("./types/index");
14
14
  const Events_1 = require("./controller/Events");
15
+ const PropertiesManager_js_1 = require("./PropertiesManager.js");
15
16
  const DataRefParser_1 = require("./utils/DataRefParser");
16
17
  const EmptyDataValue_1 = __importDefault(require("./data/EmptyDataValue"));
17
18
  const ValidationUtils_1 = require("./utils/ValidationUtils");
@@ -86,7 +87,7 @@ function dependencyTracked() {
86
87
  const get = descriptor.get;
87
88
  if (get != undefined) {
88
89
  descriptor.get = function () {
89
- this.ruleEngine.trackDependency(this);
90
+ this.ruleEngine.trackDependency(this, propertyKey);
90
91
  return get.call(this);
91
92
  };
92
93
  }
@@ -133,6 +134,7 @@ class BaseNode {
133
134
  else if ((_b = this.parent) === null || _b === void 0 ? void 0 : _b.fragment) {
134
135
  this._fragment = this.parent.fragment;
135
136
  }
137
+ this._propertiesManager = new PropertiesManager_js_1.PropertiesManager(this);
136
138
  }
137
139
  createIdSet() {
138
140
  return new Set();
@@ -256,7 +258,11 @@ class BaseNode {
256
258
  return this._jsonModel.label;
257
259
  }
258
260
  set label(l) {
259
- if (l !== this._jsonModel.label) {
261
+ const isLabelSame = (l !== null && this._jsonModel.label !== null &&
262
+ typeof l === 'object' && typeof this._jsonModel.label === 'object') ?
263
+ JSON.stringify(l) === JSON.stringify(this._jsonModel.label) :
264
+ l === this._jsonModel.label;
265
+ if (!isLabelSame) {
260
266
  const changeAction = (0, Events_1.propertyChange)('label', l, this._jsonModel.label);
261
267
  this._jsonModel = Object.assign(Object.assign({}, this._jsonModel), { label: l });
262
268
  this.notifyDependents(changeAction);
@@ -271,20 +277,22 @@ class BaseNode {
271
277
  return !this._jsonModel.name && !isNonTransparent;
272
278
  }
273
279
  getDependents() {
274
- return this._dependents.map(x => x.node.id);
280
+ return this._dependents.map(x => ({ id: x.node.id, propertyName: x.propertyName }));
275
281
  }
276
282
  getState(forRestore = false) {
277
- return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this._jsonModel), { properties: this.properties, index: this.index, parent: undefined, qualifiedName: this.qualifiedName }), (this.repeatable === true ? {
278
- repeatable: true,
279
- minOccur: this.parent.minItems,
280
- maxOccur: this.parent.maxItems
281
- } : {})), { ':type': this[':type'] }), (forRestore ? {
282
- _dependents: this._dependents.length ? this.getDependents() : undefined,
283
- allowedComponents: undefined,
284
- columnClassNames: undefined,
285
- columnCount: undefined,
286
- gridClassNames: undefined
287
- } : {}));
283
+ return this.withDependencyTrackingControl(true, () => {
284
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this._jsonModel), { properties: this.properties, index: this.index, parent: undefined, qualifiedName: this.qualifiedName }), (this.repeatable === true ? {
285
+ repeatable: true,
286
+ minOccur: this.parent.minItems,
287
+ maxOccur: this.parent.maxItems
288
+ } : {})), { ':type': this[':type'] }), (forRestore ? {
289
+ _dependents: this._dependents.length ? this.getDependents() : undefined,
290
+ allowedComponents: undefined,
291
+ columnClassNames: undefined,
292
+ columnCount: undefined,
293
+ gridClassNames: undefined
294
+ } : {}));
295
+ });
288
296
  }
289
297
  subscribe(callback, eventName = 'change') {
290
298
  this._callbacks[eventName] = this._callbacks[eventName] || [];
@@ -295,13 +303,14 @@ class BaseNode {
295
303
  }
296
304
  };
297
305
  }
298
- _addDependent(dependent) {
306
+ _addDependent(dependent, propertyName) {
299
307
  if (this._dependents.find(({ node }) => node === dependent) === undefined) {
300
308
  const subscription = this.subscribe((change) => {
301
309
  const changes = change.payload.changes;
302
310
  const propsToLook = [...exports.dynamicProps, 'items'];
303
311
  const isPropChanged = changes.findIndex(x => {
304
- return propsToLook.indexOf(x.propertyName) > -1;
312
+ const changedPropertyName = x.propertyName;
313
+ return propsToLook.includes(changedPropertyName) || (changedPropertyName.startsWith('properties.') && propertyName === changedPropertyName);
305
314
  }) > -1;
306
315
  if (isPropChanged) {
307
316
  if (this.form.changeEventBehaviour === 'deps') {
@@ -312,7 +321,7 @@ class BaseNode {
312
321
  }
313
322
  }
314
323
  });
315
- this._dependents.push({ node: dependent, subscription });
324
+ this._dependents.push({ node: dependent, propertyName, subscription });
316
325
  }
317
326
  }
318
327
  removeDependent(dependent) {
@@ -348,9 +357,9 @@ class BaseNode {
348
357
  const depsToRestore = this._jsonModel._dependents;
349
358
  if (depsToRestore) {
350
359
  depsToRestore.forEach((x) => {
351
- const node = this.form.getElement(x);
360
+ const node = this.form.getElement(x.id);
352
361
  if (node) {
353
- this._addDependent(node);
362
+ this._addDependent(node, x.propertyName);
354
363
  }
355
364
  });
356
365
  this._jsonModel._dependents = undefined;
@@ -476,10 +485,13 @@ class BaseNode {
476
485
  return this._lang;
477
486
  }
478
487
  get properties() {
479
- return this._jsonModel.properties || {};
488
+ return this._propertiesManager.properties;
480
489
  }
481
490
  set properties(p) {
482
- this._setProperty('properties', Object.assign({}, p));
491
+ this._propertiesManager.properties = p;
492
+ }
493
+ getPropertiesManager() {
494
+ return this._propertiesManager;
483
495
  }
484
496
  getNonTransparentParent() {
485
497
  let nonTransparentParent = this.parent;
@@ -570,7 +582,4 @@ __decorate([
570
582
  __decorate([
571
583
  dependencyTracked()
572
584
  ], BaseNode.prototype, "label", null);
573
- __decorate([
574
- dependencyTracked()
575
- ], BaseNode.prototype, "properties", null);
576
585
  exports.BaseNode = BaseNode;
package/lib/Checkbox.d.ts CHANGED
@@ -129,6 +129,8 @@ declare class Checkbox extends Field {
129
129
  errorMessage?: string | undefined;
130
130
  properties: {
131
131
  [key: string]: any;
132
+ } & {
133
+ [key: string]: any;
132
134
  };
133
135
  repeatable?: boolean | undefined;
134
136
  screenReaderText?: string | undefined;
@@ -144,7 +146,10 @@ declare class Checkbox extends Field {
144
146
  value?: any;
145
147
  displayValueExpression?: string | undefined;
146
148
  emptyValue?: "" | "undefined" | "null" | undefined;
147
- _dependents?: string[] | undefined;
149
+ _dependents?: {
150
+ id: string;
151
+ propertyName: string | undefined;
152
+ }[] | undefined;
148
153
  allowedComponents?: undefined;
149
154
  columnClassNames?: undefined;
150
155
  columnCount?: undefined;
@@ -145,7 +145,10 @@ declare abstract class Container<T extends ContainerJson & RulesJson> extends Sc
145
145
  items: any[];
146
146
  ':items'?: undefined;
147
147
  ':itemsOrder'?: undefined;
148
- _dependents?: string[] | undefined;
148
+ _dependents?: {
149
+ id: string;
150
+ propertyName: string | undefined;
151
+ }[] | undefined;
149
152
  allowedComponents?: undefined;
150
153
  columnClassNames?: undefined;
151
154
  columnCount?: undefined;
package/lib/Container.js CHANGED
@@ -109,12 +109,14 @@ class Container extends Scriptable_1.default {
109
109
  }
110
110
  }
111
111
  getState(isRepeatableChild = false, forRestore = false) {
112
- return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, super.getState(forRestore)), (forRestore ? {
113
- ':items': undefined,
114
- ':itemsOrder': undefined
115
- } : {})), { items: this.getItemsState(isRepeatableChild, forRestore) }), ((this._jsonModel.type === 'array' || (0, JsonUtils_1.isRepeatable)(this._jsonModel)) && this._itemTemplate ? {
116
- _itemTemplate: Object.assign({}, this._itemTemplate)
117
- } : {})), { enabled: this.enabled, readOnly: this.readOnly });
112
+ return this.withDependencyTrackingControl(true, () => {
113
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, super.getState(forRestore)), (forRestore ? {
114
+ ':items': undefined,
115
+ ':itemsOrder': undefined
116
+ } : {})), { items: this.getItemsState(isRepeatableChild, forRestore) }), ((this._jsonModel.type === 'array' || (0, JsonUtils_1.isRepeatable)(this._jsonModel)) && this._itemTemplate ? {
117
+ _itemTemplate: Object.assign({}, this._itemTemplate)
118
+ } : {})), { enabled: this.enabled, readOnly: this.readOnly });
119
+ });
118
120
  }
119
121
  _createChild(child, options) {
120
122
  return this.fieldFactory.createField(child, options);
@@ -146,10 +148,10 @@ class Container extends Scriptable_1.default {
146
148
  Object.defineProperty(parent._childrenReference, name, {
147
149
  get: () => {
148
150
  if (child.isContainer && child.hasDynamicItems()) {
149
- self.ruleEngine.trackDependency(child);
151
+ self.ruleEngine.trackDependency(child, 'items');
150
152
  }
151
153
  if (self.hasDynamicItems()) {
152
- self.ruleEngine.trackDependency(self);
154
+ self.ruleEngine.trackDependency(self, 'items');
153
155
  if (this._children[name] !== undefined) {
154
156
  return this._children[name].getRuleNode();
155
157
  }
@@ -400,9 +402,8 @@ class Container extends Scriptable_1.default {
400
402
  if (items2Remove > 0) {
401
403
  for (let i = 0; i < items2Remove; i++) {
402
404
  this._childrenReference.pop();
403
- this._children.pop();
405
+ result.removed.push(this._children.pop());
404
406
  }
405
- result.removed.push(...this._children);
406
407
  }
407
408
  }
408
409
  this._children.forEach(x => {
package/lib/Field.d.ts CHANGED
@@ -197,6 +197,8 @@ declare class Field extends Scriptable<FieldJson> implements FieldModel {
197
197
  errorMessage?: string | undefined;
198
198
  properties: {
199
199
  [key: string]: any;
200
+ } & {
201
+ [key: string]: any;
200
202
  };
201
203
  repeatable?: boolean | undefined;
202
204
  screenReaderText?: string | undefined;
@@ -213,7 +215,10 @@ declare class Field extends Scriptable<FieldJson> implements FieldModel {
213
215
  displayValueExpression?: string | undefined;
214
216
  emptyValue?: "" | "undefined" | "null" | undefined;
215
217
  checked?: boolean | undefined;
216
- _dependents?: string[] | undefined;
218
+ _dependents?: {
219
+ id: string;
220
+ propertyName: string | undefined;
221
+ }[] | undefined;
217
222
  allowedComponents?: undefined;
218
223
  columnClassNames?: undefined;
219
224
  columnCount?: undefined;
package/lib/Field.js CHANGED
@@ -445,7 +445,7 @@ class Field extends Scriptable_1.default {
445
445
  valueOf() {
446
446
  const obj = this[BaseNode_1.target];
447
447
  const actualField = obj === undefined ? this : obj;
448
- actualField.ruleEngine.trackDependency(actualField);
448
+ actualField.ruleEngine.trackDependency(actualField, 'value');
449
449
  return actualField._jsonModel.value || null;
450
450
  }
451
451
  toString() {
package/lib/Form.d.ts CHANGED
@@ -213,7 +213,10 @@ declare class Form extends Container<FormJson> implements FormModel {
213
213
  items: any[];
214
214
  ':items'?: undefined;
215
215
  ':itemsOrder'?: undefined;
216
- _dependents?: string[] | undefined;
216
+ _dependents?: {
217
+ id: string;
218
+ propertyName: string | undefined;
219
+ }[] | undefined;
217
220
  allowedComponents?: undefined;
218
221
  columnClassNames?: undefined;
219
222
  columnCount?: undefined;
@@ -0,0 +1,14 @@
1
+ export class PropertiesManager {
2
+ constructor(host: any);
3
+ host: any;
4
+ _definedProperties: Set<any>;
5
+ _propertiesWrapper: {};
6
+ _initialized: boolean;
7
+ set properties(arg: {});
8
+ get properties(): {};
9
+ ensurePropertyDescriptor(propertyName: any): void;
10
+ _setupInitialProperties(): void;
11
+ _ensurePropertyDescriptor(prop: any): void;
12
+ updateNestedProperty(propertyPath: any, value: any): void;
13
+ updateSimpleProperty(propertyName: any, value: any): void;
14
+ }
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PropertiesManager = void 0;
4
+ const Events_1 = require("./controller/Events");
5
+ class PropertiesManager {
6
+ constructor(host) {
7
+ this.host = host;
8
+ this._definedProperties = new Set();
9
+ this._propertiesWrapper = {};
10
+ this._initialized = false;
11
+ }
12
+ get properties() {
13
+ if (!this._initialized) {
14
+ this._setupInitialProperties();
15
+ this._initialized = true;
16
+ }
17
+ return this._propertiesWrapper;
18
+ }
19
+ set properties(p) {
20
+ const oldProperties = this.host._jsonModel.properties || {};
21
+ const newProperties = Object.assign({}, p);
22
+ this.host._jsonModel.properties = newProperties;
23
+ Object.keys(newProperties).forEach(prop => {
24
+ this._ensurePropertyDescriptor(prop);
25
+ });
26
+ Object.keys(Object.assign(Object.assign({}, oldProperties), newProperties)).forEach(prop => {
27
+ if (oldProperties[prop] !== newProperties[prop]) {
28
+ const changeAction = (0, Events_1.propertyChange)(`properties.${prop}`, newProperties[prop], oldProperties[prop]);
29
+ this.host.notifyDependents(changeAction);
30
+ }
31
+ });
32
+ }
33
+ ensurePropertyDescriptor(propertyName) {
34
+ this._ensurePropertyDescriptor(propertyName);
35
+ }
36
+ _setupInitialProperties() {
37
+ const properties = this.host._jsonModel.properties || {};
38
+ Object.keys(properties).forEach(prop => {
39
+ this._ensurePropertyDescriptor(prop);
40
+ });
41
+ if (!this.host._jsonModel.properties) {
42
+ this.host._jsonModel.properties = {};
43
+ }
44
+ }
45
+ _ensurePropertyDescriptor(prop) {
46
+ if (this._definedProperties.has(prop)) {
47
+ return;
48
+ }
49
+ Object.defineProperty(this._propertiesWrapper, prop, {
50
+ get: () => {
51
+ if (!prop.startsWith('fd:')) {
52
+ this.host.ruleEngine.trackDependency(this.host, `properties.${prop}`);
53
+ }
54
+ const properties = this.host._jsonModel.properties || {};
55
+ return properties[prop];
56
+ },
57
+ set: (value) => {
58
+ const properties = this.host._jsonModel.properties || {};
59
+ const oldValue = properties[prop];
60
+ if (oldValue !== value) {
61
+ const updatedProperties = Object.assign(Object.assign({}, properties), { [prop]: value });
62
+ this.host._jsonModel.properties = updatedProperties;
63
+ const changeAction = (0, Events_1.propertyChange)(`properties.${prop}`, value, oldValue);
64
+ this.host.notifyDependents(changeAction);
65
+ }
66
+ },
67
+ enumerable: true,
68
+ configurable: true
69
+ });
70
+ this._definedProperties.add(prop);
71
+ }
72
+ updateNestedProperty(propertyPath, value) {
73
+ const parts = propertyPath.split('.');
74
+ const topLevelProp = parts[0];
75
+ this._ensurePropertyDescriptor(topLevelProp);
76
+ const properties = this.host._jsonModel.properties || {};
77
+ const updatedProperties = JSON.parse(JSON.stringify(properties));
78
+ const currentObj = updatedProperties[topLevelProp] || {};
79
+ updatedProperties[topLevelProp] = currentObj;
80
+ let parentObj = currentObj;
81
+ for (let i = 1; i < parts.length - 1; i++) {
82
+ if (!parentObj[parts[i]]) {
83
+ parentObj[parts[i]] = {};
84
+ }
85
+ else if (typeof parentObj[parts[i]] !== 'object') {
86
+ parentObj[parts[i]] = {};
87
+ }
88
+ parentObj = parentObj[parts[i]];
89
+ }
90
+ const finalProp = parts[parts.length - 1];
91
+ const oldValue = parentObj[finalProp];
92
+ parentObj[finalProp] = value;
93
+ this.host._jsonModel.properties = updatedProperties;
94
+ const changeAction = (0, Events_1.propertyChange)(`properties.${propertyPath}`, value, oldValue);
95
+ this.host.notifyDependents(changeAction);
96
+ }
97
+ updateSimpleProperty(propertyName, value) {
98
+ this._ensurePropertyDescriptor(propertyName);
99
+ this._propertiesWrapper[propertyName] = value;
100
+ }
101
+ }
102
+ exports.PropertiesManager = PropertiesManager;
@@ -47,10 +47,22 @@ class EventQueue {
47
47
  events = [events];
48
48
  }
49
49
  events.forEach(e => {
50
+ var _a;
50
51
  const evntNode = new EventNode(node, e);
51
52
  const counter = this._runningEventCount[evntNode.valueOf()] || 0;
52
53
  if (counter < EventQueue.MAX_EVENT_CYCLE_COUNT) {
53
- this.logger.info(`Queued event : ${e.type} node: ${node.id} - ${node.name}`);
54
+ let payloadAsStr = '';
55
+ if ((e === null || e === void 0 ? void 0 : e.type) === 'change' && !((_a = e === null || e === void 0 ? void 0 : e.payload) === null || _a === void 0 ? void 0 : _a.changes.map(_ => _.propertyName).includes('activeChild'))) {
56
+ payloadAsStr = JSON.stringify(e.payload.changes, null, 2);
57
+ }
58
+ else if (e === null || e === void 0 ? void 0 : e.type.includes('setProperty')) {
59
+ payloadAsStr = JSON.stringify(e.payload, null, 2);
60
+ }
61
+ if (this.logger.isLevelEnabled('info')) {
62
+ node.withDependencyTrackingControl(true, () => {
63
+ this.logger.info(`Queued event : ${e.type} node: ${node.id} - ${node.qualifiedName} - ${payloadAsStr}`);
64
+ });
65
+ }
54
66
  if (priority) {
55
67
  const index = this._isProcessing ? 1 : 0;
56
68
  this._pendingEvents.splice(index, 0, evntNode);
@@ -6,6 +6,7 @@ export declare class Logger {
6
6
  warn(msg: string): void;
7
7
  error(msg: string): void;
8
8
  log(msg: string, level: LogFunction): void;
9
+ isLevelEnabled(level: LogFunction): boolean;
9
10
  private logLevel;
10
11
  constructor(logLevel?: LogLevel);
11
12
  }
@@ -29,5 +29,8 @@ class Logger {
29
29
  console[level](msg);
30
30
  }
31
31
  }
32
+ isLevelEnabled(level) {
33
+ return this.logLevel !== 0 && this.logLevel <= levels[level];
34
+ }
32
35
  }
33
36
  exports.Logger = Logger;
@@ -33,7 +33,7 @@ declare class FunctionRuntimeImpl {
33
33
  _signature: never[];
34
34
  };
35
35
  importData: {
36
- _func: (args: Array<unknown>, data: unknown, interpreter: any) => {};
36
+ _func: (args: Array<unknown>, data: unknown, interpreter: any) => any;
37
37
  _signature: never[];
38
38
  };
39
39
  submitForm: {
@@ -44,6 +44,14 @@ declare class FunctionRuntimeImpl {
44
44
  _func: (args: Array<unknown>, data: unknown, interpreter: any) => {};
45
45
  _signature: never[];
46
46
  };
47
+ setVariable: {
48
+ _func: (args: Array<unknown>, data: unknown, interpreter: any) => {};
49
+ _signature: never[];
50
+ };
51
+ getVariable: {
52
+ _func: (args: Array<unknown>, data: unknown, interpreter: any) => any;
53
+ _signature: never[];
54
+ };
47
55
  request: {
48
56
  _func: (args: Array<unknown>, data: unknown, interpreter: any) => Promise<any>;
49
57
  _signature: never[];
@@ -16,6 +16,13 @@ const FileObject_1 = require("../FileObject");
16
16
  const FormUtils_1 = require("../utils/FormUtils");
17
17
  const JsonUtils_1 = require("../utils/JsonUtils");
18
18
  const types_1 = require("../types");
19
+ function parsePropertyPath(keyStr) {
20
+ return keyStr
21
+ .replace(/\[/g, '.')
22
+ .replace(/\]/g, '')
23
+ .split('.')
24
+ .filter(Boolean);
25
+ }
19
26
  const getCustomEventName = (name) => {
20
27
  const eName = name;
21
28
  if (eName.length > 0 && eName.startsWith('custom:')) {
@@ -397,21 +404,23 @@ class FunctionRuntimeImpl {
397
404
  },
398
405
  importData: {
399
406
  _func: (args, data, interpreter) => {
400
- const inputData = args[0];
401
- const qualifiedName = args[1];
402
- if (typeof inputData === 'object' && inputData !== null && !qualifiedName) {
403
- interpreter.globals.form.importData(inputData);
404
- }
405
- else {
406
- const field = interpreter.globals.form.resolveQualifiedName(qualifiedName);
407
- if (field === null || field === void 0 ? void 0 : field.isContainer) {
408
- field.importData(inputData, qualifiedName);
407
+ return interpreter.globals.form.withDependencyTrackingControl(true, () => {
408
+ const inputData = args[0];
409
+ const qualifiedName = args[1];
410
+ if (typeof inputData === 'object' && inputData !== null && !qualifiedName) {
411
+ interpreter.globals.form.importData(inputData);
409
412
  }
410
413
  else {
411
- interpreter.globals.form.logger.error('Invalid argument passed in importData. A container is expected');
414
+ const field = interpreter.globals.form.resolveQualifiedName(qualifiedName);
415
+ if (field === null || field === void 0 ? void 0 : field.isContainer) {
416
+ field.importData(inputData, qualifiedName);
417
+ }
418
+ else {
419
+ interpreter.globals.form.logger.error('Invalid argument passed in importData. A container is expected');
420
+ }
412
421
  }
413
- }
414
- return {};
422
+ return {};
423
+ });
415
424
  },
416
425
  _signature: []
417
426
  },
@@ -477,6 +486,49 @@ class FunctionRuntimeImpl {
477
486
  },
478
487
  _signature: []
479
488
  },
489
+ setVariable: {
490
+ _func: (args, data, interpreter) => {
491
+ const variableName = toString(args[0]);
492
+ let variableValue = args[1];
493
+ const normalFieldOrPanel = args[2] || interpreter.globals.form;
494
+ if (variableValue && typeof variableValue === 'object' && '$qualifiedName' in variableValue) {
495
+ const variableValueElement = interpreter.globals.form.getElement(variableValue.$id);
496
+ variableValue = variableValueElement._jsonModel.value;
497
+ }
498
+ const target = normalFieldOrPanel.$id ? interpreter.globals.form.getElement(normalFieldOrPanel.$id) : interpreter.globals.form;
499
+ const propertiesManager = target.getPropertiesManager();
500
+ propertiesManager.updateSimpleProperty(variableName, variableValue);
501
+ return {};
502
+ },
503
+ _signature: []
504
+ },
505
+ getVariable: {
506
+ _func: (args, data, interpreter) => {
507
+ const variableName = toString(args[0]);
508
+ const normalFieldOrPanel = args[1] || interpreter.globals.form;
509
+ if (!variableName) {
510
+ return undefined;
511
+ }
512
+ const target = normalFieldOrPanel.$id ? interpreter.globals.form.getElement(normalFieldOrPanel.$id) : interpreter.globals.form;
513
+ const propertiesManager = target.getPropertiesManager();
514
+ if (variableName.includes('.')) {
515
+ const properties = parsePropertyPath(variableName);
516
+ let value = propertiesManager.properties;
517
+ for (const prop of properties) {
518
+ if (value === undefined || value === null) {
519
+ return undefined;
520
+ }
521
+ value = value[prop];
522
+ }
523
+ return value;
524
+ }
525
+ else {
526
+ propertiesManager.ensurePropertyDescriptor(variableName);
527
+ return propertiesManager.properties[variableName];
528
+ }
529
+ },
530
+ _signature: []
531
+ },
480
532
  request: {
481
533
  _func: (args, data, interpreter) => {
482
534
  const uri = toString(args[0]);
@@ -12,7 +12,7 @@ declare class RuleEngine {
12
12
  ast: any;
13
13
  };
14
14
  execute(node: any, data: any, globals: any, useValueOf: boolean | undefined, eString: string): any;
15
- trackDependency(subscriber: BaseModel): void;
15
+ trackDependency(subscriber: BaseModel, propertyName?: string): void;
16
16
  setDependencyTracking(track: boolean): void;
17
17
  getDependencyTracking(): boolean;
18
18
  }
@@ -55,9 +55,9 @@ class RuleEngine {
55
55
  this._context = oldContext;
56
56
  return finalRes;
57
57
  }
58
- trackDependency(subscriber) {
58
+ trackDependency(subscriber, propertyName) {
59
59
  if (this.dependencyTracking && this._context && this._context.field !== undefined && this._context.field !== subscriber) {
60
- subscriber._addDependent(this._context.field);
60
+ subscriber._addDependent(this._context.field, propertyName);
61
61
  }
62
62
  }
63
63
  setDependencyTracking(track) {
@@ -79,7 +79,7 @@ export interface BaseModel extends ConstraintsJson, WithController {
79
79
  getRuleNode(): any;
80
80
  ruleNodeReference(): any;
81
81
  _initialize(mode?: FormCreationMode): any;
82
- _addDependent(dependent: BaseModel): any;
82
+ _addDependent(dependent: BaseModel, propertyName?: string): any;
83
83
  _eventSource: EventSource;
84
84
  readonly fragment: string;
85
85
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aemforms/af-core",
3
- "version": "0.22.137",
3
+ "version": "0.22.139",
4
4
  "description": "Core Module for Forms Runtime",
5
5
  "author": "Adobe Systems",
6
6
  "license": "Adobe Proprietary",
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@adobe/json-formula": "0.1.50",
40
- "@aemforms/af-formatters": "^0.22.137"
40
+ "@aemforms/af-formatters": "^0.22.139"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@babel/preset-env": "^7.20.2",