@memberjunction/global 2.62.0 → 2.63.1

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.
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ClassUtils_1 = require("../ClassUtils");
4
+ // Test class hierarchy
5
+ class Animal {
6
+ constructor() {
7
+ this.name = '';
8
+ }
9
+ }
10
+ class Mammal extends Animal {
11
+ constructor() {
12
+ super(...arguments);
13
+ this.furColor = '';
14
+ }
15
+ }
16
+ class Dog extends Mammal {
17
+ constructor() {
18
+ super(...arguments);
19
+ this.breed = '';
20
+ }
21
+ }
22
+ class GoldenRetriever extends Dog {
23
+ constructor() {
24
+ super(...arguments);
25
+ this.temperament = 'friendly';
26
+ }
27
+ }
28
+ // Test cases
29
+ describe('ClassUtils', () => {
30
+ describe('GetSuperclass', () => {
31
+ it('should return immediate superclass', () => {
32
+ expect((0, ClassUtils_1.GetSuperclass)(GoldenRetriever)).toBe(Dog);
33
+ expect((0, ClassUtils_1.GetSuperclass)(Dog)).toBe(Mammal);
34
+ expect((0, ClassUtils_1.GetSuperclass)(Mammal)).toBe(Animal);
35
+ expect((0, ClassUtils_1.GetSuperclass)(Animal)).toBe(null);
36
+ });
37
+ it('should handle invalid inputs', () => {
38
+ expect((0, ClassUtils_1.GetSuperclass)(null)).toBe(null);
39
+ expect((0, ClassUtils_1.GetSuperclass)(undefined)).toBe(null);
40
+ expect((0, ClassUtils_1.GetSuperclass)({})).toBe(null);
41
+ expect((0, ClassUtils_1.GetSuperclass)('not a class')).toBe(null);
42
+ });
43
+ });
44
+ describe('GetRootClass', () => {
45
+ it('should return the root class', () => {
46
+ expect((0, ClassUtils_1.GetRootClass)(GoldenRetriever)).toBe(Animal);
47
+ expect((0, ClassUtils_1.GetRootClass)(Dog)).toBe(Animal);
48
+ expect((0, ClassUtils_1.GetRootClass)(Animal)).toBe(Animal);
49
+ });
50
+ it('should handle classes without inheritance', () => {
51
+ class Standalone {
52
+ }
53
+ expect((0, ClassUtils_1.GetRootClass)(Standalone)).toBe(Standalone);
54
+ });
55
+ });
56
+ describe('IsSubclassOf', () => {
57
+ it('should correctly identify subclass relationships', () => {
58
+ expect((0, ClassUtils_1.IsSubclassOf)(GoldenRetriever, Dog)).toBe(true);
59
+ expect((0, ClassUtils_1.IsSubclassOf)(GoldenRetriever, Mammal)).toBe(true);
60
+ expect((0, ClassUtils_1.IsSubclassOf)(GoldenRetriever, Animal)).toBe(true);
61
+ expect((0, ClassUtils_1.IsSubclassOf)(Dog, Animal)).toBe(true);
62
+ });
63
+ it('should return false for non-subclass relationships', () => {
64
+ expect((0, ClassUtils_1.IsSubclassOf)(Animal, Dog)).toBe(false);
65
+ expect((0, ClassUtils_1.IsSubclassOf)(Dog, GoldenRetriever)).toBe(false);
66
+ expect((0, ClassUtils_1.IsSubclassOf)(Dog, Dog)).toBe(false); // Not a subclass of itself
67
+ });
68
+ it('should handle invalid inputs', () => {
69
+ expect((0, ClassUtils_1.IsSubclassOf)(null, Animal)).toBe(false);
70
+ expect((0, ClassUtils_1.IsSubclassOf)(Dog, null)).toBe(false);
71
+ expect((0, ClassUtils_1.IsSubclassOf)('not a class', Animal)).toBe(false);
72
+ });
73
+ });
74
+ describe('IsRootClass', () => {
75
+ it('should identify root classes', () => {
76
+ expect((0, ClassUtils_1.IsRootClass)(Animal)).toBe(true);
77
+ class StandaloneClass {
78
+ }
79
+ expect((0, ClassUtils_1.IsRootClass)(StandaloneClass)).toBe(true);
80
+ });
81
+ it('should return false for classes with superclasses', () => {
82
+ expect((0, ClassUtils_1.IsRootClass)(GoldenRetriever)).toBe(false);
83
+ expect((0, ClassUtils_1.IsRootClass)(Dog)).toBe(false);
84
+ expect((0, ClassUtils_1.IsRootClass)(Mammal)).toBe(false);
85
+ });
86
+ it('should handle invalid inputs', () => {
87
+ expect((0, ClassUtils_1.IsRootClass)(null)).toBe(false);
88
+ expect((0, ClassUtils_1.IsRootClass)(undefined)).toBe(false);
89
+ expect((0, ClassUtils_1.IsRootClass)(42)).toBe(false);
90
+ expect((0, ClassUtils_1.IsRootClass)('string')).toBe(false);
91
+ expect((0, ClassUtils_1.IsRootClass)({})).toBe(false);
92
+ });
93
+ });
94
+ describe('IsDescendantClassOf', () => {
95
+ it('should work identically to IsSubclassOf', () => {
96
+ // Test direct parent
97
+ expect((0, ClassUtils_1.IsDescendantClassOf)(GoldenRetriever, Dog)).toBe(true);
98
+ expect((0, ClassUtils_1.IsDescendantClassOf)(Dog, Mammal)).toBe(true);
99
+ // Test grandparent and beyond
100
+ expect((0, ClassUtils_1.IsDescendantClassOf)(GoldenRetriever, Mammal)).toBe(true);
101
+ expect((0, ClassUtils_1.IsDescendantClassOf)(GoldenRetriever, Animal)).toBe(true);
102
+ // Test non-relationships
103
+ expect((0, ClassUtils_1.IsDescendantClassOf)(Animal, GoldenRetriever)).toBe(false);
104
+ expect((0, ClassUtils_1.IsDescendantClassOf)(Dog, Dog)).toBe(false);
105
+ });
106
+ });
107
+ describe('GetClassInheritance', () => {
108
+ it('should return inheritance chain', () => {
109
+ const chain = (0, ClassUtils_1.GetClassInheritance)(GoldenRetriever);
110
+ expect(chain.length).toBe(3);
111
+ expect(chain[0].name).toBe('Dog');
112
+ expect(chain[0].reference).toBe(Dog);
113
+ expect(chain[1].name).toBe('Mammal');
114
+ expect(chain[1].reference).toBe(Mammal);
115
+ expect(chain[2].name).toBe('Animal');
116
+ expect(chain[2].reference).toBe(Animal);
117
+ });
118
+ it('should return empty array for base classes', () => {
119
+ const chain = (0, ClassUtils_1.GetClassInheritance)(Animal);
120
+ expect(chain.length).toBe(0);
121
+ });
122
+ });
123
+ describe('GetFullClassHierarchy', () => {
124
+ it('should include the class itself', () => {
125
+ const hierarchy = (0, ClassUtils_1.GetFullClassHierarchy)(GoldenRetriever);
126
+ expect(hierarchy.length).toBe(4);
127
+ expect(hierarchy[0].name).toBe('GoldenRetriever');
128
+ expect(hierarchy[0].reference).toBe(GoldenRetriever);
129
+ expect(hierarchy[1].name).toBe('Dog');
130
+ expect(hierarchy[2].name).toBe('Mammal');
131
+ expect(hierarchy[3].name).toBe('Animal');
132
+ });
133
+ });
134
+ describe('IsClassConstructor', () => {
135
+ it('should identify class constructors', () => {
136
+ expect((0, ClassUtils_1.IsClassConstructor)(Animal)).toBe(true);
137
+ expect((0, ClassUtils_1.IsClassConstructor)(GoldenRetriever)).toBe(true);
138
+ });
139
+ it('should reject non-constructors', () => {
140
+ expect((0, ClassUtils_1.IsClassConstructor)(() => { })).toBe(false);
141
+ expect((0, ClassUtils_1.IsClassConstructor)(function regularFunction() { })).toBe(false);
142
+ expect((0, ClassUtils_1.IsClassConstructor)(42)).toBe(false);
143
+ expect((0, ClassUtils_1.IsClassConstructor)('string')).toBe(false);
144
+ expect((0, ClassUtils_1.IsClassConstructor)({})).toBe(false);
145
+ });
146
+ it('should handle constructor functions', () => {
147
+ function OldStyleClass() {
148
+ this.property = 'value';
149
+ }
150
+ OldStyleClass.prototype.method = function () { };
151
+ expect((0, ClassUtils_1.IsClassConstructor)(OldStyleClass)).toBe(true);
152
+ });
153
+ });
154
+ describe('GetClassName', () => {
155
+ it('should get class names', () => {
156
+ expect((0, ClassUtils_1.GetClassName)(Animal)).toBe('Animal');
157
+ expect((0, ClassUtils_1.GetClassName)(GoldenRetriever)).toBe('GoldenRetriever');
158
+ });
159
+ it('should handle anonymous classes', () => {
160
+ const AnonClass = class {
161
+ };
162
+ // Note: This might return 'AnonClass' or 'Anonymous' depending on environment
163
+ const name = (0, ClassUtils_1.GetClassName)(AnonClass);
164
+ expect(['AnonClass', 'Anonymous'].includes(name)).toBe(true);
165
+ });
166
+ it('should handle invalid inputs', () => {
167
+ expect((0, ClassUtils_1.GetClassName)(null)).toBe('Unknown');
168
+ expect((0, ClassUtils_1.GetClassName)(undefined)).toBe('Unknown');
169
+ expect((0, ClassUtils_1.GetClassName)(42)).toBe('Unknown');
170
+ });
171
+ });
172
+ });
173
+ //# sourceMappingURL=ClassUtils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClassUtils.test.js","sourceRoot":"","sources":["../../src/__tests__/ClassUtils.test.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,65 +1,10 @@
1
- import * as MJ from './interface';
2
- import { Observable } from 'rxjs';
3
- import { ClassFactory } from './ClassFactory';
4
- import { ObjectCache } from './ObjectCache';
5
- import { BaseSingleton } from './BaseSingleton';
6
1
  export { ClassFactory, ClassRegistration } from './ClassFactory';
