@memberjunction/react-runtime 5.25.0 → 5.26.0

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.
@@ -1,22 +1,22 @@
1
1
 
2
- > @memberjunction/react-runtime@5.25.0 build
2
+ > @memberjunction/react-runtime@5.26.0 build
3
3
  > npm run build:node && npm run build:umd
4
4
 
5
5
 
6
- > @memberjunction/react-runtime@5.25.0 build:node
6
+ > @memberjunction/react-runtime@5.26.0 build:node
7
7
  > tsc
8
8
 
9
9
 
10
- > @memberjunction/react-runtime@5.25.0 build:umd
10
+ > @memberjunction/react-runtime@5.26.0 build:umd
11
11
  > webpack --config webpack.umd.config.cjs
12
12
 
13
13
  [BABEL] Note: The code generator has deoptimised the styling of /home/runner/work/MJ/MJ/packages/MJCoreEntities/dist/generated/entity_subclasses.js as it exceeds the max of 500KB.
14
- asset runtime.umd.js 6.35 MiB [emitted] [big] (name: main)
14
+ asset runtime.umd.js 6.37 MiB [emitted] [big] (name: main)
15
15
  asset 490.runtime.umd.js 182 KiB [emitted] (id hint: vendors)
16
16
  asset 324.runtime.umd.js 176 KiB [emitted]
17
- orphan modules 6.39 MiB [orphan] 498 modules
17
+ orphan modules 6.41 MiB [orphan] 498 modules
18
18
  runtime modules 6.94 KiB 10 modules
19
- cacheable modules 6.54 MiB
19
+ cacheable modules 6.56 MiB
20
20
  modules by path ../../../node_modules/ 780 KiB
21
21
  modules by path ../../../node_modules/rxjs/dist/esm5/internal/ 29.1 KiB 14 modules
22
22
  modules by path ../../../node_modules/debug/src/*.js 12.7 KiB 2 modules
@@ -25,7 +25,7 @@ cacheable modules 6.54 MiB
25
25
  ../../MJCoreEntities/dist/index.js + 28 modules 3.69 MiB [built] [code generated]
26
26
  ../../MJCoreEntities/dist/engines/UserViewEngine.js 19.6 KiB [built] [code generated]
27
27
  ./dist/index.js + 27 modules 426 KiB [built] [code generated]
28
- ../../MJCore/dist/index.js + 75 modules 1.29 MiB [built] [code generated]
28
+ ../../MJCore/dist/index.js + 75 modules 1.3 MiB [built] [code generated]
29
29
  ../../MJGlobal/dist/index.js + 16 modules 220 KiB [built] [code generated]
30
30
  ../../GraphQLDataProvider/dist/index.mjs 158 KiB [built] [code generated]
31
- webpack 5.105.0 compiled successfully in 83186 ms
31
+ webpack 5.105.0 compiled successfully in 76682 ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @memberjunction/react-runtime
2
2
 
3
+ ## 5.26.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [55de456]
8
+ - Updated dependencies [a1002f4]
9
+ - @memberjunction/core-entities@5.26.0
10
+ - @memberjunction/core@5.26.0
11
+ - @memberjunction/graphql-dataprovider@5.26.0
12
+ - @memberjunction/interactive-component-types@5.26.0
13
+ - @memberjunction/global@5.26.0
14
+
3
15
  ## 5.25.0
4
16
 
5
17
  ### Patch Changes
@@ -23693,6 +23693,14 @@ var EntityInfo = /*#__PURE__*/function (_BaseInfo0) {
23693
23693
  * since those inserts bypass BaseEntity and never trigger cache invalidation.
23694
23694
  */
23695
23695
  _this0.TrustServerCacheCompletely = true;
23696
+ /**
23697
+ * Controls whether this entity participates in server-side and client-side
23698
+ * caching at all. When false (default for non-__mj entities), the entire
23699
+ * cache code path is short-circuited: no PreRunView cache check, no
23700
+ * auto-cache storage, no HandleBaseEntityEvent fingerprint scan, no
23701
+ * client-side IndexedDB cache. Zero overhead on hot save/query paths.
23702
+ */
23703
+ _this0.AllowCaching = false;
23696
23704
  /**
23697
23705
  * Whether this entity is available through the GraphQL API
23698
23706
  */
@@ -32301,10 +32309,13 @@ var DEFAULT_CONFIG = {
32301
32309
  enabled: true,
32302
32310
  maxSizeBytes: 150 * 1024 * 1024,
32303
32311
  // 150MB
32304
- maxEntries: 5000,
32305
- defaultTTLMs: 5 * 60 * 1000,
32312
+ defaultTTLMs: 0,
32313
+ // No TTL event-based invalidation is the primary mechanism
32314
+ evictionPolicy: 'lru',
32315
+ maxPercentOfCachePerEntity: 50,
32316
+ evictionSweepIntervalMs: 300000,
32306
32317
  // 5 minutes
32307
- evictionPolicy: 'lru'
32318
+ verboseLogging: false
32308
32319
  };
32309
32320
  // ============================================================================
32310
32321
  // STORAGE CATEGORIES
@@ -32390,6 +32401,10 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
32390
32401
  */
32391
32402
  _this._changeCallbacks = new Map();
32392
32403
  _this._persistTimeout = null;
32404
+ /**
32405
+ * Handle for the periodic eviction sweep timer.
32406
+ */
32407
+ _this._sweepTimer = null;
32393
32408
  return _this;
32394
32409
  }
32395
32410
  // ========================================================================
@@ -32441,6 +32456,8 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
32441
32456
  return this.loadRegistry();
32442
32457
  case 1:
32443
32458
  this._initialized = true;
32459
+ // Start periodic eviction sweep for TTL-expired entries
32460
+ this.startEvictionSweep();
32444
32461
  // Subscribe to BaseEntity events for universal cache invalidation.
32445
32462
  // When any entity is saved/deleted, update all cached RunView results for that entity.
32446
32463
  this.subscribeToBaseEntityEvents();
@@ -32479,6 +32496,18 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
32479
32496
  value: function UpdateConfig(config) {
32480
32497
  this._config = localCacheManager_objectSpread(localCacheManager_objectSpread({}, this._config), config);
32481
32498
  }