7
2
  export * from './interface';
8
3
  export * from './util';
9
4
  export * from './ObjectCache';
10
5
  export * from './BaseSingleton';
11
- /**
12
- * Global class used for coordinating events, creating class instances, and managing components across MemberJunction
13
- */
14
- export declare class MJGlobal extends BaseSingleton<MJGlobal> {
15
- private _eventsSubject;
16
- private _eventsReplaySubject;
17
- private _events$;
18
- private _eventsReplay$;
19
- private _components;
20
- private _classFactory;
21
- private _properties;
22
- /**
23
- * Returns the global instance of the MJGlobal class. This is a singleton class, so there is only one instance of it in the application. Do not directly create new instances of MJGlobal, always use this method to get the instance.
24
- */
25
- static get Instance(): MJGlobal;
26
- RegisterComponent(component: MJ.IMJComponent): void;
27
- /**
28
- * Resets the class to its initial state. Use very carefully and sparingly.
29
- */
30
- Reset(): void;
31
- /**
32
- * Use this method to raise an event to all component who are listening for the event.
33
- * @param event
34
- */
35
- RaiseEvent(event: MJ.MJEvent): void;
36
- /**
37
- * Use this method to get an observable that will fire when an event is raised.
38
- * @param withReplay
39
- * @returns
40
- */
41
- GetEventListener(withReplay?: boolean): Observable<MJ.MJEvent>;
42
- /**
43
- * Returns the instance of ClassFactory you should use in your application. Access this via the MJGlobal.Instance.ClassFactory property.
44
- */
45
- get ClassFactory(): ClassFactory;
46
- /**
47
- * Global property bag
48
- */
49
- get Properties(): MJ.MJGlobalProperty[];
50
- private _objectCache;
51
- /**
52
- * ObjectCache can be used to cache objects as needed by any application in memory. These objects are NOT persisted to disk or any other storage medium, so they are only good for the lifetime of the application
53
- */
54
- get ObjectCache(): ObjectCache;
55
- }
56
- /**
57
- * Decorate your class with this to register it with the MJGlobal class factory.
58
- * @param baseClass
59
- * @param key a string that is later used to retrieve a given registration - this should be unique for each baseClass/key combination, if multiple registrations exist for a given baseClass/key combination, the highest priority registration will be used to create class instances
60
- * @param priority Higher priority registrations will be used over lower priority registrations. If there are multiple registrations for a given base class/sub-class/key combination, the one with the highest priority will be used. If there are multiple registrations with the same priority, the last one registered will be used. Finally, if you do NOT provide this setting, the order of registrations will increment the priority automatically so dependency injection will typically care care of this. That is, in order for Class B, a subclass of Class A, to be registered properly, Class A code has to already have been loaded and therefore Class A's RegisterClass decorator was run. In that scenario, if neither Class A or B has a priority setting, Class A would be 1 and Class B would be 2 automatically. For this reason, you only need to explicitly set priority if you want to do something atypical as this mechanism normally will solve for setting the priority correctly based on the furthest descendant class that is registered.
61
- * @param skipNullKeyWarning If true, will not print a warning if the key is null or undefined. This is useful for cases where you know that the key is not needed and you don't want to see the warning in the console.
62
- * @returns an instance of the class that was registered for the combination of baseClass/key (with highest priority if more than one)
63
- */
64
- export declare function RegisterClass(baseClass: any, key?: string, priority?: number, skipNullKeyWarning?: boolean): (constructor: Function) => void;
6
+ export * from './DeepDiff';
7
+ export * from './ClassUtils';
8
+ export * from './Global';
9
+ export * from './RegisterClass';
65
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,aAAa,CAAA;AAEjC,OAAO,EAA0B,UAAU,EAAE,MAAM,MAAM,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAqB,MAAM,gBAAgB,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAChE,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAE/B;;GAEG;AACH,qBAAa,QAAS,SAAQ,aAAa,CAAC,QAAQ,CAAC;IAEjD,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,oBAAoB,CAAkD;IAG9E,OAAO,CAAC,QAAQ,CAA8D;IAC9E,OAAO,CAAC,cAAc,CAAoE;IAE1F,OAAO,CAAC,WAAW,CAAyB;IAE5C,OAAO,CAAC,aAAa,CAAoC;IAEzD,OAAO,CAAC,WAAW,CAA6B;IAEhD;;OAEG;IACH,WAAkB,QAAQ,IAAI,QAAQ,CAErC;IAEM,iBAAiB,CAAC,SAAS,EAAE,EAAE,CAAC,YAAY;IAInD;;OAEG;IACI,KAAK;IAWZ;;;OAGG;IACI,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO;IAKnC;;;;OAIG;IACI,gBAAgB,CAAC,UAAU,GAAE,OAAe,GAAG,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC;IAI5E;;OAEG;IACH,IAAW,YAAY,IAAI,YAAY,CAEtC;IAED;;OAEG;IACH,IAAW,UAAU,IAAI,EAAE,CAAC,gBAAgB,EAAE,CAE7C;IAGD,OAAO,CAAC,YAAY,CAAkC;IACtD;;OAEG;IACH,IAAW,WAAW,IAAI,WAAW,CAEpC;CACJ;AAID;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,GAAE,MAAa,EAAE,QAAQ,GAAE,MAAU,EAAE,kBAAkB,GAAE,OAAe,GAAG,CAAC,WAAW,EAAE,QAAQ,KAAK,IAAI,CAK5J"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAChE,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAG5B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA"}
package/dist/index.js CHANGED
@@ -14,104 +14,18 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.RegisterClass = exports.MJGlobal = exports.ClassRegistration = exports.ClassFactory = void 0;
18
- const rxjs_1 = require("rxjs");
19
- const ClassFactory_1 = require("./ClassFactory");
20
- const ObjectCache_1 = require("./ObjectCache");
21
- const BaseSingleton_1 = require("./BaseSingleton");
22
- var ClassFactory_2 = require("./ClassFactory");
23
- Object.defineProperty(exports, "ClassFactory", { enumerable: true, get: function () { return ClassFactory_2.ClassFactory; } });
24
- Object.defineProperty(exports, "ClassRegistration", { enumerable: true, get: function () { return ClassFactory_2.ClassRegistration; } });
17
+ exports.ClassRegistration = exports.ClassFactory = void 0;
18
+ // Export all types and utilities
19
+ var ClassFactory_1 = require("./ClassFactory");
20
+ Object.defineProperty(exports, "ClassFactory", { enumerable: true, get: function () { return ClassFactory_1.ClassFactory; } });
21
+ Object.defineProperty(exports, "ClassRegistration", { enumerable: true, get: function () { return ClassFactory_1.ClassRegistration; } });
25
22
  __exportStar(require("./interface"), exports);
26
23
  __exportStar(require("./util"), exports);
27
24
  __exportStar(require("./ObjectCache"), exports);
28
25
  __exportStar(require("./BaseSingleton"), exports);
29
- /**
30
- * Global class used for coordinating events, creating class instances, and managing components across MemberJunction
31
- */
32
- class MJGlobal extends BaseSingleton_1.BaseSingleton {
33
- constructor() {
34
- super(...arguments);
35
- // subjects for observables to handle eventing
36
- this._eventsSubject = new rxjs_1.Subject();
37
- this._eventsReplaySubject = new rxjs_1.ReplaySubject();
38
- // Convert the Subjects to Observables for public use.
39
- this._events$ = this._eventsSubject.asObservable();
40
- this._eventsReplay$ = this._eventsReplaySubject.asObservable();
41
- this._components = [];
42
- this._classFactory = new ClassFactory_1.ClassFactory();
43
- this._properties = [];
44
- this._objectCache = new ObjectCache_1.ObjectCache();
45
- }
46
- /**
47
- * Returns the global instance of the MJGlobal class. This is a singleton class, so there is only one instance of it in the application. Do not directly create new instances of MJGlobal, always use this method to get the instance.
48
- */
49
- static get Instance() {
50
- return super.getInstance();
51
- }
52
- RegisterComponent(component) {
53
- this._components.push(component);
54
- }
55
- /**
56
- * Resets the class to its initial state. Use very carefully and sparingly.
57
- */
58
- Reset() {
59
- this._components = [];
60
- this._eventsSubject = new rxjs_1.Subject();
61
- this._eventsReplaySubject = new rxjs_1.ReplaySubject();
62
- // Convert the Subjects to Observables for public use.
63
- this._events$ = this._eventsSubject.asObservable();
64
- this._eventsReplay$ = this._eventsReplaySubject.asObservable();
65
- }
66
- /**
67
- * Use this method to raise an event to all component who are listening for the event.
68
- * @param event
69
- */
70
- RaiseEvent(event) {
71
- this._eventsSubject.next(event);
72
- this._eventsReplaySubject.next(event);
73
- }
74
- /**
75
- * Use this method to get an observable that will fire when an event is raised.
76
- * @param withReplay
77
- * @returns
78
- */
79
- GetEventListener(withReplay = false) {
80
- return withReplay ? this._eventsReplay$ : this._events$;
81
- }
82
- /**
83
- * Returns the instance of ClassFactory you should use in your application. Access this via the MJGlobal.Instance.ClassFactory property.
84
- */
85
- get ClassFactory() {
86
- return this._classFactory;
87
- }
88
- /**
89
- * Global property bag
90
- */
91
- get Properties() {
92
- return this._properties;
93
- }
94
- /**
95
- * ObjectCache can be used to cache objects as needed by any application in memory. These objects are NOT persisted to disk or any other storage medium, so they are only good for the lifetime of the application
96
- */
97
- get ObjectCache() {
98
- return this._objectCache;
99
- }
100
- }
101
- exports.MJGlobal = MJGlobal;
102
- /**
103
- * Decorate your class with this to register it with the MJGlobal class factory.
104
- * @param baseClass
105
- * @param key a string that is later used to retrieve a given registration - this should be unique for each baseClass/key combination, if multiple registrations exist for a given baseClass/key combination, the highest priority registration will be used to create class instances
106
- * @param priority Higher priority registrations will be used over lower priority registrations. If there are multiple registrations for a given base class/sub-class/key combination, the one with the highest priority will be used. If there are multiple registrations with the same priority, the last one registered will be used. Finally, if you do NOT provide this setting, the order of registrations will increment the priority automatically so dependency injection will typically care care of this. That is, in order for Class B, a subclass of Class A, to be registered properly, Class A code has to already have been loaded and therefore Class A's RegisterClass decorator was run. In that scenario, if neither Class A or B has a priority setting, Class A would be 1 and Class B would be 2 automatically. For this reason, you only need to explicitly set priority if you want to do something atypical as this mechanism normally will solve for setting the priority correctly based on the furthest descendant class that is registered.
107
- * @param skipNullKeyWarning If true, will not print a warning if the key is null or undefined. This is useful for cases where you know that the key is not needed and you don't want to see the warning in the console.
108
- * @returns an instance of the class that was registered for the combination of baseClass/key (with highest priority if more than one)
109
- */
110
- function RegisterClass(baseClass, key = null, priority = 0, skipNullKeyWarning = false) {
111
- return function (constructor) {
112
- // Invoke the registration method
113
- MJGlobal.Instance.ClassFactory.Register(baseClass, constructor, key, priority, skipNullKeyWarning);
114
- };
115
- }
116
- exports.RegisterClass = RegisterClass;
26
+ __exportStar(require("./DeepDiff"), exports);
27
+ __exportStar(require("./ClassUtils"), exports);
28
+ // Export the main classes
29
+ __exportStar(require("./Global"), exports);
30
+ __exportStar(require("./RegisterClass"), exports);
117
31
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAEA,+BAA0D;AAC1D,iDAAgE;AAChE,+CAA4C;AAC5C,mDAAgD;AAEhD,+CAAgE;AAAvD,4GAAA,YAAY,OAAA;AAAE,iHAAA,iBAAiB,OAAA;AACxC,8CAA2B;AAC3B,yCAAsB;AACtB,gDAA6B;AAC7B,kDAA+B;AAE/B;;GAEG;AACH,MAAa,QAAS,SAAQ,6BAAuB;IAArD;;QACI,8CAA8C;QACtC,mBAAc,GAAwB,IAAI,cAAO,EAAE,CAAC;QACpD,yBAAoB,GAA8B,IAAI,oBAAa,EAAE,CAAC;QAE9E,sDAAsD;QAC9C,aAAQ,GAA2B,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;QACtE,mBAAc,GAA2B,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,CAAC;QAElF,gBAAW,GAAsB,EAAE,CAAC;QAEpC,kBAAa,GAAiB,IAAI,2BAAY,EAAE,CAAC;QAEjD,gBAAW,GAA0B,EAAE,CAAC;QA4DxC,iBAAY,GAAgB,IAAI,yBAAW,EAAE,CAAC;IAO1D,CAAC;IAjEG;;OAEG;IACI,MAAM,KAAK,QAAQ;QACtB,OAAO,KAAK,CAAC,WAAW,EAAY,CAAC;IACzC,CAAC;IAEM,iBAAiB,CAAC,SAA0B;QAC/C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACI,KAAK;QACR,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QAEtB,IAAI,CAAC,cAAc,GAAI,IAAI,cAAO,EAAE,CAAC;QACrC,IAAI,CAAC,oBAAoB,GAAG,IAAI,oBAAa,EAAE,CAAC;QAEhD,sDAAsD;QACtD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;QACnD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,CAAC;IACnE,CAAC;IAED;;;OAGG;IACI,UAAU,CAAC,KAAiB;QAC/B,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACI,gBAAgB,CAAC,aAAsB,KAAK;QAC/C,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,IAAW,YAAY;QACnB,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,IAAW,UAAU;QACjB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC5B,CAAC;IAID;;OAEG;IACH,IAAW,WAAW;QAClB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;CACJ;AAhFD,4BAgFC;AAID;;;;;;;GAOG;AACH,SAAgB,aAAa,CAAC,SAAc,EAAE,MAAc,IAAI,EAAE,WAAmB,CAAC,EAAE,qBAA8B,KAAK;IACvH,OAAO,UAAU,WAAqB;QAClC,iCAAiC;QACjC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IACvG,CAAC,CAAA;AACL,CAAC;AALD,sCAKC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iCAAiC;AACjC,+CAAgE;AAAvD,4GAAA,YAAY,OAAA;AAAE,iHAAA,iBAAiB,OAAA;AACxC,8CAA2B;AAC3B,yCAAsB;AACtB,gDAA6B;AAC7B,kDAA+B;AAC/B,6CAA0B;AAC1B,+CAA4B;AAE5B,0BAA0B;AAC1B,2CAAwB;AACxB,kDAA+B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/global",
3
- "version": "2.62.0",
3
+ "version": "2.63.1",
4
4
  "description": "MemberJunction: Global Object - Needed for ALL other MJ components",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/readme.md CHANGED