32499
+ /**
32500
+ * Checks whether caching is enabled for a given entity. Returns the entity's
32501
+ * AllowCaching metadata flag. This is the single source of truth for cache
32502
+ * eligibility — schema-level opt-in is applied at CodeGen time via the
32503
+ * `newEntityDefaults.AllowCachingBySchema` config, which flips this flag when
32504
+ * the entity is first inserted into the metadata.
32505
+ */
32506
+ }, {
32507
+ key: "IsCachingEnabledForEntity",
32508
+ value: function IsCachingEnabledForEntity(entityInfo) {
32509
+ return entityInfo.AllowCaching === true;
32510
+ }
32482
32511
  /**
32483
32512
  * Replaces the storage provider after initialization. This is needed when
32484
32513
  * the initial provider (e.g., in-memory) needs to be swapped for a
@@ -32694,72 +32723,78 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
32694
32723
  }
32695
32724
  return _context3.a(2);
32696
32725
  case 1:
32697
- entityName = baseEntity.EntityInfo.Name;
32698
- fingerprints = this._entityFingerprintIndex.get(entityName);
32699
- if (!(!fingerprints || fingerprints.size === 0)) {
32726
+ entityName = baseEntity.EntityInfo.Name; // Short-circuit: if caching is disabled for this entity, skip the fingerprint scan
32727
+ if (this.IsCachingEnabledForEntity(baseEntity.EntityInfo)) {
32700
32728
  _context3.n = 2;
32701
32729
  break;
32702
32730
  }
32703
32731
  return _context3.a(2);
32704
32732
  case 2:
32705
- primaryKeys = baseEntity.EntityInfo.PrimaryKeys;
32706
- if (!(!primaryKeys || primaryKeys.length === 0)) {
32733
+ fingerprints = this._entityFingerprintIndex.get(entityName);
32734
+ if (!(!fingerprints || fingerprints.size === 0)) {
32707
32735
  _context3.n = 3;
32708
32736
  break;
32709
32737
  }
32710
32738
  return _context3.a(2);
32711
32739
  case 3:
32740
+ primaryKeys = baseEntity.EntityInfo.PrimaryKeys;
32741
+ if (!(!primaryKeys || primaryKeys.length === 0)) {
32742
+ _context3.n = 4;
32743
+ break;
32744
+ }
32745
+ return _context3.a(2);
32746
+ case 4:
32712
32747
  // Build a CompositeKey from the entity's primary key fields
32713
32748
  key = new CompositeKey();
32714
32749
  key.LoadFromEntityInfoAndRecord(baseEntity.EntityInfo, baseEntity.GetAll());
32715
32750
  if (!(key.KeyValuePairs.length === 0 || key.KeyValuePairs.some(function (kv) {
32716
32751
  return kv.Value == null;
32717
32752
  }))) {
32718
- _context3.n = 4;
32753
+ _context3.n = 5;
32719
32754
  break;
32720
32755
  }
32721
32756
  return _context3.a(2);
32722
- case 4:
32757
+ case 5:
32723
32758
  LogStatusVerbose("LocalCacheManager: BaseEntity ".concat(entityEvent.type, " event for \"").concat(entityName, "\" PK=").concat(key.ToConcatenatedString(), ", updating ").concat(fingerprints.size, " cached fingerprint(s)"));
32724
32759
  fingerprintSnapshot = localCacheManager_toConsumableArray(fingerprints);
32725
32760
  nowISO = new Date().toISOString();
32726
32761
  _iterator2 = localCacheManager_createForOfIteratorHelper(fingerprintSnapshot);
32727
- _context3.p = 5;
32762
+ _context3.p = 6;
32728
32763
  _iterator2.s();
32729
- case 6:
32764
+ case 7:
32730
32765
  if ((_step2 = _iterator2.n()).done) {
32731
- _context3.n = 11;
32766
+ _context3.n = 12;
32732
32767
  break;
32733
32768
  }
32734
32769
  fingerprint = _step2.value;
32735
- _context3.p = 7;
32736
- _context3.n = 8;
32770
+ _context3.p = 8;
32771
+ _context3.n = 9;
32737
32772
  return this.processEntityEventForFingerprint(entityEvent.type, fingerprint, baseEntity, key, nowISO);
32738
- case 8:
32739
- _context3.n = 10;
32740
- break;
32741
32773
  case 9:
32742
- _context3.p = 9;
32774
+ _context3.n = 11;
32775
+ break;
32776
+ case 10:
32777
+ _context3.p = 10;
32743
32778
  _t3 = _context3.v;
32744
32779
  LogError("HandleBaseEntityEvent: failed to update fingerprint \"".concat(fingerprint, "\": ").concat(_t3.message));
32745
- case 10:
32746
- _context3.n = 6;
32747
- break;
32748
32780
  case 11:
32749
- _context3.n = 13;
32781
+ _context3.n = 7;
32750
32782
  break;
32751
32783
  case 12:
32752
- _context3.p = 12;
32753
- _t4 = _context3.v;
32754
- _iterator2.e(_t4);
32784
+ _context3.n = 14;
32785
+ break;
32755
32786
  case 13:
32756
32787
  _context3.p = 13;
32757
- _iterator2.f();
32758
- return _context3.f(13);
32788
+ _t4 = _context3.v;
32789
+ _iterator2.e(_t4);
32759
32790
  case 14:
32791
+ _context3.p = 14;
32792
+ _iterator2.f();
32793
+ return _context3.f(14);
32794
+ case 15:
32760
32795
  return _context3.a(2);
32761
32796
  }
32762
- }, _callee3, this, [[7, 9], [5, 12, 13, 14]]);
32797
+ }, _callee3, this, [[8, 10], [6, 13, 14, 15]]);
32763
32798
  }));
32764
32799
  function HandleBaseEntityEvent(_x4) {
32765
32800
  return _HandleBaseEntityEvent.apply(this, arguments);
@@ -32777,7 +32812,7 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
32777
32812
  key: "HandleRemoteInvalidateEvent",
32778
32813
  value: (function () {
32779
32814
  var _HandleRemoteInvalidateEvent = localCacheManager_asyncToGenerator(/*#__PURE__*/localCacheManager_regenerator().m(function _callee4(entityEvent) {
32780
- var payload, entityName, fingerprints, action, md, entityInfo, _i, _arr, fp, primaryKeys, _i2, _arr2, _fp, nowISO, fingerprintSnapshot, key, _iterator3, _step3, _fp2, _iterator4, _step4, fingerprint, recordData, _key, _iterator5, _step5, _fingerprint, _iterator6, _step6, _fp3, _iterator7, _step7, _fp4, _t5, _t6, _t7, _t8, _t9, _t0, _t1, _t10;
32815
+ var payload, entityName, md, entityInfo, fingerprints, action, _i, _arr, fp, primaryKeys, _i2, _arr2, _fp, nowISO, fingerprintSnapshot, key, _iterator3, _step3, _fp2, _iterator4, _step4, fingerprint, recordData, _key, _iterator5, _step5, _fingerprint, _iterator6, _step6, _fp3, _iterator7, _step7, _fp4, _t5, _t6, _t7, _t8, _t9, _t0, _t1, _t10;
32781
32816
  return localCacheManager_regenerator().w(function (_context4) {
32782
32817
  while (1) switch (_context4.p = _context4.n) {
32783
32818
  case 0:
@@ -32789,141 +32824,148 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
32789
32824
  }
32790
32825
  return _context4.a(2);
32791
32826
  case 1:
32792
- fingerprints = this._entityFingerprintIndex.get(entityName);
32793
- if (!(!fingerprints || fingerprints.size === 0)) {
32827
+ // Short-circuit: if caching is disabled for this entity, skip processing
32828
+ md = new Metadata();
32829
+ entityInfo = md.EntityByName(entityName);
32830
+ if (!(entityInfo && !this.IsCachingEnabledForEntity(entityInfo))) {
32794
32831
  _context4.n = 2;
32795
32832
  break;
32796
32833
  }
32797
32834
  return _context4.a(2);
32798
32835
  case 2:
32799
- action = payload === null || payload === void 0 ? void 0 : payload.action; // Look up entity metadata for PK field names
32800
- md = new Metadata();
32801
- entityInfo = md.EntityByName(entityName);
32836
+ fingerprints = this._entityFingerprintIndex.get(entityName);
32837
+ if (!(!fingerprints || fingerprints.size === 0)) {
32838
+ _context4.n = 3;
32839
+ break;
32840
+ }
32841
+ return _context4.a(2);
32842
+ case 3:
32843
+ action = payload === null || payload === void 0 ? void 0 : payload.action; // entityInfo was looked up above for the AllowCaching check
32802
32844
  if (entityInfo) {
32803
- _context4.n = 6;
32845
+ _context4.n = 7;
32804
32846
  break;
32805
32847
  }
32806
32848
  LogStatusVerbose("LocalCacheManager: remote-invalidate \u2014 entity \"".concat(entityName, "\" not found in metadata, invalidating caches"));
32807
32849
  _i = 0, _arr = localCacheManager_toConsumableArray(fingerprints);
32808
- case 3:
32850
+ case 4:
32809
32851
  if (!(_i < _arr.length)) {
32810
- _context4.n = 5;
32852
+ _context4.n = 6;
32811
32853
  break;
32812
32854
  }
32813
32855
  fp = _arr[_i];
32814
- _context4.n = 4;
32856
+ _context4.n = 5;
32815
32857
  return this.InvalidateRunViewResult(fp);
32816
- case 4:
32858
+ case 5:
32817
32859
  _i++;
32818
- _context4.n = 3;
32860
+ _context4.n = 4;
32819
32861
  break;
32820
- case 5:
32821
- return _context4.a(2);
32822
32862
  case 6:
32863
+ return _context4.a(2);
32864
+ case 7:
32823
32865
  primaryKeys = entityInfo.PrimaryKeys;
32824
32866
  if (!(!primaryKeys || primaryKeys.length === 0)) {
32825
- _context4.n = 10;
32867
+ _context4.n = 11;
32826
32868
  break;
32827
32869
  }
32828
32870
  LogStatusVerbose("LocalCacheManager: remote-invalidate \u2014 no PKs for \"".concat(entityName, "\", invalidating ").concat(fingerprints.size, " cached fingerprint(s)"));
32829
32871
  _i2 = 0, _arr2 = localCacheManager_toConsumableArray(fingerprints);
32830
- case 7:
32872
+ case 8:
32831
32873
  if (!(_i2 < _arr2.length)) {
32832
- _context4.n = 9;
32874
+ _context4.n = 10;
32833
32875
  break;
32834
32876
  }
32835
32877
  _fp = _arr2[_i2];
32836
- _context4.n = 8;
32878
+ _context4.n = 9;
32837
32879
  return this.InvalidateRunViewResult(_fp);
32838
- case 8:
32880
+ case 9:
32839
32881
  _i2++;
32840
- _context4.n = 7;
32882
+ _context4.n = 8;
32841
32883
  break;
32842
- case 9:
32843
- return _context4.a(2);
32844
32884
  case 10:
32885
+ return _context4.a(2);
32886
+ case 11:
32845
32887
  nowISO = new Date().toISOString();
32846
32888
  fingerprintSnapshot = localCacheManager_toConsumableArray(fingerprints); // Handle delete: remove the record from all cached results
32847
32889
  if (!(action === 'delete')) {
32848
- _context4.n = 29;
32890
+ _context4.n = 30;
32849
32891
  break;
32850
32892
  }
32851
32893
  key = this.parseCompositeKeyFromJSON(payload === null || payload === void 0 ? void 0 : payload.primaryKeyValues);
32852
32894
  if (key) {
32853
- _context4.n = 18;
32895
+ _context4.n = 19;
32854
32896
  break;
32855
32897
  }
32856
32898
  LogStatusVerbose("LocalCacheManager: remote-invalidate (delete) \u2014 no PK values for \"".concat(entityName, "\", invalidating caches"));
32857
32899
  _iterator3 = localCacheManager_createForOfIteratorHelper(fingerprintSnapshot);
32858
- _context4.p = 11;
32900
+ _context4.p = 12;
32859
32901
  _iterator3.s();
32860
- case 12:
32902
+ case 13:
32861
32903
  if ((_step3 = _iterator3.n()).done) {
32862
- _context4.n = 14;
32904
+ _context4.n = 15;
32863
32905
  break;
32864
32906
  }
32865
32907
  _fp2 = _step3.value;
32866
- _context4.n = 13;
32908
+ _context4.n = 14;
32867
32909
  return this.InvalidateRunViewResult(_fp2);
32868
- case 13:
32869
- _context4.n = 12;
32870
- break;
32871
32910
  case 14:
32872
- _context4.n = 16;
32911
+ _context4.n = 13;
32873
32912
  break;
32874
32913
  case 15:
32875
- _context4.p = 15;
32876
- _t5 = _context4.v;
32877
- _iterator3.e(_t5);
32914
+ _context4.n = 17;
32915
+ break;
32878
32916
  case 16:
32879
32917
  _context4.p = 16;
32880
- _iterator3.f();
32881
- return _context4.f(16);
32918
+ _t5 = _context4.v;
32919
+ _iterator3.e(_t5);
32882
32920
  case 17:
32883
- return _context4.a(2);
32921
+ _context4.p = 17;
32922
+ _iterator3.f();
32923
+ return _context4.f(17);
32884
32924
  case 18:
32925
+ return _context4.a(2);
32926
+ case 19:
32885
32927
  LogStatusVerbose("LocalCacheManager: remote-invalidate (delete) for \"".concat(entityName, "\" PK=").concat(key.ToConcatenatedString(), ", removing from ").concat(fingerprints.size, " cached fingerprint(s)"));
32886
32928
  _iterator4 = localCacheManager_createForOfIteratorHelper(fingerprintSnapshot);
32887
- _context4.p = 19;
32929
+ _context4.p = 20;
32888
32930
  _iterator4.s();
32889
- case 20:
32931
+ case 21:
32890
32932
  if ((_step4 = _iterator4.n()).done) {
32891
- _context4.n = 25;
32933
+ _context4.n = 26;
32892
32934
  break;
32893
32935
  }
32894
32936
  fingerprint = _step4.value;
32895
- _context4.p = 21;
32896
- _context4.n = 22;
32937
+ _context4.p = 22;
32938
+ _context4.n = 23;
32897
32939
  return this.RemoveSingleEntity(fingerprint, key, nowISO);
32898
- case 22:
32899
- _context4.n = 24;
32900
- break;
32901
32940
  case 23:
32902
- _context4.p = 23;
32941
+ _context4.n = 25;
32942
+ break;
32943
+ case 24:
32944
+ _context4.p = 24;
32903
32945
  _t6 = _context4.v;
32904
32946
  LogError("HandleRemoteInvalidateEvent: failed to remove from \"".concat(fingerprint, "\": ").concat(_t6.message));
32905
- case 24:
32906
- _context4.n = 20;
32907
- break;
32908
32947
  case 25:
32909
- _context4.n = 27;
32948
+ _context4.n = 21;
32910
32949
  break;
32911
32950
  case 26:
32912
- _context4.p = 26;
32913
- _t7 = _context4.v;
32914
- _iterator4.e(_t7);
32951
+ _context4.n = 28;
32952
+ break;
32915
32953
  case 27:
32916
32954
  _context4.p = 27;
32917
- _iterator4.f();
32918
- return _context4.f(27);
32955
+ _t7 = _context4.v;
32956
+ _iterator4.e(_t7);
32919
32957
  case 28:
32920
- return _context4.a(2);
32958
+ _context4.p = 28;
32959
+ _iterator4.f();
32960
+ return _context4.f(28);
32921
32961
  case 29:
32962
+ return _context4.a(2);
32963
+ case 30:
32922
32964
  if (!(action === 'save' && payload !== null && payload !== void 0 && payload.recordData)) {
32923
- _context4.n = 52;
32965
+ _context4.n = 53;
32924
32966
  break;
32925
32967
  }
32926
- _context4.p = 30;
32968
+ _context4.p = 31;
32927
32969
  recordData = JSON.parse(payload.recordData); // Build CompositeKey from record data using entity PK fields
32928
32970
  _key = this.buildCompositeKeyFromRow(recordData, primaryKeys.map(function (pk) {
32929
32971
  return pk.Name;
@@ -32931,121 +32973,121 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
32931
32973
  if (!_key.KeyValuePairs.some(function (kv) {
32932
32974
  return kv.Value == null;
32933
32975
  })) {
32934
- _context4.n = 31;
32976
+ _context4.n = 32;
32935
32977
  break;
32936
32978
  }
32937
32979
  return _context4.a(2);
32938
- case 31:
32980
+ case 32:
32939
32981
  LogStatusVerbose("LocalCacheManager: remote-invalidate (save) for \"".concat(entityName, "\" PK=").concat(_key.ToConcatenatedString(), ", updating ").concat(fingerprints.size, " cached fingerprint(s)"));
32940
32982
  _iterator5 = localCacheManager_createForOfIteratorHelper(fingerprintSnapshot);
32941
- _context4.p = 32;
32983
+ _context4.p = 33;
32942
32984
  _iterator5.s();
32943
- case 33:
32985
+ case 34:
32944
32986
  if ((_step5 = _iterator5.n()).done) {
32945
- _context4.n = 40;
32987
+ _context4.n = 41;
32946
32988
  break;
32947
32989
  }
32948
32990
  _fingerprint = _step5.value;
32949
- _context4.p = 34;
32991
+ _context4.p = 35;
32950
32992
  if (this.isFilteredFingerprint(_fingerprint)) {
32951
- _context4.n = 36;
32993
+ _context4.n = 37;
32952
32994
  break;
32953
32995
  }
32954
- _context4.n = 35;
32996
+ _context4.n = 36;
32955
32997
  return this.UpsertSingleEntity(_fingerprint, recordData, _key, nowISO);
32956
- case 35:
32957
- _context4.n = 37;
32958
- break;
32959
32998
  case 36:
32960
- _context4.n = 37;
32961
- return this.InvalidateRunViewResult(_fingerprint);
32962
- case 37:
32963
- _context4.n = 39;
32999
+ _context4.n = 38;
32964
33000
  break;
33001
+ case 37:
33002
+ _context4.n = 38;
33003
+ return this.InvalidateRunViewResult(_fingerprint);
32965
33004
  case 38:
32966
- _context4.p = 38;
33005
+ _context4.n = 40;
33006
+ break;
33007
+ case 39:
33008
+ _context4.p = 39;
32967
33009
  _t8 = _context4.v;
32968
33010
  LogError("HandleRemoteInvalidateEvent: failed to update \"".concat(_fingerprint, "\": ").concat(_t8.message));
32969
- case 39:
32970
- _context4.n = 33;
32971
- break;
32972
33011
  case 40:
32973
- _context4.n = 42;
33012
+ _context4.n = 34;
32974
33013
  break;
32975
33014
  case 41:
32976
- _context4.p = 41;
32977
- _t9 = _context4.v;
32978
- _iterator5.e(_t9);
33015
+ _context4.n = 43;
33016
+ break;
32979
33017
  case 42:
32980
33018
  _context4.p = 42;
32981
- _iterator5.f();
32982
- return _context4.f(42);
33019
+ _t9 = _context4.v;
33020
+ _iterator5.e(_t9);
32983
33021
  case 43:
32984
- _context4.n = 51;
32985
- break;
33022
+ _context4.p = 43;
33023
+ _iterator5.f();
33024
+ return _context4.f(43);
32986
33025
  case 44:
32987
- _context4.p = 44;
33026
+ _context4.n = 52;
33027
+ break;
33028
+ case 45:
33029
+ _context4.p = 45;
32988
33030
  _t0 = _context4.v;
32989
33031
  LogError("HandleRemoteInvalidateEvent: failed to parse recordData for \"".concat(entityName, "\": ").concat(_t0.message));
32990
33032
  _iterator6 = localCacheManager_createForOfIteratorHelper(fingerprintSnapshot);
32991
- _context4.p = 45;
33033
+ _context4.p = 46;
32992
33034
  _iterator6.s();
32993
- case 46:
33035
+ case 47:
32994
33036
  if ((_step6 = _iterator6.n()).done) {
32995
- _context4.n = 48;
33037
+ _context4.n = 49;
32996
33038
  break;
32997
33039
  }
32998
33040
  _fp3 = _step6.value;
32999
- _context4.n = 47;
33041
+ _context4.n = 48;
33000
33042
  return this.InvalidateRunViewResult(_fp3);
33001
- case 47:
33002
- _context4.n = 46;
33003
- break;
33004
33043
  case 48:
33005
- _context4.n = 50;
33044
+ _context4.n = 47;
33006
33045
  break;
33007
33046
  case 49:
33008
- _context4.p = 49;
33009
- _t1 = _context4.v;
33010
- _iterator6.e(_t1);
33047
+ _context4.n = 51;
33048
+ break;
33011
33049
  case 50:
33012
33050
  _context4.p = 50;
33013
- _iterator6.f();
33014
- return _context4.f(50);
33051
+ _t1 = _context4.v;
33052
+ _iterator6.e(_t1);
33015
33053
  case 51:
33016
- return _context4.a(2);
33054
+ _context4.p = 51;
33055
+ _iterator6.f();
33056
+ return _context4.f(51);
33017
33057
  case 52:
33058
+ return _context4.a(2);
33059
+ case 53:
33018
33060
  // Fallback: no record data or unrecognized action — invalidate
33019
33061
  LogStatusVerbose("LocalCacheManager: remote-invalidate (".concat(action || 'unknown', ") for \"").concat(entityName, "\", invalidating ").concat(fingerprints.size, " cached fingerprint(s)"));
33020
33062
  _iterator7 = localCacheManager_createForOfIteratorHelper(fingerprintSnapshot);
33021
- _context4.p = 53;
33063
+ _context4.p = 54;
33022
33064
  _iterator7.s();
33023
- case 54:
33065
+ case 55:
33024
33066
  if ((_step7 = _iterator7.n()).done) {
33025
- _context4.n = 56;
33067
+ _context4.n = 57;
33026
33068
  break;
33027
33069
  }
33028
33070
  _fp4 = _step7.value;
33029
- _context4.n = 55;
33071
+ _context4.n = 56;
33030
33072
  return this.InvalidateRunViewResult(_fp4);
33031
- case 55:
33032
- _context4.n = 54;
33033
- break;
33034
33073
  case 56:
33035
- _context4.n = 58;
33074
+ _context4.n = 55;
33036
33075
  break;
33037
33076
  case 57:
33038
- _context4.p = 57;
33039
- _t10 = _context4.v;
33040
- _iterator7.e(_t10);
33077
+ _context4.n = 59;
33078
+ break;
33041
33079
  case 58:
33042
33080
  _context4.p = 58;
33043
- _iterator7.f();
33044
- return _context4.f(58);
33081
+ _t10 = _context4.v;
33082
+ _iterator7.e(_t10);
33045
33083
  case 59:
33084
+ _context4.p = 59;
33085
+ _iterator7.f();
33086
+ return _context4.f(59);
33087
+ case 60:
33046
33088
  return _context4.a(2);
33047
33089
  }
33048
- }, _callee4, this, [[53, 57, 58, 59], [45, 49, 50, 51], [34, 38], [32, 41, 42, 43], [30, 44], [21, 23], [19, 26, 27, 28], [11, 15, 16, 17]]);
33090
+ }, _callee4, this, [[54, 58, 59, 60], [46, 50, 51, 52], [35, 39], [33, 42, 43, 44], [31, 45], [22, 24], [20, 27, 28, 29], [12, 16, 17, 18]]);
33049
33091
  }));
33050
33092
  function HandleRemoteInvalidateEvent(_x5) {
33051
33093
  return _HandleRemoteInvalidateEvent.apply(this, arguments);
@@ -33624,7 +33666,7 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
33624
33666
  key: "SetRunViewResult",
33625
33667
  value: (function () {
33626
33668
  var _SetRunViewResult = localCacheManager_asyncToGenerator(/*#__PURE__*/localCacheManager_regenerator().m(function _callee1(fingerprint, params, results, maxUpdatedAt, aggregateResults, totalRowCount) {
33627
- var data, value, sizeBytes, _params$Aggregates$le, _params$Aggregates, _t16;
33669
+ var data, value, sizeBytes, entityName, _params$Aggregates$le, _params$Aggregates, _t16;
33628
33670
  return localCacheManager_regenerator().w(function (_context1) {
33629
33671
  while (1) switch (_context1.p = _context1.n) {
33630
33672
  case 0:
@@ -33646,14 +33688,18 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
33646
33688
  data.totalRowCount = totalRowCount;
33647
33689
  }
33648
33690
  value = JSON.stringify(data);
33649
- sizeBytes = this.estimateSize(value); // Check if we need to evict entries
33691
+ sizeBytes = this.estimateSize(value); // Per-entity memory limit: evict oldest entries for this entity if over budget
33692
+ entityName = params.EntityName || 'Unknown';
33650
33693
  _context1.n = 2;
33651
- return this.evictIfNeeded(sizeBytes);
33694
+ return this.enforcePerEntityMemoryLimit(entityName, sizeBytes);
33652
33695
  case 2:
33653
- _context1.p = 2;
33654
33696
  _context1.n = 3;
33655
- return this._storageProvider.SetItem(fingerprint, value, CacheCategory.RunViewCache);
33697
+ return this.evictIfNeeded(sizeBytes);
33656
33698
  case 3:
33699
+ _context1.p = 3;
33700
+ _context1.n = 4;
33701
+ return this._storageProvider.SetItem(fingerprint, value, CacheCategory.RunViewCache);
33702
+ case 4:
33657
33703
  this.registerEntry({
33658
33704
  key: fingerprint,
33659
33705
  type: 'runview',
@@ -33677,16 +33723,16 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
33677
33723
  // Maintain entity→fingerprint reverse index for universal cache invalidation
33678
33724
  this.addToEntityIndex(fingerprint);
33679
33725
  LogStatusVerbose("LocalCacheManager.SetRunViewResult: Cached ".concat(results.length, " rows for \"").concat(fingerprint.substring(0, 60), "\" (").concat(sizeBytes, " bytes)"));
33680
- _context1.n = 5;
33726
+ _context1.n = 6;
33681
33727
  break;
33682
- case 4:
33683
- _context1.p = 4;
33728
+ case 5:
33729
+ _context1.p = 5;
33684
33730
  _t16 = _context1.v;
33685
33731
  LogError("LocalCacheManager.SetRunViewResult failed: ".concat(_t16));
33686
- case 5:
33732
+ case 6:
33687
33733
  return _context1.a(2);
33688
33734
  }
33689
- }, _callee1, this, [[2, 4]]);
33735
+ }, _callee1, this, [[3, 5]]);
33690
33736
  }));
33691
33737
  function SetRunViewResult(_x25, _x26, _x27, _x28, _x29, _x30) {
33692
33738
  return _SetRunViewResult.apply(this, arguments);
@@ -35027,7 +35073,7 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
35027
35073
  key: "evictIfNeeded",
35028
35074
  value: (function () {
35029
35075
  var _evictIfNeeded = localCacheManager_asyncToGenerator(/*#__PURE__*/localCacheManager_regenerator().m(function _callee29(neededBytes) {
35030
- var stats, wouldExceedSize, wouldExceedCount, targetFreeBytes, targetFreeCount;
35076
+ var stats, wouldExceedSize, targetFreeBytes;
35031
35077
  return localCacheManager_regenerator().w(function (_context29) {
35032
35078
  while (1) switch (_context29.n) {
35033
35079
  case 0:
@@ -35039,18 +35085,17 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
35039
35085
  case 1:
35040
35086
  stats = this.GetStats();
35041
35087
  wouldExceedSize = stats.totalSizeBytes + neededBytes > this._config.maxSizeBytes;
35042
- wouldExceedCount = stats.totalEntries >= this._config.maxEntries;
35043
- if (!(!wouldExceedSize && !wouldExceedCount)) {
35088
+ if (wouldExceedSize) {
35044
35089
  _context29.n = 2;
35045
35090
  break;
35046
35091
  }
35047
35092
  return _context29.a(2);
35048
35093
  case 2:
35049
- // Calculate how much to free
35050
- targetFreeBytes = Math.max(neededBytes, this._config.maxSizeBytes * 0.1); // At least 10% of max
35051
- targetFreeCount = Math.max(1, Math.floor(this._config.maxEntries * 0.1)); // At least 10% of max
35094
+ // Calculate how much to free — at least the incoming entry's size, but
35095
+ // free 10% of total budget to avoid thrashing on every store.
35096
+ targetFreeBytes = Math.max(neededBytes, this._config.maxSizeBytes * 0.1);
35052
35097
  _context29.n = 3;
35053
- return this.evict(targetFreeBytes, targetFreeCount);
35098
+ return this.evict(targetFreeBytes);
35054
35099
  case 3:
35055
35100
  return _context29.a(2);
35056
35101
  }
@@ -35068,8 +35113,8 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
35068
35113
  }, {
35069
35114
  key: "evict",
35070
35115
  value: (function () {
35071
- var _evict = localCacheManager_asyncToGenerator(/*#__PURE__*/localCacheManager_regenerator().m(function _callee30(targetBytes, targetCount) {
35072
- var entries, freedBytes, freedCount, toDelete, _iterator20, _step20, _entry, _i5, _toDelete, key, entry, category, _t33, _t34, _t35;
35116
+ var _evict = localCacheManager_asyncToGenerator(/*#__PURE__*/localCacheManager_regenerator().m(function _callee30(targetBytes) {
35117
+ var entries, freedBytes, toDelete, _iterator20, _step20, _entry, _i5, _toDelete, key, entry, category, _t33, _t34, _t35;
35073
35118
  return localCacheManager_regenerator().w(function (_context30) {
35074
35119
  while (1) switch (_context30.p = _context30.n) {
35075
35120
  case 0:
@@ -35100,7 +35145,6 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
35100
35145
  return _context30.a(3, 5);
35101
35146
  case 5:
35102
35147
  freedBytes = 0;
35103
- freedCount = 0;
35104
35148
  toDelete = [];
35105
35149
  _iterator20 = localCacheManager_createForOfIteratorHelper(entries);
35106
35150
  _context30.p = 6;
@@ -35111,7 +35155,7 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
35111
35155
  break;
35112
35156
  }
35113
35157
  _entry = _step20.value;
35114
- if (!(freedBytes >= targetBytes && freedCount >= targetCount)) {
35158
+ if (!(freedBytes >= targetBytes)) {
35115
35159
  _context30.n = 8;
35116
35160
  break;
35117
35161
  }
@@ -35119,7 +35163,6 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
35119
35163
  case 8:
35120
35164
  toDelete.push(_entry.key);
35121
35165
  freedBytes += _entry.sizeBytes;
35122
- freedCount++;
35123
35166
  case 9:
35124
35167
  _context30.n = 7;
35125
35168
  break;
@@ -35185,10 +35228,282 @@ var LocalCacheManager = /*#__PURE__*/function (_BaseSingleton) {
35185
35228
  }
35186
35229
  }, _callee30, this, [[15, 18], [6, 11, 12, 13]]);
35187
35230
  }));
35188
- function evict(_x67, _x68) {
35231
+ function evict(_x67) {
35189
35232
  return _evict.apply(this, arguments);
35190
35233
  }
35191
35234
  return evict;
35235
+ }()
35236
+ /**
35237
+ * Returns the memory limit in bytes for a given entity based on
35238
+ * maxPercentOfCachePerEntity. Returns 0 if no limit applies.
35239
+ */
35240
+ )
35241
+ }, {
35242
+ key: "getEntityMemoryLimitBytes",
35243
+ value: function getEntityMemoryLimitBytes() {
35244
+ var pct = this._config.maxPercentOfCachePerEntity;
35245
+ if (pct <= 0) return 0;
35246
+ return Math.floor(this._config.maxSizeBytes * pct / 100);
35247
+ }
35248
+ /**
35249
+ * Enforces per-entity memory limits. When an entity's total cached bytes
35250
+ * (including the incoming entry) would exceed its limit, evicts the
35251
+ * least-recently-accessed entries for that entity until under the limit.
35252
+ * @param incomingSizeBytes - estimated size of the entry about to be stored
35253
+ */
35254
+ }, {
35255
+ key: "enforcePerEntityMemoryLimit",
35256
+ value: (function () {
35257
+ var _enforcePerEntityMemoryLimit = localCacheManager_asyncToGenerator(/*#__PURE__*/localCacheManager_regenerator().m(function _callee31(entityName, incomingSizeBytes) {
35258
+ var _this7 = this;
35259
+ var limitBytes, fingerprints, entries, totalBytes, bytesToFree, _iterator21, _step21, entry, category, _t36, _t37;
35260
+ return localCacheManager_regenerator().w(function (_context31) {
35261
+ while (1) switch (_context31.p = _context31.n) {
35262
+ case 0:
35263
+ limitBytes = this.getEntityMemoryLimitBytes();
35264
+ if (!(limitBytes <= 0 || !this._storageProvider)) {
35265
+ _context31.n = 1;
35266
+ break;
35267
+ }
35268
+ return _context31.a(2);
35269
+ case 1:
35270
+ fingerprints = this._entityFingerprintIndex.get(entityName);
35271
+ if (!(!fingerprints || fingerprints.size === 0)) {
35272
+ _context31.n = 2;
35273
+ break;
35274
+ }
35275
+ return _context31.a(2);
35276
+ case 2:
35277
+ // Sum up total bytes for this entity, including the incoming entry
35278
+ entries = localCacheManager_toConsumableArray(fingerprints).map(function (fp) {
35279
+ return _this7._registry.get(fp);
35280
+ }).filter(function (e) {
35281
+ return !!e;
35282
+ });
35283
+ totalBytes = entries.reduce(function (sum, e) {
35284
+ return sum + e.sizeBytes;
35285
+ }, 0) + incomingSizeBytes;
35286
+ if (!(totalBytes <= limitBytes)) {
35287
+ _context31.n = 3;
35288
+ break;
35289
+ }
35290
+ return _context31.a(2);
35291
+ case 3:
35292
+ // Sort by lastAccessedAt ascending (LRU first)
35293
+ entries.sort(function (a, b) {
35294
+ return a.lastAccessedAt - b.lastAccessedAt;
35295
+ });
35296
+ bytesToFree = totalBytes - limitBytes;
35297
+ if (this._config.verboseLogging) {
35298
+ LogStatusEx({
35299
+ message: " \uD83D\uDDD1\uFE0F [Cache PER-ENTITY EVICT] Entity \"".concat(entityName, "\" using ").concat((totalBytes / 1024 / 1024).toFixed(1), "MB (limit: ").concat((limitBytes / 1024 / 1024).toFixed(1), "MB), evicting LRU entries"),
35300
+ verboseOnly: true
35301
+ });
35302
+ }
35303
+ _iterator21 = localCacheManager_createForOfIteratorHelper(entries);
35304
+ _context31.p = 4;
35305
+ _iterator21.s();
35306
+ case 5:
35307
+ if ((_step21 = _iterator21.n()).done) {
35308
+ _context31.n = 10;
35309
+ break;
35310
+ }
35311
+ entry = _step21.value;
35312
+ if (!(bytesToFree <= 0)) {
35313
+ _context31.n = 6;
35314
+ break;
35315
+ }
35316
+ return _context31.a(3, 10);
35317
+ case 6:
35318
+ _context31.p = 6;
35319
+ category = this.getCategoryForType(entry.type);
35320
+ _context31.n = 7;
35321
+ return this._storageProvider.Remove(entry.key, category);
35322
+ case 7:
35323
+ this.removeFromEntityIndex(entry.key);
35324
+ bytesToFree -= entry.sizeBytes;
35325
+ this._registry.delete(entry.key);
35326
+ _context31.n = 9;
35327
+ break;
35328
+ case 8:
35329
+ _context31.p = 8;
35330
+ _t36 = _context31.v;
35331
+ case 9:
35332
+ _context31.n = 5;
35333
+ break;
35334
+ case 10:
35335
+ _context31.n = 12;
35336
+ break;
35337
+ case 11:
35338
+ _context31.p = 11;
35339
+ _t37 = _context31.v;
35340
+ _iterator21.e(_t37);
35341
+ case 12:
35342
+ _context31.p = 12;
35343
+ _iterator21.f();
35344
+ return _context31.f(12);
35345
+ case 13:
35346
+ this.debouncedPersistRegistry();
35347
+ case 14:
35348
+ return _context31.a(2);
35349
+ }
35350
+ }, _callee31, this, [[6, 8], [4, 11, 12, 13]]);
35351
+ }));
35352
+ function enforcePerEntityMemoryLimit(_x68, _x69) {
35353
+ return _enforcePerEntityMemoryLimit.apply(this, arguments);
35354
+ }
35355
+ return enforcePerEntityMemoryLimit;
35356
+ }()
35357
+ /**
35358
+ * Starts the periodic eviction sweep timer. Called during initialization.
35359
+ * The sweep catches entries that should have been evicted (TTL expired)
35360
+ * but weren't because no new stores triggered eviction.
35361
+ */
35362
+ )
35363
+ }, {
35364
+ key: "startEvictionSweep",
35365
+ value: function startEvictionSweep() {
35366
+ var _this8 = this;
35367
+ this.stopEvictionSweep(); // Clear any existing timer
35368
+ var intervalMs = this._config.evictionSweepIntervalMs;
35369
+ if (intervalMs <= 0) return; // Disabled
35370
+ this._sweepTimer = setInterval(function () {
35371
+ _this8.runEvictionSweep().catch(function (err) {
35372
+ LogError("LocalCacheManager: eviction sweep failed: ".concat(err.message));
35373
+ });
35374
+ }, intervalMs);
35375
+ // Don't prevent Node.js process from exiting
35376
+ if (localCacheManager_typeof(this._sweepTimer) === 'object' && 'unref' in this._sweepTimer) {
35377
+ this._sweepTimer.unref();
35378
+ }
35379
+ }
35380
+ /**
35381
+ * Stops the periodic eviction sweep timer.
35382
+ */
35383
+ }, {
35384
+ key: "stopEvictionSweep",
35385
+ value: function stopEvictionSweep() {
35386
+ if (this._sweepTimer) {
35387
+ clearInterval(this._sweepTimer);
35388
+ this._sweepTimer = null;
35389
+ }
35390
+ }
35391
+ /**
35392
+ * Runs a single eviction sweep: evicts entries that have exceeded their TTL
35393
+ * or entries for entities that are over their per-entity cap.
35394
+ */
35395
+ }, {
35396
+ key: "runEvictionSweep",
35397
+ value: (function () {
35398
+ var _runEvictionSweep = localCacheManager_asyncToGenerator(/*#__PURE__*/localCacheManager_regenerator().m(function _callee32() {
35399
+ var now, ttlMs, toDelete, _iterator22, _step22, _step22$value, _key4, _entry2, _iterator23, _step23, key, entry, category, _t38, _t39, _t40;
35400
+ return localCacheManager_regenerator().w(function (_context32) {
35401
+ while (1) switch (_context32.p = _context32.n) {
35402
+ case 0:
35403
+ if (!(!this._storageProvider || !this._config.enabled)) {
35404
+ _context32.n = 1;
35405
+ break;
35406
+ }
35407
+ return _context32.a(2);
35408
+ case 1:
35409
+ now = Date.now();
35410
+ ttlMs = this._config.defaultTTLMs;
35411
+ toDelete = [];
35412
+ _iterator22 = localCacheManager_createForOfIteratorHelper(this._registry);
35413
+ _context32.p = 2;
35414
+ _iterator22.s();
35415
+ case 3:
35416
+ if ((_step22 = _iterator22.n()).done) {
35417
+ _context32.n = 6;
35418
+ break;
35419
+ }
35420
+ _step22$value = localCacheManager_slicedToArray(_step22.value, 2), _key4 = _step22$value[0], _entry2 = _step22$value[1];
35421
+ if (!(ttlMs > 0 && _entry2.cachedAt + ttlMs < now)) {
35422
+ _context32.n = 4;
35423
+ break;
35424
+ }
35425
+ toDelete.push(_key4);
35426
+ return _context32.a(3, 5);
35427
+ case 4:
35428
+ // expiresAt check (if set individually)
35429
+ if (_entry2.expiresAt && _entry2.expiresAt < now) {
35430
+ toDelete.push(_key4);
35431
+ }
35432
+ case 5:
35433
+ _context32.n = 3;
35434
+ break;
35435
+ case 6:
35436
+ _context32.n = 8;
35437
+ break;
35438
+ case 7:
35439
+ _context32.p = 7;
35440
+ _t38 = _context32.v;
35441
+ _iterator22.e(_t38);
35442
+ case 8:
35443
+ _context32.p = 8;
35444
+ _iterator22.f();
35445
+ return _context32.f(8);
35446
+ case 9:
35447
+ if (!(toDelete.length > 0)) {
35448
+ _context32.n = 20;
35449
+ break;
35450
+ }
35451
+ if (this._config.verboseLogging) {
35452
+ LogStatusEx({
35453
+ message: " \uD83D\uDDD1\uFE0F [Cache SWEEP] Evicting ".concat(toDelete.length, " TTL-expired entries"),
35454
+ verboseOnly: true
35455
+ });
35456
+ }
35457
+ _iterator23 = localCacheManager_createForOfIteratorHelper(toDelete);
35458
+ _context32.p = 10;
35459
+ _iterator23.s();
35460
+ case 11:
35461
+ if ((_step23 = _iterator23.n()).done) {
35462
+ _context32.n = 16;
35463
+ break;
35464
+ }
35465
+ key = _step23.value;
35466
+ _context32.p = 12;
35467
+ entry = this._registry.get(key);
35468
+ category = this.getCategoryForType(entry === null || entry === void 0 ? void 0 : entry.type);
35469
+ _context32.n = 13;
35470
+ return this._storageProvider.Remove(key, category);
35471
+ case 13:
35472
+ if (entry !== null && entry !== void 0 && entry.fingerprint) {
35473
+ this.removeFromEntityIndex(entry.fingerprint);
35474
+ }
35475
+ this._registry.delete(key);
35476
+ _context32.n = 15;
35477
+ break;
35478
+ case 14:
35479
+ _context32.p = 14;
35480
+ _t39 = _context32.v;
35481
+ case 15:
35482
+ _context32.n = 11;
35483
+ break;
35484
+ case 16:
35485
+ _context32.n = 18;
35486
+ break;
35487
+ case 17:
35488
+ _context32.p = 17;
35489
+ _t40 = _context32.v;
35490
+ _iterator23.e(_t40);
35491
+ case 18:
35492
+ _context32.p = 18;
35493
+ _iterator23.f();
35494
+ return _context32.f(18);
35495
+ case 19:
35496
+ _context32.n = 20;
35497
+ return this.persistRegistry();
35498
+ case 20:
35499
+ return _context32.a(2);
35500
+ }
35501
+ }, _callee32, this, [[12, 14], [10, 17, 18, 19], [2, 7, 8, 9]]);
35502
+ }));
35503
+ function runEvictionSweep() {
35504
+ return _runEvictionSweep.apply(this, arguments);
35505
+ }
35506
+ return runEvictionSweep;
35192
35507
  }())
35193
35508
  }], [{
35194
35509
  key: "Instance",
@@ -39408,6 +39723,9 @@ var ProviderBase = /*#__PURE__*/function () {
39408
39723
  if (!params.EntityName) return true; // View-based queries without entity name — allow caching
39409
39724
  var entity = this.EntityByName(params.EntityName);
39410
39725
  if (!entity) return true; // Entity not found — allow caching (will fail later anyway)
39726
+ // If caching is disabled for this entity (neither the per-entity flag nor the
39727
+ // schema-level config enables it), skip all cache operations.
39728
+ if (!LocalCacheManager.Instance.IsCachingEnabledForEntity(entity)) return false;
39411
39729
  // Always exempt Record Changes — rows are created via spCreateRecordChange_Internal
39412
39730
  // inside save SQL batches, never through BaseEntity.Save(), so the cache is never
39413
39731
  // invalidated by entity events. Even if TrustServerCacheCompletely is accidentally
@@ -54123,7 +54441,7 @@ function _regenerator(){/*! regenerator-runtime -- Copyright (c) 2014-present, F
54123
54441
  * zod schema definition for the entity MJ: Encryption Keys
54124
54442
  */var MJEncryptionKeySchema=z.object({ID:z.string().describe("\n * * Field Name: ID\n * * Display Name: ID\n * * SQL Data Type: uniqueidentifier\n * * Default Value: newsequentialid()\n * * Description: Unique identifier for the encryption key configuration."),Name:z.string().describe("\n * * Field Name: Name\n * * Display Name: Name\n * * SQL Data Type: nvarchar(100)\n * * Description: Unique name for this key (e.g., PII Master Key, API Secrets Key)."),Description:z.string().nullable().describe("\n * * Field Name: Description\n * * Display Name: Description\n * * SQL Data Type: nvarchar(MAX)\n * * Description: Description of this key purpose and scope."),EncryptionKeySourceID:z.string().describe("\n * * Field Name: EncryptionKeySourceID\n * * Display Name: Encryption Key Source ID\n * * SQL Data Type: uniqueidentifier\n * * Related Entity/Foreign Key: MJ: Encryption Key Sources (vwEncryptionKeySources.ID)\n * * Description: References the key source that provides the key material."),EncryptionAlgorithmID:z.string().describe("\n * * Field Name: EncryptionAlgorithmID\n * * Display Name: Encryption Algorithm ID\n * * SQL Data Type: uniqueidentifier\n * * Related Entity/Foreign Key: MJ: Encryption Algorithms (vwEncryptionAlgorithms.ID)\n * * Description: References the algorithm to use for encryption/decryption."),KeyLookupValue:z.string().describe("\n * * Field Name: KeyLookupValue\n * * Display Name: Key Lookup Value\n * * SQL Data Type: nvarchar(500)\n * * Description: Source-specific lookup value (e.g., environment variable name, vault path)."),KeyVersion:z.string().describe("\n * * Field Name: KeyVersion\n * * Display Name: Key Version\n * * SQL Data Type: nvarchar(20)\n * * Default Value: 1\n * * Description: Version string for key rotation tracking. Incremented during rotation."),Marker:z.string().describe("\n * * Field Name: Marker\n * * Display Name: Marker\n * * SQL Data Type: nvarchar(20)\n * * Default Value: $ENC$\n * * Description: Prefix marker for encrypted values (default: $ENC$)."),IsActive:z.boolean().describe("\n * * Field Name: IsActive\n * * Display Name: Is Active\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Whether this key can be used for new encryption operations."),Status:z.union([z.literal('Active'),z.literal('Expired'),z.literal('Inactive'),z.literal('Rotating')]).describe("\n * * Field Name: Status\n * * Display Name: Status\n * * SQL Data Type: nvarchar(20)\n * * Default Value: Active\n * * Value List Type: List\n * * Possible Values \n * * Active\n * * Expired\n * * Inactive\n * * Rotating\n * * Description: Current status: Active, Inactive, Rotating, or Expired."),ActivatedAt:z.date().nullable().describe("\n * * Field Name: ActivatedAt\n * * Display Name: Activated At\n * * SQL Data Type: datetimeoffset\n * * Description: When the current key version was activated."),ExpiresAt:z.date().nullable().describe("\n * * Field Name: ExpiresAt\n * * Display Name: Expires At\n * * SQL Data Type: datetimeoffset\n * * Description: Optional expiration date. Keys past this date cannot be used for new encryption."),__mj_CreatedAt:z.date().describe("\n * * Field Name: __mj_CreatedAt\n * * Display Name: Created At\n * * SQL Data Type: datetimeoffset\n * * Default Value: getutcdate()"),__mj_UpdatedAt:z.date().describe("\n * * Field Name: __mj_UpdatedAt\n * * Display Name: Updated At\n * * SQL Data Type: datetimeoffset\n * * Default Value: getutcdate()"),EncryptionKeySource:z.string().describe("\n * * Field Name: EncryptionKeySource\n * * Display Name: Encryption Key Source\n * * SQL Data Type: nvarchar(100)"),EncryptionAlgorithm:z.string().describe("\n * * Field Name: EncryptionAlgorithm\n * * Display Name: Encryption Algorithm\n * * SQL Data Type: nvarchar(50)")});/**
54125
54443
  * zod schema definition for the entity MJ: Entities
54126
- */var MJEntitySchema=z.object({ID:z.string().describe("\n * * Field Name: ID\n * * Display Name: ID\n * * SQL Data Type: uniqueidentifier\n * * Default Value: newsequentialid()"),ParentID:z.string().nullable().describe("\n * * Field Name: ParentID\n * * Display Name: Parent\n * * SQL Data Type: uniqueidentifier\n * * Related Entity/Foreign Key: MJ: Entities (vwEntities.ID)"),Name:z.string().describe("\n * * Field Name: Name\n * * Display Name: Name\n * * SQL Data Type: nvarchar(255)\n * * Description: The canonical, unique name for this entity. For entities in schemas with an EntityNamePrefix configured (e.g., \"MJ: \" for the core schema), the Name includes the prefix: \"MJ: AI Models\", \"MJ: Users\", etc. This is the value used in GetEntityObject(), RunView({ EntityName }), and @RegisterClass decorators. The DisplayName column provides the shorter, UI-friendly alternative without the prefix."),NameSuffix:z.string().nullable().describe("\n * * Field Name: NameSuffix\n * * Display Name: Name Suffix\n * * SQL Data Type: nvarchar(255)\n * * Description: Optional suffix appended to entity names for display purposes."),Description:z.string().nullable().describe("\n * * Field Name: Description\n * * Display Name: Description\n * * SQL Data Type: nvarchar(MAX)"),AutoUpdateDescription:z.boolean().describe("\n * * Field Name: AutoUpdateDescription\n * * Display Name: Auto Update Description\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When set to 1 (default), whenever a description is modified in the underlying view (first choice) or table (second choice), the Description column in the entity definition will be automatically updated. If you never set metadata in the database directly, you can leave this alone. However, if you have metadata set in the database level for description, and you want to provide a DIFFERENT description in this entity definition, turn this bit off and then set the Description field and future CodeGen runs will NOT override the Description field here."),BaseTable:z.string().describe("\n * * Field Name: BaseTable\n * * Display Name: Base Table\n * * SQL Data Type: nvarchar(255)\n * * Description: The underlying database table name for this entity."),BaseView:z.string().describe("\n * * Field Name: BaseView\n * * Display Name: Base View\n * * SQL Data Type: nvarchar(255)\n * * Description: The \"wrapper\" database view used for querying this entity with joins and computed fields."),BaseViewGenerated:z.boolean().describe("\n * * Field Name: BaseViewGenerated\n * * Display Name: Base View Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When set to 0, CodeGen no longer generates a base view for the entity."),SchemaName:z.string().describe("\n * * Field Name: SchemaName\n * * Display Name: Schema Name\n * * SQL Data Type: nvarchar(255)\n * * Default Value: dbo\n * * Description: Database schema containing this entity's table and view."),VirtualEntity:z.boolean().describe("\n * * Field Name: VirtualEntity\n * * Display Name: Virtual Entity\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Indicates if this is a virtual entity without a physical database table."),TrackRecordChanges:z.boolean().describe("\n * * Field Name: TrackRecordChanges\n * * Display Name: Track Record Changes\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When set to 1, changes made via the MemberJunction architecture will result in tracking records being created in the RecordChange table. In addition, when turned on CodeGen will ensure that your table has two fields: __mj_CreatedAt and __mj_UpdatedAt which are special fields used in conjunction with the RecordChange table to track changes to rows in your entity."),AuditRecordAccess:z.boolean().describe("\n * * Field Name: AuditRecordAccess\n * * Display Name: Audit Record Access\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When set to 1, accessing a record by an end-user will result in an Audit Log record being created"),AuditViewRuns:z.boolean().describe("\n * * Field Name: AuditViewRuns\n * * Display Name: Audit View Runs\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When set to 1, users running a view against this entity will result in an Audit Log record being created."),IncludeInAPI:z.boolean().describe("\n * * Field Name: IncludeInAPI\n * * Display Name: Include In API\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: If set to 0, the entity will not be available at all in the GraphQL API or the object model."),AllowAllRowsAPI:z.boolean().describe("\n * * Field Name: AllowAllRowsAPI\n * * Display Name: Allow All Rows API\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: If set to 1, a GraphQL query will be enabled that allows access to all rows in the entity."),AllowUpdateAPI:z.boolean().describe("\n * * Field Name: AllowUpdateAPI\n * * Display Name: Allow Update API\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Global flag controlling if updates are allowed for any user, or not. If set to 1, a GraqhQL mutation and stored procedure are created. Permissions are still required to perform the action but if this flag is set to 0, no user will be able to perform the action."),AllowCreateAPI:z.boolean().describe("\n * * Field Name: AllowCreateAPI\n * * Display Name: Allow Create API\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Global flag controlling if creates are allowed for any user, or not. If set to 1, a GraqhQL mutation and stored procedure are created. Permissions are still required to perform the action but if this flag is set to 0, no user will be able to perform the action."),AllowDeleteAPI:z.boolean().describe("\n * * Field Name: AllowDeleteAPI\n * * Display Name: Allow Delete API\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Global flag controlling if deletes are allowed for any user, or not. If set to 1, a GraqhQL mutation and stored procedure are created. Permissions are still required to perform the action but if this flag is set to 0, no user will be able to perform the action."),CustomResolverAPI:z.boolean().describe("\n * * Field Name: CustomResolverAPI\n * * Display Name: Custom Resolver API\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Set to 1 if a custom resolver has been created for the entity."),AllowUserSearchAPI:z.boolean().describe("\n * * Field Name: AllowUserSearchAPI\n * * Display Name: Allow User Search\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Enabling this bit will result in search being possible at the API and UI layers"),FullTextSearchEnabled:z.boolean().describe("\n * * Field Name: FullTextSearchEnabled\n * * Display Name: Full-Text Search Enabled\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Whether full-text search indexing is enabled for this entity."),FullTextCatalog:z.string().nullable().describe("\n * * Field Name: FullTextCatalog\n * * Display Name: Full-Text Catalog\n * * SQL Data Type: nvarchar(255)\n * * Description: Name of the SQL Server full-text catalog if search is enabled."),FullTextCatalogGenerated:z.boolean().describe("\n * * Field Name: FullTextCatalogGenerated\n * * Display Name: Full-Text Catalog Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the full-text catalog was auto-generated by CodeGen."),FullTextIndex:z.string().nullable().describe("\n * * Field Name: FullTextIndex\n * * Display Name: Full-Text Index\n * * SQL Data Type: nvarchar(255)\n * * Description: Name of the full-text index on this entity's table."),FullTextIndexGenerated:z.boolean().describe("\n * * Field Name: FullTextIndexGenerated\n * * Display Name: Full-Text Index Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the full-text index was auto-generated by CodeGen."),FullTextSearchFunction:z.string().nullable().describe("\n * * Field Name: FullTextSearchFunction\n * * Display Name: Search Function\n * * SQL Data Type: nvarchar(255)\n * * Description: Name of the function used for full-text searching this entity."),FullTextSearchFunctionGenerated:z.boolean().describe("\n * * Field Name: FullTextSearchFunctionGenerated\n * * Display Name: Search Function Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the search function was auto-generated by CodeGen."),UserViewMaxRows:z.number().nullable().describe("\n * * Field Name: UserViewMaxRows\n * * Display Name: User View Max Rows\n * * SQL Data Type: int\n * * Default Value: 1000\n * * Description: Maximum number of rows to return in user-created views for this entity."),spCreate:z.string().nullable().describe("\n * * Field Name: spCreate\n * * Display Name: Create Procedure\n * * SQL Data Type: nvarchar(255)\n * * Description: Name of the stored procedure for creating records in this entity."),spUpdate:z.string().nullable().describe("\n * * Field Name: spUpdate\n * * Display Name: Update Procedure\n * * SQL Data Type: nvarchar(255)\n * * Description: Name of the stored procedure for updating records in this entity."),spDelete:z.string().nullable().describe("\n * * Field Name: spDelete\n * * Display Name: Delete Procedure\n * * SQL Data Type: nvarchar(255)\n * * Description: Name of the stored procedure for deleting records in this entity."),spCreateGenerated:z.boolean().describe("\n * * Field Name: spCreateGenerated\n * * Display Name: Create SP Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the create procedure was auto-generated by CodeGen."),spUpdateGenerated:z.boolean().describe("\n * * Field Name: spUpdateGenerated\n * * Display Name: Update SP Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the update procedure was auto-generated by CodeGen."),spDeleteGenerated:z.boolean().describe("\n * * Field Name: spDeleteGenerated\n * * Display Name: Delete SP Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the delete procedure was auto-generated by CodeGen."),CascadeDeletes:z.boolean().describe("\n * * Field Name: CascadeDeletes\n * * Display Name: Cascade Deletes\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: When set to 1, the deleted spDelete will pre-process deletion to related entities that have 1:M cardinality with this entity. This does not have effect if spDeleteGenerated = 0"),DeleteType:z.union([z.literal('Hard'),z.literal('Soft')]).describe("\n * * Field Name: DeleteType\n * * Display Name: Delete Type\n * * SQL Data Type: nvarchar(10)\n * * Default Value: Hard\n * * Value List Type: List\n * * Possible Values \n * * Hard\n * * Soft\n * * Description: Hard deletes physically remove rows from the underlying BaseTable. Soft deletes do not remove rows but instead mark the row as deleted by using the special field __mj_DeletedAt which will automatically be added to the entity's basetable by the CodeGen tool."),AllowRecordMerge:z.boolean().describe("\n * * Field Name: AllowRecordMerge\n * * Display Name: Allow Record Merge\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: This field must be turned on in order to enable merging of records for the entity. For AllowRecordMerge to be turned on, AllowDeleteAPI must be set to 1, and DeleteType must be set to Soft"),spMatch:z.string().nullable().describe("\n * * Field Name: spMatch\n * * Display Name: Match Procedure\n * * SQL Data Type: nvarchar(255)\n * * Description: When specified, this stored procedure is used to find matching records in this particular entity. The convention is to pass in the primary key(s) columns for the given entity to the procedure and the return will be zero to many rows where there is a column for each primary key field(s) and a ProbabilityScore (numeric(1,12)) column that has a 0 to 1 value of the probability of a match."),RelationshipDefaultDisplayType:z.union([z.literal('Dropdown'),z.literal('Search')]).describe("\n * * Field Name: RelationshipDefaultDisplayType\n * * Display Name: Default Relationship Display Type\n * * SQL Data Type: nvarchar(20)\n * * Default Value: Search\n * * Value List Type: List\n * * Possible Values \n * * Dropdown\n * * Search\n * * Description: When another entity links to this entity with a foreign key, this is the default component type that will be used in the UI. CodeGen will populate the RelatedEntityDisplayType column in the Entity Fields entity with whatever is provided here whenever a new foreign key is detected by CodeGen. The selection can be overridden on a per-foreign-key basis in each row of the Entity Fields entity."),UserFormGenerated:z.boolean().describe("\n * * Field Name: UserFormGenerated\n * * Display Name: User Form Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the default user form was auto-generated for this entity."),EntityObjectSubclassName:z.string().nullable().describe("\n * * Field Name: EntityObjectSubclassName\n * * Display Name: Subclass Name\n * * SQL Data Type: nvarchar(255)\n * * Description: TypeScript class name for the entity subclass in the codebase."),EntityObjectSubclassImport:z.string().nullable().describe("\n * * Field Name: EntityObjectSubclassImport\n * * Display Name: Subclass Import Path\n * * SQL Data Type: nvarchar(255)\n * * Description: Import path for the entity subclass in the TypeScript codebase."),PreferredCommunicationField:z.string().nullable().describe("\n * * Field Name: PreferredCommunicationField\n * * Display Name: Preferred Communication Field\n * * SQL Data Type: nvarchar(255)\n * * Description: Used to specify a field within the entity that in turn contains the field name that will be used for record-level communication preferences. For example in a hypothetical entity called Contacts, say there is a field called PreferredComm and that field had possible values of Email1, SMS, and Phone, and those value in turn corresponded to field names in the entity. Each record in the Contacts entity could have a specific preference for which field would be used for communication. The MJ Communication Framework will use this information when available, as a priority ahead of the data in the Entity Communication Fields entity which is entity-level and not record-level."),Icon:z.string().nullable().describe("\n * * Field Name: Icon\n * * Display Name: Icon\n * * SQL Data Type: nvarchar(500)\n * * Description: Optional, specify an icon (CSS Class) for each entity for display in the UI"),__mj_CreatedAt:z.date().describe("\n * * Field Name: __mj_CreatedAt\n * * Display Name: Created At\n * * SQL Data Type: datetimeoffset\n * * Default Value: getutcdate()"),__mj_UpdatedAt:z.date().describe("\n * * Field Name: __mj_UpdatedAt\n * * Display Name: Updated At\n * * SQL Data Type: datetimeoffset\n * * Default Value: getutcdate()"),ScopeDefault:z.string().nullable().describe("\n * * Field Name: ScopeDefault\n * * Display Name: Default Scope\n * * SQL Data Type: nvarchar(100)\n * * Description: Optional, comma-delimited string indicating the default scope for entity visibility. Options include Users, Admins, AI, and All. Defaults to All when NULL. This is used for simple defaults for filtering entity visibility, not security enforcement."),RowsToPackWithSchema:z.union([z.literal('All'),z.literal('None'),z.literal('Sample')]).describe("\n * * Field Name: RowsToPackWithSchema\n * * Display Name: Rows To Pack\n * * SQL Data Type: nvarchar(20)\n * * Default Value: None\n * * Value List Type: List\n * * Possible Values \n * * All\n * * None\n * * Sample\n * * Description: Determines how entity rows should be packaged for external use. Options include None, Sample, and All. Defaults to None."),RowsToPackSampleMethod:z.union([z.literal('bottom n'),z.literal('random'),z.literal('top n')]).describe("\n * * Field Name: RowsToPackSampleMethod\n * * Display Name: Packing Sample Method\n * * SQL Data Type: nvarchar(20)\n * * Default Value: random\n * * Value List Type: List\n * * Possible Values \n * * bottom n\n * * random\n * * top n\n * * Description: Defines the sampling method for row packing when RowsToPackWithSchema is set to Sample. Options include random, top n, and bottom n. Defaults to random."),RowsToPackSampleCount:z.number().describe("\n * * Field Name: RowsToPackSampleCount\n * * Display Name: Packing Sample Count\n * * SQL Data Type: int\n * * Default Value: 0\n * * Description: The number of rows to pack when RowsToPackWithSchema is set to Sample, based on the designated sampling method. Defaults to 0."),RowsToPackSampleOrder:z.string().nullable().describe("\n * * Field Name: RowsToPackSampleOrder\n * * Display Name: Packing Sample Order\n * * SQL Data Type: nvarchar(MAX)\n * * Description: An optional ORDER BY clause for row packing when RowsToPackWithSchema is set to Sample. Allows custom ordering for selected entity data when using top n and bottom n."),AutoRowCountFrequency:z.number().nullable().describe("\n * * Field Name: AutoRowCountFrequency\n * * Display Name: Refresh Frequency (Hours)\n * * SQL Data Type: int\n * * Description: Frequency in hours for automatically performing row counts on this entity. If NULL, automatic row counting is disabled. If greater than 0, schedules recurring SELECT COUNT(*) queries at the specified interval."),RowCount:z.number().nullable().describe("\n * * Field Name: RowCount\n * * Display Name: Row Count\n * * SQL Data Type: bigint\n * * Description: Cached row count for this entity, populated by automatic row count processes when AutoRowCountFrequency is configured."),RowCountRunAt:z.date().nullable().describe("\n * * Field Name: RowCountRunAt\n * * Display Name: Last Counted At\n * * SQL Data Type: datetimeoffset\n * * Description: Timestamp indicating when the last automatic row count was performed for this entity."),Status:z.union([z.literal('Active'),z.literal('Deprecated'),z.literal('Disabled')]).describe("\n * * Field Name: Status\n * * Display Name: Status\n * * SQL Data Type: nvarchar(25)\n * * Default Value: Active\n * * Value List Type: List\n * * Possible Values \n * * Active\n * * Deprecated\n * * Disabled\n * * Description: Status of the entity. Active: fully functional; Deprecated: functional but generates console warnings when used; Disabled: not available for use even though metadata and physical table remain."),DisplayName:z.string().nullable().describe("\n * * Field Name: DisplayName\n * * Display Name: Display Name\n * * SQL Data Type: nvarchar(255)\n * * Description: User-friendly display name shown in the Explorer UI and other interfaces. When set, this is used instead of the entity Name for display purposes. Typically contains the entity name without the schema prefix \u2014 e.g., \"AI Models\" when Name is \"MJ: AI Models\". If NULL, the UI falls back to using the full Name."),AllowMultipleSubtypes:z.boolean().describe("\n * * Field Name: AllowMultipleSubtypes\n * * Display Name: Allow Multiple Subtypes\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: When false (default), child types are disjoint - a record can only be one child type at a time. When true, a record can simultaneously exist as multiple child types (e.g., a Person can be both a Member and a Volunteer)."),AutoUpdateFullTextSearch:z.boolean().describe("\n * * Field Name: AutoUpdateFullTextSearch\n * * Display Name: Auto Update Search Settings\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When true, CodeGen LLM can auto-configure full-text search settings (FullTextSearchEnabled, catalog, index, function) during code generation runs."),AutoUpdateAllowUserSearchAPI:z.boolean().describe("\n * * Field Name: AutoUpdateAllowUserSearchAPI\n * * Display Name: Auto Update Search API\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When true, CodeGen LLM can auto-set AllowUserSearchAPI during code generation runs."),TrustServerCacheCompletely:z.boolean().describe("\n * * Field Name: TrustServerCacheCompletely\n * * Display Name: Trust Server Cache\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When true (default), the server-side RunView cache will store and return cached results for this entity, trusting that all mutations flow through BaseEntity.Save() which fires cache invalidation events. Set to false for entities whose rows are created as side-effects of other operations via raw SQL (e.g., Record Changes created by spCreateRecordChange_Internal), since those inserts bypass BaseEntity and never trigger cache invalidation."),SupportsGeoCoding:z.boolean().describe("\n * * Field Name: SupportsGeoCoding\n * * Display Name: Supports Geo-Coding\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: When true, CodeGen generates geo-aware subclass code, adds __mj_Latitude/__mj_Longitude virtual fields to the base view, and the UI shows a map view toggle. Auto-set by CodeGen when LLM detects geo-capable fields (address, lat/lng, etc.)."),AutoUpdateSupportsGeoCoding:z.boolean().describe("\n * * Field Name: AutoUpdateSupportsGeoCoding\n * * Display Name: Auto Update Geo-Coding\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When true (default), CodeGen can automatically set SupportsGeoCoding based on LLM analysis of entity fields. Set to 0 to lock the value and prevent CodeGen from changing it."),CodeName:z.string().nullable().describe("\n * * Field Name: CodeName\n * * Display Name: Code Name\n * * SQL Data Type: nvarchar(MAX)\n * * Description: Schema-based programmatic code name derived from the entity Name. Uses GetClassNameSchemaPrefix(SchemaName) as the prefix, then strips EntityNamePrefix from the Name and removes spaces. For \"__mj\" schema with entity \"MJ: AI Models\", this produces \"MJAIModels\". For entities in other schemas, the sanitized schema name is prepended. Used in GraphQL type generation and internal code references."),ClassName:z.string().nullable().describe("\n * * Field Name: ClassName\n * * Display Name: Class Name\n * * SQL Data Type: nvarchar(MAX)\n * * Description: Schema-based programmatic class name used for TypeScript entity classes, Zod schemas, and Angular form components. Computed as GetProgrammaticName(GetClassNameSchemaPrefix(SchemaName) + BaseTable + NameSuffix). The prefix is derived from SchemaName (guaranteed unique by SQL Server), not from EntityNamePrefix. For the core __mj schema, the prefix is \"MJ\"; for all other schemas it is the alphanumeric-sanitized schema name. This prevents cross-schema collisions and aligns with GraphQL type naming in getGraphQLTypeNameBase()."),BaseTableCodeName:z.string().nullable().describe("\n * * Field Name: BaseTableCodeName\n * * Display Name: Base Table Code Name\n * * SQL Data Type: nvarchar(MAX)"),ParentEntity:z.string().nullable().describe("\n * * Field Name: ParentEntity\n * * Display Name: Parent Entity\n * * SQL Data Type: nvarchar(255)"),ParentBaseTable:z.string().nullable().describe("\n * * Field Name: ParentBaseTable\n * * Display Name: Parent Base Table\n * * SQL Data Type: nvarchar(255)"),ParentBaseView:z.string().nullable().describe("\n * * Field Name: ParentBaseView\n * * Display Name: Parent Base View\n * * SQL Data Type: nvarchar(255)")});/**
54444
+ */var MJEntitySchema=z.object({ID:z.string().describe("\n * * Field Name: ID\n * * Display Name: ID\n * * SQL Data Type: uniqueidentifier\n * * Default Value: newsequentialid()"),ParentID:z.string().nullable().describe("\n * * Field Name: ParentID\n * * Display Name: Parent\n * * SQL Data Type: uniqueidentifier\n * * Related Entity/Foreign Key: MJ: Entities (vwEntities.ID)"),Name:z.string().describe("\n * * Field Name: Name\n * * Display Name: Name\n * * SQL Data Type: nvarchar(255)\n * * Description: The canonical, unique name for this entity. For entities in schemas with an EntityNamePrefix configured (e.g., \"MJ: \" for the core schema), the Name includes the prefix: \"MJ: AI Models\", \"MJ: Users\", etc. This is the value used in GetEntityObject(), RunView({ EntityName }), and @RegisterClass decorators. The DisplayName column provides the shorter, UI-friendly alternative without the prefix."),NameSuffix:z.string().nullable().describe("\n * * Field Name: NameSuffix\n * * Display Name: Name Suffix\n * * SQL Data Type: nvarchar(255)\n * * Description: Optional suffix appended to entity names for display purposes."),Description:z.string().nullable().describe("\n * * Field Name: Description\n * * Display Name: Description\n * * SQL Data Type: nvarchar(MAX)"),AutoUpdateDescription:z.boolean().describe("\n * * Field Name: AutoUpdateDescription\n * * Display Name: Auto Update Description\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When set to 1 (default), whenever a description is modified in the underlying view (first choice) or table (second choice), the Description column in the entity definition will be automatically updated. If you never set metadata in the database directly, you can leave this alone. However, if you have metadata set in the database level for description, and you want to provide a DIFFERENT description in this entity definition, turn this bit off and then set the Description field and future CodeGen runs will NOT override the Description field here."),BaseTable:z.string().describe("\n * * Field Name: BaseTable\n * * Display Name: Base Table\n * * SQL Data Type: nvarchar(255)\n * * Description: The underlying database table name for this entity."),BaseView:z.string().describe("\n * * Field Name: BaseView\n * * Display Name: Base View\n * * SQL Data Type: nvarchar(255)\n * * Description: The \"wrapper\" database view used for querying this entity with joins and computed fields."),BaseViewGenerated:z.boolean().describe("\n * * Field Name: BaseViewGenerated\n * * Display Name: Base View Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When set to 0, CodeGen no longer generates a base view for the entity."),SchemaName:z.string().describe("\n * * Field Name: SchemaName\n * * Display Name: Schema Name\n * * SQL Data Type: nvarchar(255)\n * * Default Value: dbo\n * * Description: Database schema containing this entity's table and view."),VirtualEntity:z.boolean().describe("\n * * Field Name: VirtualEntity\n * * Display Name: Virtual Entity\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Indicates if this is a virtual entity without a physical database table."),TrackRecordChanges:z.boolean().describe("\n * * Field Name: TrackRecordChanges\n * * Display Name: Track Record Changes\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When set to 1, changes made via the MemberJunction architecture will result in tracking records being created in the RecordChange table. In addition, when turned on CodeGen will ensure that your table has two fields: __mj_CreatedAt and __mj_UpdatedAt which are special fields used in conjunction with the RecordChange table to track changes to rows in your entity."),AuditRecordAccess:z.boolean().describe("\n * * Field Name: AuditRecordAccess\n * * Display Name: Audit Record Access\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When set to 1, accessing a record by an end-user will result in an Audit Log record being created"),AuditViewRuns:z.boolean().describe("\n * * Field Name: AuditViewRuns\n * * Display Name: Audit View Runs\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When set to 1, users running a view against this entity will result in an Audit Log record being created."),IncludeInAPI:z.boolean().describe("\n * * Field Name: IncludeInAPI\n * * Display Name: Include In API\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: If set to 0, the entity will not be available at all in the GraphQL API or the object model."),AllowAllRowsAPI:z.boolean().describe("\n * * Field Name: AllowAllRowsAPI\n * * Display Name: Allow All Rows API\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: If set to 1, a GraphQL query will be enabled that allows access to all rows in the entity."),AllowUpdateAPI:z.boolean().describe("\n * * Field Name: AllowUpdateAPI\n * * Display Name: Allow Update API\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Global flag controlling if updates are allowed for any user, or not. If set to 1, a GraqhQL mutation and stored procedure are created. Permissions are still required to perform the action but if this flag is set to 0, no user will be able to perform the action."),AllowCreateAPI:z.boolean().describe("\n * * Field Name: AllowCreateAPI\n * * Display Name: Allow Create API\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Global flag controlling if creates are allowed for any user, or not. If set to 1, a GraqhQL mutation and stored procedure are created. Permissions are still required to perform the action but if this flag is set to 0, no user will be able to perform the action."),AllowDeleteAPI:z.boolean().describe("\n * * Field Name: AllowDeleteAPI\n * * Display Name: Allow Delete API\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Global flag controlling if deletes are allowed for any user, or not. If set to 1, a GraqhQL mutation and stored procedure are created. Permissions are still required to perform the action but if this flag is set to 0, no user will be able to perform the action."),CustomResolverAPI:z.boolean().describe("\n * * Field Name: CustomResolverAPI\n * * Display Name: Custom Resolver API\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Set to 1 if a custom resolver has been created for the entity."),AllowUserSearchAPI:z.boolean().describe("\n * * Field Name: AllowUserSearchAPI\n * * Display Name: Allow User Search\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Enabling this bit will result in search being possible at the API and UI layers"),FullTextSearchEnabled:z.boolean().describe("\n * * Field Name: FullTextSearchEnabled\n * * Display Name: Full-Text Search Enabled\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Whether full-text search indexing is enabled for this entity."),FullTextCatalog:z.string().nullable().describe("\n * * Field Name: FullTextCatalog\n * * Display Name: Full-Text Catalog\n * * SQL Data Type: nvarchar(255)\n * * Description: Name of the SQL Server full-text catalog if search is enabled."),FullTextCatalogGenerated:z.boolean().describe("\n * * Field Name: FullTextCatalogGenerated\n * * Display Name: Full-Text Catalog Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the full-text catalog was auto-generated by CodeGen."),FullTextIndex:z.string().nullable().describe("\n * * Field Name: FullTextIndex\n * * Display Name: Full-Text Index\n * * SQL Data Type: nvarchar(255)\n * * Description: Name of the full-text index on this entity's table."),FullTextIndexGenerated:z.boolean().describe("\n * * Field Name: FullTextIndexGenerated\n * * Display Name: Full-Text Index Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the full-text index was auto-generated by CodeGen."),FullTextSearchFunction:z.string().nullable().describe("\n * * Field Name: FullTextSearchFunction\n * * Display Name: Search Function\n * * SQL Data Type: nvarchar(255)\n * * Description: Name of the function used for full-text searching this entity."),FullTextSearchFunctionGenerated:z.boolean().describe("\n * * Field Name: FullTextSearchFunctionGenerated\n * * Display Name: Search Function Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the search function was auto-generated by CodeGen."),UserViewMaxRows:z.number().nullable().describe("\n * * Field Name: UserViewMaxRows\n * * Display Name: User View Max Rows\n * * SQL Data Type: int\n * * Default Value: 1000\n * * Description: Maximum number of rows to return in user-created views for this entity."),spCreate:z.string().nullable().describe("\n * * Field Name: spCreate\n * * Display Name: Create Procedure\n * * SQL Data Type: nvarchar(255)\n * * Description: Name of the stored procedure for creating records in this entity."),spUpdate:z.string().nullable().describe("\n * * Field Name: spUpdate\n * * Display Name: Update Procedure\n * * SQL Data Type: nvarchar(255)\n * * Description: Name of the stored procedure for updating records in this entity."),spDelete:z.string().nullable().describe("\n * * Field Name: spDelete\n * * Display Name: Delete Procedure\n * * SQL Data Type: nvarchar(255)\n * * Description: Name of the stored procedure for deleting records in this entity."),spCreateGenerated:z.boolean().describe("\n * * Field Name: spCreateGenerated\n * * Display Name: Create SP Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the create procedure was auto-generated by CodeGen."),spUpdateGenerated:z.boolean().describe("\n * * Field Name: spUpdateGenerated\n * * Display Name: Update SP Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the update procedure was auto-generated by CodeGen."),spDeleteGenerated:z.boolean().describe("\n * * Field Name: spDeleteGenerated\n * * Display Name: Delete SP Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the delete procedure was auto-generated by CodeGen."),CascadeDeletes:z.boolean().describe("\n * * Field Name: CascadeDeletes\n * * Display Name: Cascade Deletes\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: When set to 1, the deleted spDelete will pre-process deletion to related entities that have 1:M cardinality with this entity. This does not have effect if spDeleteGenerated = 0"),DeleteType:z.union([z.literal('Hard'),z.literal('Soft')]).describe("\n * * Field Name: DeleteType\n * * Display Name: Delete Type\n * * SQL Data Type: nvarchar(10)\n * * Default Value: Hard\n * * Value List Type: List\n * * Possible Values \n * * Hard\n * * Soft\n * * Description: Hard deletes physically remove rows from the underlying BaseTable. Soft deletes do not remove rows but instead mark the row as deleted by using the special field __mj_DeletedAt which will automatically be added to the entity's basetable by the CodeGen tool."),AllowRecordMerge:z.boolean().describe("\n * * Field Name: AllowRecordMerge\n * * Display Name: Allow Record Merge\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: This field must be turned on in order to enable merging of records for the entity. For AllowRecordMerge to be turned on, AllowDeleteAPI must be set to 1, and DeleteType must be set to Soft"),spMatch:z.string().nullable().describe("\n * * Field Name: spMatch\n * * Display Name: Match Procedure\n * * SQL Data Type: nvarchar(255)\n * * Description: When specified, this stored procedure is used to find matching records in this particular entity. The convention is to pass in the primary key(s) columns for the given entity to the procedure and the return will be zero to many rows where there is a column for each primary key field(s) and a ProbabilityScore (numeric(1,12)) column that has a 0 to 1 value of the probability of a match."),RelationshipDefaultDisplayType:z.union([z.literal('Dropdown'),z.literal('Search')]).describe("\n * * Field Name: RelationshipDefaultDisplayType\n * * Display Name: Default Relationship Display Type\n * * SQL Data Type: nvarchar(20)\n * * Default Value: Search\n * * Value List Type: List\n * * Possible Values \n * * Dropdown\n * * Search\n * * Description: When another entity links to this entity with a foreign key, this is the default component type that will be used in the UI. CodeGen will populate the RelatedEntityDisplayType column in the Entity Fields entity with whatever is provided here whenever a new foreign key is detected by CodeGen. The selection can be overridden on a per-foreign-key basis in each row of the Entity Fields entity."),UserFormGenerated:z.boolean().describe("\n * * Field Name: UserFormGenerated\n * * Display Name: User Form Generated\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: Indicates if the default user form was auto-generated for this entity."),EntityObjectSubclassName:z.string().nullable().describe("\n * * Field Name: EntityObjectSubclassName\n * * Display Name: Subclass Name\n * * SQL Data Type: nvarchar(255)\n * * Description: TypeScript class name for the entity subclass in the codebase."),EntityObjectSubclassImport:z.string().nullable().describe("\n * * Field Name: EntityObjectSubclassImport\n * * Display Name: Subclass Import Path\n * * SQL Data Type: nvarchar(255)\n * * Description: Import path for the entity subclass in the TypeScript codebase."),PreferredCommunicationField:z.string().nullable().describe("\n * * Field Name: PreferredCommunicationField\n * * Display Name: Preferred Communication Field\n * * SQL Data Type: nvarchar(255)\n * * Description: Used to specify a field within the entity that in turn contains the field name that will be used for record-level communication preferences. For example in a hypothetical entity called Contacts, say there is a field called PreferredComm and that field had possible values of Email1, SMS, and Phone, and those value in turn corresponded to field names in the entity. Each record in the Contacts entity could have a specific preference for which field would be used for communication. The MJ Communication Framework will use this information when available, as a priority ahead of the data in the Entity Communication Fields entity which is entity-level and not record-level."),Icon:z.string().nullable().describe("\n * * Field Name: Icon\n * * Display Name: Icon\n * * SQL Data Type: nvarchar(500)\n * * Description: Optional, specify an icon (CSS Class) for each entity for display in the UI"),__mj_CreatedAt:z.date().describe("\n * * Field Name: __mj_CreatedAt\n * * Display Name: Created At\n * * SQL Data Type: datetimeoffset\n * * Default Value: getutcdate()"),__mj_UpdatedAt:z.date().describe("\n * * Field Name: __mj_UpdatedAt\n * * Display Name: Updated At\n * * SQL Data Type: datetimeoffset\n * * Default Value: getutcdate()"),ScopeDefault:z.string().nullable().describe("\n * * Field Name: ScopeDefault\n * * Display Name: Default Scope\n * * SQL Data Type: nvarchar(100)\n * * Description: Optional, comma-delimited string indicating the default scope for entity visibility. Options include Users, Admins, AI, and All. Defaults to All when NULL. This is used for simple defaults for filtering entity visibility, not security enforcement."),RowsToPackWithSchema:z.union([z.literal('All'),z.literal('None'),z.literal('Sample')]).describe("\n * * Field Name: RowsToPackWithSchema\n * * Display Name: Rows To Pack\n * * SQL Data Type: nvarchar(20)\n * * Default Value: None\n * * Value List Type: List\n * * Possible Values \n * * All\n * * None\n * * Sample\n * * Description: Determines how entity rows should be packaged for external use. Options include None, Sample, and All. Defaults to None."),RowsToPackSampleMethod:z.union([z.literal('bottom n'),z.literal('random'),z.literal('top n')]).describe("\n * * Field Name: RowsToPackSampleMethod\n * * Display Name: Packing Sample Method\n * * SQL Data Type: nvarchar(20)\n * * Default Value: random\n * * Value List Type: List\n * * Possible Values \n * * bottom n\n * * random\n * * top n\n * * Description: Defines the sampling method for row packing when RowsToPackWithSchema is set to Sample. Options include random, top n, and bottom n. Defaults to random."),RowsToPackSampleCount:z.number().describe("\n * * Field Name: RowsToPackSampleCount\n * * Display Name: Packing Sample Count\n * * SQL Data Type: int\n * * Default Value: 0\n * * Description: The number of rows to pack when RowsToPackWithSchema is set to Sample, based on the designated sampling method. Defaults to 0."),RowsToPackSampleOrder:z.string().nullable().describe("\n * * Field Name: RowsToPackSampleOrder\n * * Display Name: Packing Sample Order\n * * SQL Data Type: nvarchar(MAX)\n * * Description: An optional ORDER BY clause for row packing when RowsToPackWithSchema is set to Sample. Allows custom ordering for selected entity data when using top n and bottom n."),AutoRowCountFrequency:z.number().nullable().describe("\n * * Field Name: AutoRowCountFrequency\n * * Display Name: Refresh Frequency (Hours)\n * * SQL Data Type: int\n * * Description: Frequency in hours for automatically performing row counts on this entity. If NULL, automatic row counting is disabled. If greater than 0, schedules recurring SELECT COUNT(*) queries at the specified interval."),RowCount:z.number().nullable().describe("\n * * Field Name: RowCount\n * * Display Name: Row Count\n * * SQL Data Type: bigint\n * * Description: Cached row count for this entity, populated by automatic row count processes when AutoRowCountFrequency is configured."),RowCountRunAt:z.date().nullable().describe("\n * * Field Name: RowCountRunAt\n * * Display Name: Last Counted At\n * * SQL Data Type: datetimeoffset\n * * Description: Timestamp indicating when the last automatic row count was performed for this entity."),Status:z.union([z.literal('Active'),z.literal('Deprecated'),z.literal('Disabled')]).describe("\n * * Field Name: Status\n * * Display Name: Status\n * * SQL Data Type: nvarchar(25)\n * * Default Value: Active\n * * Value List Type: List\n * * Possible Values \n * * Active\n * * Deprecated\n * * Disabled\n * * Description: Status of the entity. Active: fully functional; Deprecated: functional but generates console warnings when used; Disabled: not available for use even though metadata and physical table remain."),DisplayName:z.string().nullable().describe("\n * * Field Name: DisplayName\n * * Display Name: Display Name\n * * SQL Data Type: nvarchar(255)\n * * Description: User-friendly display name shown in the Explorer UI and other interfaces. When set, this is used instead of the entity Name for display purposes. Typically contains the entity name without the schema prefix \u2014 e.g., \"AI Models\" when Name is \"MJ: AI Models\". If NULL, the UI falls back to using the full Name."),AllowMultipleSubtypes:z.boolean().describe("\n * * Field Name: AllowMultipleSubtypes\n * * Display Name: Allow Multiple Subtypes\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: When false (default), child types are disjoint - a record can only be one child type at a time. When true, a record can simultaneously exist as multiple child types (e.g., a Person can be both a Member and a Volunteer)."),AutoUpdateFullTextSearch:z.boolean().describe("\n * * Field Name: AutoUpdateFullTextSearch\n * * Display Name: Auto Update Search Settings\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When true, CodeGen LLM can auto-configure full-text search settings (FullTextSearchEnabled, catalog, index, function) during code generation runs."),AutoUpdateAllowUserSearchAPI:z.boolean().describe("\n * * Field Name: AutoUpdateAllowUserSearchAPI\n * * Display Name: Auto Update Search API\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When true, CodeGen LLM can auto-set AllowUserSearchAPI during code generation runs."),TrustServerCacheCompletely:z.boolean().describe("\n * * Field Name: TrustServerCacheCompletely\n * * Display Name: Trust Server Cache\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When true (default), the server-side RunView cache will store and return cached results for this entity, trusting that all mutations flow through BaseEntity.Save() which fires cache invalidation events. Set to false for entities whose rows are created as side-effects of other operations via raw SQL (e.g., Record Changes created by spCreateRecordChange_Internal), since those inserts bypass BaseEntity and never trigger cache invalidation."),SupportsGeoCoding:z.boolean().describe("\n * * Field Name: SupportsGeoCoding\n * * Display Name: Supports Geo-Coding\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: When true, CodeGen generates geo-aware subclass code, adds __mj_Latitude/__mj_Longitude virtual fields to the base view, and the UI shows a map view toggle. Auto-set by CodeGen when LLM detects geo-capable fields (address, lat/lng, etc.)."),AutoUpdateSupportsGeoCoding:z.boolean().describe("\n * * Field Name: AutoUpdateSupportsGeoCoding\n * * Display Name: Auto Update Geo-Coding\n * * SQL Data Type: bit\n * * Default Value: 1\n * * Description: When true (default), CodeGen can automatically set SupportsGeoCoding based on LLM analysis of entity fields. Set to 0 to lock the value and prevent CodeGen from changing it."),AllowCaching:z.boolean().describe("\n * * Field Name: AllowCaching\n * * Display Name: Allow Caching\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: Controls whether this entity participates in server-side and client-side caching. When false, all cache operations (PreRunView checks, auto-cache storage, BaseEntity event fingerprint scans, client-side IndexedDB cache) are skipped entirely. This column is the single source of truth at runtime; schema-level defaults are applied at CodeGen time via newEntityDefaults.AllowCachingBySchema."),DetectExternalChanges:z.boolean().describe("\n * * Field Name: DetectExternalChanges\n * * Display Name: Detect External Changes\n * * SQL Data Type: bit\n * * Default Value: 0\n * * Description: When set to 1 AND TrackRecordChanges is also 1, the external change detection system will scan this entity for changes made outside the MJ framework (direct SQL, third-party tools, etc.) and replay them through Save() to create proper RecordChange audit entries. Default is 0 (opt-out) because most entities, especially __mj schema metadata tables, are managed by migrations/CodeGen and should not be scanned."),CodeName:z.string().nullable().describe("\n * * Field Name: CodeName\n * * Display Name: Code Name\n * * SQL Data Type: nvarchar(MAX)\n * * Description: Schema-based programmatic code name derived from the entity Name. Uses GetClassNameSchemaPrefix(SchemaName) as the prefix, then strips EntityNamePrefix from the Name and removes spaces. For \"__mj\" schema with entity \"MJ: AI Models\", this produces \"MJAIModels\". For entities in other schemas, the sanitized schema name is prepended. Used in GraphQL type generation and internal code references."),ClassName:z.string().nullable().describe("\n * * Field Name: ClassName\n * * Display Name: Class Name\n * * SQL Data Type: nvarchar(MAX)\n * * Description: Schema-based programmatic class name used for TypeScript entity classes, Zod schemas, and Angular form components. Computed as GetProgrammaticName(GetClassNameSchemaPrefix(SchemaName) + BaseTable + NameSuffix). The prefix is derived from SchemaName (guaranteed unique by SQL Server), not from EntityNamePrefix. For the core __mj schema, the prefix is \"MJ\"; for all other schemas it is the alphanumeric-sanitized schema name. This prevents cross-schema collisions and aligns with GraphQL type naming in getGraphQLTypeNameBase()."),BaseTableCodeName:z.string().nullable().describe("\n * * Field Name: BaseTableCodeName\n * * Display Name: Base Table Code Name\n * * SQL Data Type: nvarchar(MAX)"),ParentEntity:z.string().nullable().describe("\n * * Field Name: ParentEntity\n * * Display Name: Parent Entity\n * * SQL Data Type: nvarchar(255)"),ParentBaseTable:z.string().nullable().describe("\n * * Field Name: ParentBaseTable\n * * Display Name: Parent Base Table\n * * SQL Data Type: nvarchar(255)"),ParentBaseView:z.string().nullable().describe("\n * * Field Name: ParentBaseView\n * * Display Name: Parent Base View\n * * SQL Data Type: nvarchar(255)")});/**
54127
54445
  * zod schema definition for the entity MJ: Entity Action Filters
54128
54446
  */var MJEntityActionFilterSchema=z.object({ID:z.string().describe("\n * * Field Name: ID\n * * Display Name: ID\n * * SQL Data Type: uniqueidentifier\n * * Default Value: newsequentialid()"),EntityActionID:z.string().describe("\n * * Field Name: EntityActionID\n * * Display Name: Entity Action\n * * SQL Data Type: uniqueidentifier\n * * Related Entity/Foreign Key: MJ: Entity Actions (vwEntityActions.ID)"),ActionFilterID:z.string().describe("\n * * Field Name: ActionFilterID\n * * Display Name: Action Filter\n * * SQL Data Type: uniqueidentifier\n * * Related Entity/Foreign Key: MJ: Action Filters (vwActionFilters.ID)"),Sequence:z.number().describe("\n * * Field Name: Sequence\n * * Display Name: Sequence\n * * SQL Data Type: int\n * * Description: Order of filter execution."),Status:z.union([z.literal('Active'),z.literal('Disabled'),z.literal('Pending')]).describe("\n * * Field Name: Status\n * * Display Name: Status\n * * SQL Data Type: nvarchar(20)\n * * Default Value: Pending\n * * Value List Type: List\n * * Possible Values \n * * Active\n * * Disabled\n * * Pending\n * * Description: Status of the entity action filter (Pending, Active, Disabled)."),__mj_CreatedAt:z.date().describe("\n * * Field Name: __mj_CreatedAt\n * * Display Name: Created At\n * * SQL Data Type: datetimeoffset\n * * Default Value: getutcdate()"),__mj_UpdatedAt:z.date().describe("\n * * Field Name: __mj_UpdatedAt\n * * Display Name: Updated At\n * * SQL Data Type: datetimeoffset\n * * Default Value: getutcdate()"),EntityAction:z.string().describe("\n * * Field Name: EntityAction\n * * Display Name: Entity Action Name\n * * SQL Data Type: nvarchar(425)"),ActionFilter:z.string().describe("\n * * Field Name: ActionFilter\n * * Display Name: Action Filter Name\n * * SQL Data Type: nvarchar(MAX)")});/**
54129
54447
  * zod schema definition for the entity MJ: Entity Action Invocation Types
@@ -70530,6 +70848,18 @@ provider=dist/* Metadata */.OS.Provider;_context136.p=1;_context136.n=2;return p
70530
70848
  * * Default Value: 1
70531
70849
  * * Description: When true (default), CodeGen can automatically set SupportsGeoCoding based on LLM analysis of entity fields. Set to 0 to lock the value and prevent CodeGen from changing it.
70532
70850
  */},{key:"AutoUpdateSupportsGeoCoding",get:function get(){return this.Get('AutoUpdateSupportsGeoCoding');},set:function set(value){this.Set('AutoUpdateSupportsGeoCoding',value);}/**
70851
+ * * Field Name: AllowCaching
70852
+ * * Display Name: Allow Caching
70853
+ * * SQL Data Type: bit
70854
+ * * Default Value: 0
70855
+ * * Description: Controls whether this entity participates in server-side and client-side caching. When false, all cache operations (PreRunView checks, auto-cache storage, BaseEntity event fingerprint scans, client-side IndexedDB cache) are skipped entirely. This column is the single source of truth at runtime; schema-level defaults are applied at CodeGen time via newEntityDefaults.AllowCachingBySchema.
70856
+ */},{key:"AllowCaching",get:function get(){return this.Get('AllowCaching');},set:function set(value){this.Set('AllowCaching',value);}/**
70857
+ * * Field Name: DetectExternalChanges
70858
+ * * Display Name: Detect External Changes
70859
+ * * SQL Data Type: bit
70860
+ * * Default Value: 0
70861
+ * * Description: When set to 1 AND TrackRecordChanges is also 1, the external change detection system will scan this entity for changes made outside the MJ framework (direct SQL, third-party tools, etc.) and replay them through Save() to create proper RecordChange audit entries. Default is 0 (opt-out) because most entities, especially __mj schema metadata tables, are managed by migrations/CodeGen and should not be scanned.
70862
+ */},{key:"DetectExternalChanges",get:function get(){return this.Get('DetectExternalChanges');},set:function set(value){this.Set('DetectExternalChanges',value);}/**
70533
70863
  * * Field Name: CodeName
70534
70864
  * * Display Name: Code Name
70535
70865
  * * SQL Data Type: nvarchar(MAX)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/react-runtime",
3
- "version": "5.25.0",
3
+ "version": "5.26.0",
4
4
  "description": "Platform-agnostic React component runtime for MemberJunction. Provides core compilation, registry, and execution capabilities for React components in any JavaScript environment.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -29,11 +29,11 @@
29
29
  },
30
30
  "homepage": "https://github.com/MemberJunction/MJ#readme",
31
31
  "dependencies": {
32
- "@memberjunction/core": "5.25.0",
33
- "@memberjunction/global": "5.25.0",
34
- "@memberjunction/interactive-component-types": "5.25.0",
35
- "@memberjunction/core-entities": "5.25.0",
36
- "@memberjunction/graphql-dataprovider": "5.25.0",
32
+ "@memberjunction/core": "5.26.0",
33
+ "@memberjunction/global": "5.26.0",
34
+ "@memberjunction/interactive-component-types": "5.26.0",
35
+ "@memberjunction/core-entities": "5.26.0",
36
+ "@memberjunction/graphql-dataprovider": "5.26.0",
37
37
  "@babel/standalone": "^7.29.1",
38
38
  "rxjs": "^7.8.2"
39
39
  },