@@ -13,9 +13,11 @@ npm install @memberjunction/global
13
13
  The `@memberjunction/global` library serves as the foundation for cross-component communication and coordination in MemberJunction applications. It provides:
14
14
 
15
15
  - **Global Singleton Management** - Ensures true singleton instances across module boundaries
16
- - **Class Factory System** - Dynamic class registration and instantiation with inheritance support
16
+ - **Class Factory System** - Dynamic class registration and instantiation with automatic root class detection
17
17
  - **Event System** - RxJS-based event bus for component communication
18
18
  - **Object Caching** - In-memory object cache for application lifetime
19
+ - **Class Reflection Utilities** - Runtime class hierarchy inspection and analysis
20
+ - **Deep Diff Engine** - Comprehensive object comparison and change tracking
19
21
  - **Utility Functions** - Common string manipulation, JSON parsing (including recursive nested JSON parsing), and formatting utilities
20
22
 
21
23
  ## Core Components
@@ -54,21 +56,27 @@ const replaySubscription = mjGlobal.GetEventListener(true).subscribe(event => {
54
56
 
55
57
  ### Class Factory System
56
58
 
57
- Register and instantiate classes dynamically with support for inheritance and key-based selection.
59
+ Register and instantiate classes dynamically with automatic root class detection and inheritance chain support.
58
60
 
59
61
  ```typescript
60
62
  import { RegisterClass, MJGlobal } from '@memberjunction/global';
61
63
 
62
- // Define a base class
64
+ // Define a base class hierarchy
63
65
  class BaseProcessor {
64
66
  process(data: any): void {
65
67
  console.log('Base processing');
66
68
  }
67
69
  }
68
70
 
69
- // Register a subclass using the decorator
70
- @RegisterClass(BaseProcessor, 'custom', 100)
71
- class CustomProcessor extends BaseProcessor {
71
+ class SpecialProcessor extends BaseProcessor {
72
+ process(data: any): void {
73
+ console.log('Special processing');
74
+ }
75
+ }
76
+
77
+ // Register a subclass - automatically registers with root class (BaseProcessor)
78
+ @RegisterClass(SpecialProcessor, 'custom')
79
+ class CustomProcessor extends SpecialProcessor {
72
80
  process(data: any): void {
73
81
  console.log('Custom processing');
74
82
  }
@@ -78,6 +86,15 @@ class CustomProcessor extends BaseProcessor {
78
86
  const factory = MJGlobal.Instance.ClassFactory;
79
87
  const processor = factory.CreateInstance<BaseProcessor>(BaseProcessor, 'custom');
80
88
  processor.process(data); // Uses CustomProcessor
89
+
90
+ // Key Features:
91
+ // 1. Auto-registers with root class by default (BaseProcessor in this case)
92
+ // 2. Ensures proper priority ordering in inheritance chains
93
+ // 3. Can opt-out with autoRegisterWithRootClass: false
94
+ @RegisterClass(SpecialProcessor, 'special', 0, false, false) // Last param disables auto-root registration
95
+ class DirectRegistration extends SpecialProcessor {
96
+ // This registers directly to SpecialProcessor, not BaseProcessor
97
+ }
81
98
  ```
82
99
 
83
100
  ### Object Cache
@@ -127,6 +144,117 @@ const service = MyService.Instance;
127
144
  service.addData('example');
128
145
  ```
129
146
 
147
+ ### Class Reflection Utilities
148
+
149
+ Runtime utilities for inspecting and analyzing class hierarchies.
150
+
151
+ ```typescript
152
+ import {
153
+ GetSuperclass,
154
+ GetRootClass,
155
+ IsSubclassOf,
156
+ IsRootClass,
157
+ IsDescendantClassOf,
158
+ GetClassInheritance,
159
+ GetFullClassHierarchy,
160
+ IsClassConstructor,
161
+ GetClassName
162
+ } from '@memberjunction/global';
163
+
164
+ // Example class hierarchy
165
+ class Animal {}
166
+ class Mammal extends Animal {}
167
+ class Dog extends Mammal {}
168
+ class GoldenRetriever extends Dog {}
169
+
170
+ // Get immediate superclass
171
+ const parent = GetSuperclass(GoldenRetriever); // Returns: Dog
172
+
173
+ // Get root class of hierarchy
174
+ const root = GetRootClass(GoldenRetriever); // Returns: Animal
175
+
176
+ // Check inheritance relationships
177
+ IsSubclassOf(GoldenRetriever, Animal); // true (checks entire chain)
178
+ IsDescendantClassOf(GoldenRetriever, Animal); // true (alias for IsSubclassOf)
179
+ IsRootClass(Animal); // true
180
+ IsRootClass(Dog); // false
181
+
182
+ // Get inheritance chain
183
+ const chain = GetClassInheritance(GoldenRetriever);
184
+ // Returns: [
185
+ // { name: 'Dog', reference: Dog },
186
+ // { name: 'Mammal', reference: Mammal },
187
+ // { name: 'Animal', reference: Animal }
188
+ // ]
189
+
190
+ // Get full hierarchy including the class itself
191
+ const fullChain = GetFullClassHierarchy(GoldenRetriever);
192
+ // Returns: [
193
+ // { name: 'GoldenRetriever', reference: GoldenRetriever },
194
+ // { name: 'Dog', reference: Dog },
195
+ // { name: 'Mammal', reference: Mammal },
196
+ // { name: 'Animal', reference: Animal }
197
+ // ]
198
+
199
+ // Utility functions
200
+ IsClassConstructor(Dog); // true
201
+ IsClassConstructor(() => {}); // false
202
+ GetClassName(GoldenRetriever); // "GoldenRetriever"
203
+ ```
204
+
205
+ ### Deep Diff Engine
206
+
207
+ Comprehensive object comparison and change tracking with hierarchical diff visualization.
208
+
209
+ ```typescript
210
+ import { DeepDiffer, DiffChangeType } from '@memberjunction/global';
211
+
212
+ // Create a differ instance
213
+ const differ = new DeepDiffer({
214
+ includeUnchanged: false, // Don't track unchanged values
215
+ maxDepth: 10, // Maximum recursion depth
216
+ maxStringLength: 100 // Truncate long strings
217
+ });
218
+
219
+ // Compare two objects
220
+ const oldData = {
221
+ user: { name: 'John', age: 30, role: 'admin' },
222
+ settings: { theme: 'dark', notifications: true },
223
+ tags: ['important', 'active']
224
+ };
225
+
226
+ const newData = {
227
+ user: { name: 'John', age: 31, role: 'superadmin' },
228
+ settings: { theme: 'light', notifications: true, language: 'en' },
229
+ tags: ['important', 'active', 'premium']
230
+ };
231
+
232
+ // Get the diff
233
+ const result = differ.diff(oldData, newData);
234
+
235
+ // Access summary
236
+ console.log(result.summary);
237
+ // { added: 2, removed: 0, modified: 3, unchanged: 3, total: 8 }
238
+
239
+ // Iterate through changes
240
+ result.changes.forEach(change => {
241
+ console.log(`${change.path}: ${change.type} - ${change.description}`);
242
+ });
243
+ // Output:
244
+ // user.age: Modified - Changed from 30 to 31
245
+ // user.role: Modified - Changed from "admin" to "superadmin"
246
+ // settings.theme: Modified - Changed from "dark" to "light"
247
+ // settings.language: Added - Value: "en"
248
+ // tags[2]: Added - Value: "premium"
249
+
250
+ // Filter changes by type
251
+ const additions = result.changes.filter(c => c.type === DiffChangeType.Added);
252
+ const modifications = result.changes.filter(c => c.type === DiffChangeType.Modified);
253
+
254
+ // Update configuration on the fly
255
+ differ.updateConfig({ includeUnchanged: true });
256
+ ```
257
+
130
258
  ## Event Types
131
259
 
132
260
  The library provides predefined event types for common scenarios:
@@ -255,6 +383,45 @@ InvokeManualResize(50, myComponent);
255
383
 
256
384
  ## Advanced Usage
257
385
 
386
+ ### Class Factory with Root Class Detection
387
+
388
+ The Class Factory automatically detects and uses root classes for registration, ensuring proper priority ordering in inheritance hierarchies:
389
+
390
+ ```typescript
391
+ class BaseEntity {} // Root class
392
+
393
+ class UserEntity extends BaseEntity {}
394
+
395
+ // This automatically registers with BaseEntity (the root)
396
+ @RegisterClass(UserEntity, 'Admin')
397
+ class AdminUserEntity extends UserEntity {}
398
+
399
+ // Also registers with BaseEntity, gets higher priority
400
+ @RegisterClass(AdminUserEntity, 'SuperAdmin')
401
+ class SuperAdminEntity extends AdminUserEntity {}
402
+
403
+ // All of these create SuperAdminEntity (highest priority)
404
+ factory.CreateInstance(BaseEntity, 'SuperAdmin'); // ✓ Works
405
+ factory.CreateInstance(UserEntity, 'SuperAdmin'); // ✓ Works
406
+ factory.CreateInstance(AdminUserEntity, 'SuperAdmin'); // ✓ Works
407
+ ```
408
+
409
+ ### Disabling Auto-Root Registration
410
+
411
+ Sometimes you want to register at a specific level in the hierarchy:
412
+
413
+ ```typescript
414
+ // Register directly to UserEntity, not BaseEntity
415
+ @RegisterClass(UserEntity, 'Special', 0, false, false) // Last param = false
416
+ class SpecialUserEntity extends UserEntity {
417
+ // This only matches when creating from UserEntity, not BaseEntity
418
+ }
419
+
420
+ // Direct registration queries
421
+ factory.CreateInstance(UserEntity, 'Special'); // ✓ Returns SpecialUserEntity
422
+ factory.CreateInstance(BaseEntity, 'Special'); // ✗ Returns BaseEntity instance
423
+ ```
424
+
258
425
  ### Class Factory with Parameters
259
426
 
260
427
  ```typescript
@@ -289,6 +456,23 @@ class AdvancedDataHandler extends BaseHandler {}
289
456
  const handler = factory.CreateInstance<BaseHandler>(BaseHandler, 'data');
290
457
  ```
291
458
 
459
+ ### Inspecting Registrations
460
+
461
+ ```typescript
462
+ // Get all registrations for a base class
463
+ const registrations = factory.GetAllRegistrations(BaseEntity, 'Users');
464
+
465
+ // Get registrations by root class
466
+ const rootRegistrations = factory.GetRegistrationsByRootClass(BaseEntity);
467
+
468
+ // Each registration contains:
469
+ // - BaseClass: The class it's registered to (usually root)
470
+ // - SubClass: The actual implementation class
471
+ // - RootClass: The detected root of the hierarchy
472
+ // - Key: The registration key
473
+ // - Priority: The priority number
474
+ ```
475
+
292
476
  ### Global Properties
293
477
 
294
478
  Store and retrieve global properties: