@memberjunction/global 4.0.0 → 4.2.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.
Files changed (119) hide show
  1. package/README.md +634 -0
  2. package/package.json +1 -1
  3. package/dist/Core.d.ts +0 -29
  4. package/dist/Core.d.ts.map +0 -1
  5. package/dist/Core.js +0 -58
  6. package/dist/Core.js.map +0 -1
  7. package/dist/generic/QueryCache.d.ts +0 -85
  8. package/dist/generic/QueryCache.d.ts.map +0 -1
  9. package/dist/generic/QueryCache.js +0 -198
  10. package/dist/generic/QueryCache.js.map +0 -1
  11. package/dist/generic/QueryCacheConfig.d.ts +0 -72
  12. package/dist/generic/QueryCacheConfig.d.ts.map +0 -1
  13. package/dist/generic/QueryCacheConfig.js +0 -3
  14. package/dist/generic/QueryCacheConfig.js.map +0 -1
  15. package/dist/generic/applicationInfo.d.ts +0 -138
  16. package/dist/generic/applicationInfo.d.ts.map +0 -1
  17. package/dist/generic/applicationInfo.js +0 -177
  18. package/dist/generic/applicationInfo.js.map +0 -1
  19. package/dist/generic/authEvaluator.d.ts +0 -25
  20. package/dist/generic/authEvaluator.d.ts.map +0 -1
  21. package/dist/generic/authEvaluator.js +0 -49
  22. package/dist/generic/authEvaluator.js.map +0 -1
  23. package/dist/generic/authTypes.d.ts +0 -193
  24. package/dist/generic/authTypes.d.ts.map +0 -1
  25. package/dist/generic/authTypes.js +0 -19
  26. package/dist/generic/authTypes.js.map +0 -1
  27. package/dist/generic/baseEngine.d.ts +0 -260
  28. package/dist/generic/baseEngine.d.ts.map +0 -1
  29. package/dist/generic/baseEngine.js +0 -510
  30. package/dist/generic/baseEngine.js.map +0 -1
  31. package/dist/generic/baseEntity.d.ts +0 -691
  32. package/dist/generic/baseEntity.d.ts.map +0 -1
  33. package/dist/generic/baseEntity.js +0 -1688
  34. package/dist/generic/baseEntity.js.map +0 -1
  35. package/dist/generic/baseInfo.d.ts +0 -24
  36. package/dist/generic/baseInfo.d.ts.map +0 -1
  37. package/dist/generic/baseInfo.js +0 -53
  38. package/dist/generic/baseInfo.js.map +0 -1
  39. package/dist/generic/compositeKey.d.ts +0 -206
  40. package/dist/generic/compositeKey.d.ts.map +0 -1
  41. package/dist/generic/compositeKey.js +0 -412
  42. package/dist/generic/compositeKey.js.map +0 -1
  43. package/dist/generic/databaseProviderBase.d.ts +0 -46
  44. package/dist/generic/databaseProviderBase.d.ts.map +0 -1
  45. package/dist/generic/databaseProviderBase.js +0 -14
  46. package/dist/generic/databaseProviderBase.js.map +0 -1
  47. package/dist/generic/entityInfo.d.ts +0 -983
  48. package/dist/generic/entityInfo.d.ts.map +0 -1
  49. package/dist/generic/entityInfo.js +0 -1401
  50. package/dist/generic/entityInfo.js.map +0 -1
  51. package/dist/generic/explorerNavigationItem.d.ts +0 -20
  52. package/dist/generic/explorerNavigationItem.d.ts.map +0 -1
  53. package/dist/generic/explorerNavigationItem.js +0 -29
  54. package/dist/generic/explorerNavigationItem.js.map +0 -1
  55. package/dist/generic/interfaces.d.ts +0 -610
  56. package/dist/generic/interfaces.d.ts.map +0 -1
  57. package/dist/generic/interfaces.js +0 -211
  58. package/dist/generic/interfaces.js.map +0 -1
  59. package/dist/generic/libraryInfo.d.ts +0 -40
  60. package/dist/generic/libraryInfo.d.ts.map +0 -1
  61. package/dist/generic/libraryInfo.js +0 -56
  62. package/dist/generic/libraryInfo.js.map +0 -1
  63. package/dist/generic/logging.d.ts +0 -179
  64. package/dist/generic/logging.d.ts.map +0 -1
  65. package/dist/generic/logging.js +0 -382
  66. package/dist/generic/logging.js.map +0 -1
  67. package/dist/generic/metadata.d.ts +0 -305
  68. package/dist/generic/metadata.d.ts.map +0 -1
  69. package/dist/generic/metadata.js +0 -454
  70. package/dist/generic/metadata.js.map +0 -1
  71. package/dist/generic/metadataUtil.d.ts +0 -8
  72. package/dist/generic/metadataUtil.d.ts.map +0 -1
  73. package/dist/generic/metadataUtil.js +0 -36
  74. package/dist/generic/metadataUtil.js.map +0 -1
  75. package/dist/generic/providerBase.d.ts +0 -546
  76. package/dist/generic/providerBase.d.ts.map +0 -1
  77. package/dist/generic/providerBase.js +0 -999
  78. package/dist/generic/providerBase.js.map +0 -1
  79. package/dist/generic/queryInfo.d.ts +0 -460
  80. package/dist/generic/queryInfo.d.ts.map +0 -1
  81. package/dist/generic/queryInfo.js +0 -633
  82. package/dist/generic/queryInfo.js.map +0 -1
  83. package/dist/generic/querySQLFilters.d.ts +0 -54
  84. package/dist/generic/querySQLFilters.d.ts.map +0 -1
  85. package/dist/generic/querySQLFilters.js +0 -84
  86. package/dist/generic/querySQLFilters.js.map +0 -1
  87. package/dist/generic/runQuery.d.ts +0 -96
  88. package/dist/generic/runQuery.d.ts.map +0 -1
  89. package/dist/generic/runQuery.js +0 -66
  90. package/dist/generic/runQuery.js.map +0 -1
  91. package/dist/generic/runQuerySQLFilterImplementations.d.ts +0 -51
  92. package/dist/generic/runQuerySQLFilterImplementations.d.ts.map +0 -1
  93. package/dist/generic/runQuerySQLFilterImplementations.js +0 -238
  94. package/dist/generic/runQuerySQLFilterImplementations.js.map +0 -1
  95. package/dist/generic/runReport.d.ts +0 -25
  96. package/dist/generic/runReport.d.ts.map +0 -1
  97. package/dist/generic/runReport.js +0 -42
  98. package/dist/generic/runReport.js.map +0 -1
  99. package/dist/generic/securityInfo.d.ts +0 -355
  100. package/dist/generic/securityInfo.d.ts.map +0 -1
  101. package/dist/generic/securityInfo.js +0 -425
  102. package/dist/generic/securityInfo.js.map +0 -1
  103. package/dist/generic/transactionGroup.d.ts +0 -184
  104. package/dist/generic/transactionGroup.d.ts.map +0 -1
  105. package/dist/generic/transactionGroup.js +0 -357
  106. package/dist/generic/transactionGroup.js.map +0 -1
  107. package/dist/generic/util.d.ts +0 -81
  108. package/dist/generic/util.d.ts.map +0 -1
  109. package/dist/generic/util.js +0 -301
  110. package/dist/generic/util.js.map +0 -1
  111. package/dist/views/runView.d.ts +0 -150
  112. package/dist/views/runView.d.ts.map +0 -1
  113. package/dist/views/runView.js +0 -100
  114. package/dist/views/runView.js.map +0 -1
  115. package/dist/views/viewInfo.d.ts +0 -121
  116. package/dist/views/viewInfo.d.ts.map +0 -1
  117. package/dist/views/viewInfo.js +0 -182
  118. package/dist/views/viewInfo.js.map +0 -1
  119. package/readme.md +0 -1168
package/readme.md DELETED
@@ -1,1168 +0,0 @@
1
- # @memberjunction/global
2
-
3
- Core global utilities and coordination library for MemberJunction applications. This package provides essential singleton management, class factory patterns, event coordination, and utility functions that are used throughout the MemberJunction ecosystem.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @memberjunction/global
9
- ```
10
-
11
- ## Overview
12
-
13
- The `@memberjunction/global` library serves as the foundation for cross-component communication and coordination in MemberJunction applications. It provides:
14
-
15
- - **Global Singleton Management** - Ensures true singleton instances across module boundaries
16
- - **Class Factory System** - Dynamic class registration and instantiation with automatic root class detection
17
- - **Event System** - RxJS-based event bus for component communication
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
21
- - **JSON Validator** - Lightweight JSON validation with flexible rules and special syntax
22
- - **Warning Manager** - Smart warning system with debouncing, batching, and session tracking
23
- - **Utility Functions** - Common string manipulation, JSON parsing (including recursive nested JSON parsing), pattern matching, and formatting utilities
24
-
25
- ## Core Components
26
-
27
- ### MJGlobal Class
28
-
29
- The central singleton class that coordinates events and manages components across your application.
30
-
31
- ```typescript
32
- import { MJGlobal } from '@memberjunction/global';
33
-
34
- // Get the singleton instance
35
- const mjGlobal = MJGlobal.Instance;
36
-
37
- // Register a component
38
- mjGlobal.RegisterComponent(myComponent);
39
-
40
- // Raise an event
41
- mjGlobal.RaiseEvent({
42
- component: myComponent,
43
- event: MJEventType.ComponentEvent,
44
- eventCode: 'CUSTOM_EVENT',
45
- args: { data: 'example' }
46
- });
47
-
48
- // Listen for events
49
- const subscription = mjGlobal.GetEventListener().subscribe(event => {
50
- console.log('Event received:', event);
51
- });
52
-
53
- // Listen with replay (gets past events too)
54
- const replaySubscription = mjGlobal.GetEventListener(true).subscribe(event => {
55
- console.log('Event with replay:', event);
56
- });
57
- ```
58
-
59
- ### Class Factory System
60
-
61
- Register and instantiate classes dynamically with automatic root class detection and inheritance chain support.
62
-
63
- ```typescript
64
- import { RegisterClass, MJGlobal } from '@memberjunction/global';
65
-
66
- // Define a base class hierarchy
67
- class BaseProcessor {
68
- process(data: any): void {
69
- console.log('Base processing');
70
- }
71
- }
72
-
73
- class SpecialProcessor extends BaseProcessor {
74
- process(data: any): void {
75
- console.log('Special processing');
76
- }
77
- }
78
-
79
- // Register a subclass - automatically registers with root class (BaseProcessor)
80
- @RegisterClass(SpecialProcessor, 'custom')
81
- class CustomProcessor extends SpecialProcessor {
82
- process(data: any): void {
83
- console.log('Custom processing');
84
- }
85
- }
86
-
87
- // Create instances via the factory
88
- const factory = MJGlobal.Instance.ClassFactory;
89
- const processor = factory.CreateInstance<BaseProcessor>(BaseProcessor, 'custom');
90
- processor.process(data); // Uses CustomProcessor
91
-
92
- // Key Features:
93
- // 1. Auto-registers with root class by default (BaseProcessor in this case)
94
- // 2. Ensures proper priority ordering in inheritance chains
95
- // 3. Can opt-out with autoRegisterWithRootClass: false
96
- @RegisterClass(SpecialProcessor, 'special', 0, false, false) // Last param disables auto-root registration
97
- class DirectRegistration extends SpecialProcessor {
98
- // This registers directly to SpecialProcessor, not BaseProcessor
99
- }
100
- ```
101
-
102
- ### Object Cache
103
-
104
- In-memory caching system for application-lifetime object storage.
105
-
106
- ```typescript
107
- const cache = MJGlobal.Instance.ObjectCache;
108
-
109
- // Add an object to cache
110
- cache.Add('user:123', { id: 123, name: 'John Doe' });
111
-
112
- // Find an object
113
- const user = cache.Find<User>('user:123');
114
-
115
- // Replace an existing object
116
- cache.Replace('user:123', { id: 123, name: 'Jane Doe' });
117
-
118
- // Remove from cache
119
- cache.Remove('user:123');
120
-
121
- // Clear all cached objects
122
- cache.Clear();
123
- ```
124
-
125
- ### BaseSingleton Class
126
-
127
- Abstract base class for creating global singleton instances that persist across module boundaries.
128
-
129
- ```typescript
130
- import { BaseSingleton } from '@memberjunction/global';
131
-
132
- export class MyService extends BaseSingleton<MyService> {
133
- private data: string[] = [];
134
-
135
- public static get Instance(): MyService {
136
- return super.getInstance<MyService>();
137
- }
138
-
139
- public addData(item: string): void {
140
- this.data.push(item);
141
- }
142
- }
143
-
144
- // Usage anywhere in your app
145
- const service = MyService.Instance;
146
- service.addData('example');
147
- ```
148
-
149
- ### Class Reflection Utilities
150
-
151
- Runtime utilities for inspecting and analyzing class hierarchies.
152
-
153
- ```typescript
154
- import {
155
- GetSuperclass,
156
- GetRootClass,
157
- IsSubclassOf,
158
- IsRootClass,
159
- IsDescendantClassOf,
160
- GetClassInheritance,
161
- GetFullClassHierarchy,
162
- IsClassConstructor,
163
- GetClassName
164
- } from '@memberjunction/global';
165
-
166
- // Example class hierarchy
167
- class Animal {}
168
- class Mammal extends Animal {}
169
- class Dog extends Mammal {}
170
- class GoldenRetriever extends Dog {}
171
-
172
- // Get immediate superclass
173
- const parent = GetSuperclass(GoldenRetriever); // Returns: Dog
174
-
175
- // Get root class of hierarchy
176
- const root = GetRootClass(GoldenRetriever); // Returns: Animal
177
-
178
- // Check inheritance relationships
179
- IsSubclassOf(GoldenRetriever, Animal); // true (checks entire chain)
180
- IsDescendantClassOf(GoldenRetriever, Animal); // true (alias for IsSubclassOf)
181
- IsRootClass(Animal); // true
182
- IsRootClass(Dog); // false
183
-
184
- // Get inheritance chain
185
- const chain = GetClassInheritance(GoldenRetriever);
186
- // Returns: [
187
- // { name: 'Dog', reference: Dog },
188
- // { name: 'Mammal', reference: Mammal },
189
- // { name: 'Animal', reference: Animal }
190
- // ]
191
-
192
- // Get full hierarchy including the class itself
193
- const fullChain = GetFullClassHierarchy(GoldenRetriever);
194
- // Returns: [
195
- // { name: 'GoldenRetriever', reference: GoldenRetriever },
196
- // { name: 'Dog', reference: Dog },
197
- // { name: 'Mammal', reference: Mammal },
198
- // { name: 'Animal', reference: Animal }
199
- // ]
200
-
201
- // Utility functions
202
- IsClassConstructor(Dog); // true
203
- IsClassConstructor(() => {}); // false
204
- GetClassName(GoldenRetriever); // "GoldenRetriever"
205
- ```
206
-
207
- ### Deep Diff Engine
208
-
209
- Comprehensive object comparison and change tracking with hierarchical diff visualization.
210
-
211
- ```typescript
212
- import { DeepDiffer, DiffChangeType } from '@memberjunction/global';
213
-
214
- // Create a differ instance
215
- const differ = new DeepDiffer({
216
- includeUnchanged: false, // Don't track unchanged values
217
- maxDepth: 10, // Maximum recursion depth
218
- maxStringLength: 100, // Truncate long strings
219
- treatNullAsUndefined: false // Treat null and undefined as distinct (default: false)
220
- });
221
-
222
- // Compare two objects
223
- const oldData = {
224
- user: { name: 'John', age: 30, role: 'admin' },
225
- settings: { theme: 'dark', notifications: true },
226
- tags: ['important', 'active']
227
- };
228
-
229
- const newData = {
230
- user: { name: 'John', age: 31, role: 'superadmin' },
231
- settings: { theme: 'light', notifications: true, language: 'en' },
232
- tags: ['important', 'active', 'premium']
233
- };
234
-
235
- // Get the diff
236
- const result = differ.diff(oldData, newData);
237
-
238
- // Access summary
239
- console.log(result.summary);
240
- // { added: 2, removed: 0, modified: 3, unchanged: 3, total: 8 }
241
-
242
- // Iterate through changes
243
- result.changes.forEach(change => {
244
- console.log(`${change.path}: ${change.type} - ${change.description}`);
245
- });
246
- // Output:
247
- // user.age: Modified - Changed from 30 to 31
248
- // user.role: Modified - Changed from "admin" to "superadmin"
249
- // settings.theme: Modified - Changed from "dark" to "light"
250
- // settings.language: Added - Value: "en"
251
- // tags[2]: Added - Value: "premium"
252
-
253
- // Filter changes by type
254
- const additions = result.changes.filter(c => c.type === DiffChangeType.Added);
255
- const modifications = result.changes.filter(c => c.type === DiffChangeType.Modified);
256
-
257
- // Update configuration on the fly
258
- differ.updateConfig({ includeUnchanged: true });
259
- ```
260
-
261
- #### Treating null as undefined
262
-
263
- When working with APIs or databases where `null` and `undefined` are used interchangeably, you can enable the `treatNullAsUndefined` option:
264
-
265
- ```typescript
266
- const differ = new DeepDiffer({ treatNullAsUndefined: true });
267
-
268
- const oldData = {
269
- name: null,
270
- status: 'active',
271
- oldProp: 'value'
272
- };
273
-
274
- const newData = {
275
- name: 'John', // Will show as "Added" instead of "Modified"
276
- status: null, // Will show as "Removed" instead of "Modified"
277
- newProp: 'value'
278
- };
279
-
280
- const result = differ.diff(oldData, newData);
281
- // With treatNullAsUndefined: true
282
- // - name: Added (not Modified, since null is treated as non-existent)
283
- // - status: Removed (not Modified, since null is treated as non-existent)
284
- // - oldProp: Removed
285
- // - newProp: Added
286
- ```
287
-
288
- ### JSON Validator
289
-
290
- Lightweight JSON validation with flexible validation rules and special field suffixes.
291
-
292
- ```typescript
293
- import { JSONValidator } from '@memberjunction/global';
294
-
295
- // Create validator instance
296
- const validator = new JSONValidator();
297
-
298
- // Define validation template with rules
299
- const template = {
300
- name: "John Doe", // Required field
301
- email?: "user@example.com", // Optional field
302
- settings*: {}, // Required, any content allowed
303
- tags:[1+]: ["tag1"], // Array with at least 1 item
304
- age:number: 25, // Must be a number
305
- username:string:!empty: "johndoe", // Non-empty string
306
- items:array:[2-5]?: ["A", "B"] // Optional array with 2-5 items
307
- };
308
-
309
- // Validate data against template
310
- const data = {
311
- name: "Jane Smith",
312
- tags: ["work", "urgent"],
313
- age: 30,
314
- username: "jsmith"
315
- };
316
-
317
- const result = validator.validate(data, template);
318
- if (result.Success) {
319
- console.log('Validation passed!');
320
- } else {
321
- result.Errors.forEach(error => {
322
- console.log(`${error.Source}: ${error.Message}`);
323
- });
324
- }
325
- ```
326
-
327
- #### Validation Syntax
328
-
329
- **Field Suffixes:**
330
- - `?` - Optional field (e.g., `email?`)
331
- - `*` - Required field with any content/structure (e.g., `payload*`)
332
-
333
- **Validation Rules (using `:` delimiter):**
334
- - **Array Length:**
335
- - `[N+]` - At least N elements (e.g., `tags:[1+]`)
336
- - `[N-M]` - Between N and M elements (e.g., `items:[2-5]`)
337
- - `[=N]` - Exactly N elements (e.g., `coordinates:[=2]`)
338
-
339
- - **Type Checking:**
340
- - `string` - Must be a string
341
- - `number` - Must be a number (NaN fails validation)
342
- - `boolean` - Must be a boolean
343
- - `object` - Must be an object (not array or null)
344
- - `array` - Must be an array
345
-
346
- - **Value Constraints:**
347
- - `!empty` - Non-empty string, array, or object
348
-
349
- **Combining Rules:**
350
- Multiple validation rules can be combined with `:` delimiter:
351
- ```typescript
352
- {
353
- // Array of strings with 2+ items
354
- "tags:array:[2+]": ["important", "urgent"],
355
-
356
- // Non-empty string
357
- "username:string:!empty": "johndoe",
358
-
359
- // Optional number
360
- "score:number?": 85,
361
-
362
- // Optional array with 1-3 items
363
- "options:array:[1-3]?": ["A", "B"]
364
- }
365
- ```
366
-
367
- #### Nested Object Validation
368
-
369
- The validator recursively validates nested objects:
370
-
371
- ```typescript
372
- const template = {
373
- user: {
374
- id:number: 123,
375
- name:string:!empty: "John",
376
- roles:array:[1+]: ["admin"]
377
- },
378
- settings?: {
379
- theme: "dark",
380
- notifications:boolean: true
381
- }
382
- };
383
- ```
384
-
385
- #### Cleaning Validation Syntax
386
-
387
- The validator can clean validation syntax from JSON objects that may have been returned by AI systems:
388
-
389
- ```typescript
390
- // AI might return JSON with validation syntax in keys
391
- const aiResponse = {
392
- "name?": "John Doe",
393
- "email:string": "john@example.com",
394
- "tags:[2+]": ["work", "urgent"],
395
- "settings*": { theme: "dark" },
396
- "score:number:!empty": 85
397
- };
398
-
399
- // Clean the validation syntax
400
- const cleaned = validator.cleanValidationSyntax<any>(aiResponse);
401
- // Returns:
402
- // {
403
- // "name": "John Doe",
404
- // "email": "john@example.com",
405
- // "tags": ["work", "urgent"],
406
- // "settings": { theme: "dark" },
407
- // "score": 85
408
- // }
409
- ```
410
-
411
- The `cleanValidationSyntax` method:
412
- - Recursively processes all object keys
413
- - Removes validation suffixes (`?`, `*`)
414
- - Removes validation rules (`:type`, `:[N+]`, `:!empty`, etc.)
415
- - Preserves the original values unchanged
416
- - Handles nested objects and arrays
417
- - Returns a new object with cleaned keys
418
-
419
- #### Convenience Methods
420
-
421
- ```typescript
422
- // Validate against JSON string
423
- const schemaJson = '{"name": "string", "age:number": 0}';
424
- const result = validator.validateAgainstSchema(data, schemaJson);
425
-
426
- // Integration with MemberJunction ValidationResult
427
- // Returns standard ValidationResult with ValidationErrorInfo[]
428
- // Compatible with existing MJ validation patterns
429
- ```
430
-
431
- #### Use Cases
432
-
433
- 1. **API Response Validation:**
434
- ```typescript
435
- const apiResponseTemplate = {
436
- status:string: "success",
437
- data*: {}, // Any data structure allowed
438
- errors:array?: []
439
- };
440
- ```
441
-
442
- 2. **Configuration Validation:**
443
- ```typescript
444
- const configTemplate = {
445
- apiUrl:string:!empty: "https://api.example.com",
446
- timeout:number: 5000,
447
- retries:number: 3,
448
- features:array:[1+]: ["logging"]
449
- };
450
- ```
451
-
452
- 3. **Form Data Validation:**
453
- ```typescript
454
- const formTemplate = {
455
- username:string:!empty: "user",
456
- email:string: "user@example.com",
457
- age:number?: 25,
458
- preferences:object?: {
459
- notifications:boolean: true
460
- }
461
- };
462
- ```
463
-
464
- ## Event Types
465
-
466
- The library provides predefined event types for common scenarios:
467
-
468
- ```typescript
469
- export const MJEventType = {
470
- ComponentRegistered: 'ComponentRegistered',
471
- ComponentUnregistered: 'ComponentUnregistered',
472
- ComponentEvent: 'ComponentEvent',
473
- LoggedIn: 'LoggedIn',
474
- LoggedOut: 'LoggedOut',
475
- LoginFailed: 'LoginFailed',
476
- LogoutFailed: 'LogoutFailed',
477
- ManualResizeRequest: 'ManualResizeRequest',
478
- DisplaySimpleNotificationRequest: 'DisplaySimpleNotificationRequest',
479
- } as const;
480
- ```
481
-
482
- ## Utility Functions
483
-
484
- ### String Manipulation
485
-
486
- ```typescript
487
- import {
488
- convertCamelCaseToHaveSpaces,
489
- stripWhitespace,
490
- generatePluralName,
491
- adjustCasing,
492
- stripTrailingChars,
493
- replaceAllSpaces
494
- } from '@memberjunction/global';
495
-
496
- // Convert camel case to spaces
497
- convertCamelCaseToHaveSpaces('AIAgentLearningCycle'); // "AI Agent Learning Cycle"
498
-
499
- // Remove all whitespace
500
- stripWhitespace(' Hello World '); // "HelloWorld"
501
-
502
- // Generate plural forms
503
- generatePluralName('child'); // "children"
504
- generatePluralName('box'); // "boxes"
505
- generatePluralName('party'); // "parties"
506
-
507
- // Adjust casing
508
- adjustCasing('hello', { capitalizeFirstLetterOnly: true }); // "Hello"
509
- adjustCasing('world', { capitalizeEntireWord: true }); // "WORLD"
510
-
511
- // Strip trailing characters
512
- stripTrailingChars('example.txt', '.txt', false); // "example"
513
-
514
- // Remove all spaces
515
- replaceAllSpaces('Hello World'); // "HelloWorld"
516
- ```
517
-
518
- ### JSON Utilities
519
-
520
- ```typescript
521
- import { CleanJSON, SafeJSONParse, ParseJSONRecursive } from '@memberjunction/global';
522
-
523
- // Safe JSON parsing with error handling
524
- const parsed = SafeJSONParse<MyType>('{"key": "value"}', true);
525
-
526
- // Recursively parse JSON strings within objects
527
- const input = {
528
- data: '{"nested": "{\\"deeply\\": \\"nested\\"}"}',
529
- messages: '[{"content": "{\\"type\\": \\"greeting\\", \\"text\\": \\"Hello\\"}"}]'
530
- };
531
- const output = ParseJSONRecursive(input);
532
- // Returns: {
533
- // data: { nested: { deeply: "nested" } },
534
- // messages: [{ content: { type: "greeting", text: "Hello" } }]
535
- // }
536
-
537
- // Extract inline JSON from text strings
538
- const textWithJson = {
539
- result: 'Action completed: {"status": "success", "count": 42}'
540
- };
541
- const extracted = ParseJSONRecursive(textWithJson, { extractInlineJson: true });
542
- // Returns: {
543
- // result: "Action completed:",
544
- // result_: { status: "success", count: 42 }
545
- // }
546
-
547
- // Control recursion depth and enable debugging
548
- const deeplyNested = ParseJSONRecursive(complexData, {
549
- maxDepth: 50, // Default: 100
550
- extractInlineJson: true, // Default: false
551
- debug: true // Default: false, logs parsing steps
552
- });
553
- ```
554
-
555
- #### CleanJSON Function
556
-
557
- The `CleanJSON` function intelligently extracts and cleans JSON from various input formats, including double-escaped strings, strings with embedded JSON, and markdown code blocks. It's particularly useful when dealing with AI-generated responses or data from external systems that may have inconsistent JSON formatting.
558
-
559
- **Processing Order:**
560
- 1. First attempts to parse the input as valid JSON (preserving embedded content)
561
- 2. If that fails, handles double-escaped characters (`\\n`, `\\"`, etc.)
562
- 3. Only extracts from markdown blocks or inline JSON as a last resort
563
-
564
- ```typescript
565
- import { CleanJSON } from '@memberjunction/global';
566
-
567
- // Example 1: Already valid JSON - returns formatted
568
- const valid = CleanJSON('{"name": "test", "value": 123}');
569
- // Returns:
570
- // {
571
- // "name": "test",
572
- // "value": 123
573
- // }
574
-
575
- // Example 2: Double-escaped JSON string
576
- const escaped = CleanJSON('{\\"name\\": \\"test\\", \\"value\\": 123}');
577
- // Returns:
578
- // {
579
- // "name": "test",
580
- // "value": 123
581
- // }
582
-
583
- // Example 3: JSON with escaped newlines (common from AI responses)
584
- const withNewlines = CleanJSON('\\n{\\"mode\\": \\"test\\",\\n\\"data\\": [1, 2, 3]}\\n');
585
- // Returns:
586
- // {
587
- // "mode": "test",
588
- // "data": [1, 2, 3]
589
- // }
590
-
591
- // Example 4: Complex JSON with embedded markdown (preserves the markdown)
592
- const complexJson = CleanJSON(`{
593
- "taskComplete": false,
594
- "message": "Processing complete",
595
- "nextAction": {
596
- "type": "design",
597
- "payload": {
598
- "outputFormat": "\`\`\`json\\n{\\"componentName\\": \\"Example\\"}\\n\`\`\`"
599
- }
600
- }
601
- }`);
602
- // Returns the JSON with the markdown code block preserved in the outputFormat field
603
-
604
- // Example 5: Extract JSON from markdown (only when input isn't valid JSON)
605
- const markdown = CleanJSON('Some text ```json\n{"extracted": true}\n``` more text');
606
- // Returns:
607
- // {
608
- // "extracted": true
609
- // }
610
-
611
- // Example 6: Extract inline JSON from mixed text
612
- const mixed = CleanJSON('Response: {"status": "success", "code": 200} - Done');
613
- // Returns:
614
- // {
615
- // "status": "success",
616
- // "code": 200
617
- // }
618
-
619
- // Example 7: Complex real-world example with nested escaped JSON
620
- const aiResponse = CleanJSON(`{
621
- "analysis": "Complete",
622
- "data": "{\\"users\\": [{\\"name\\": \\"John\\", \\"active\\": true}]}",
623
- "metadata": {
624
- "template": "\`\`\`json\\n{\\"format\\": \\"standard\\"}\\n\`\`\`"
625
- }
626
- }`);
627
- // Returns properly formatted JSON with all nested structures intact
628
- ```
629
-
630
- **Key Features:**
631
- - **Preserves embedded content**: When the input is valid JSON, markdown blocks and escaped strings within values are preserved
632
- - **Smart unescaping**: Handles `\\n` → `\n`, `\\"` → `"`, `\\\\` → `\` and other common escape sequences
633
- - **Markdown extraction**: Extracts JSON from ` ```json ` code blocks when needed
634
- - **Inline extraction**: Finds JSON objects/arrays within surrounding text
635
- - **Null safety**: Returns `null` for invalid inputs instead of throwing errors
636
-
637
- **Common Use Cases:**
638
- - Processing AI model responses that may contain escaped JSON
639
- - Cleaning data from external APIs with inconsistent formatting
640
- - Extracting JSON from log files or debug output
641
- - Handling JSON strings stored in databases that may be double-escaped
642
- - Processing user input that may contain JSON in various formats
643
-
644
- ### HTML Conversion
645
-
646
- ```typescript
647
- import { ConvertMarkdownStringToHtmlList } from '@memberjunction/global';
648
-
649
- // Convert markdown to HTML list
650
- const html = ConvertMarkdownStringToHtmlList('Unordered', '- Item 1\n- Item 2\n- Item 3');
651
- // Returns: <ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>
652
- ```
653
-
654
- ### Warning Manager
655
-
656
- The Warning Manager provides intelligent warning batching and deduplication for console messages across your application. It tracks warnings per session, groups them by type, and displays them in clean, formatted output after a configurable debounce period.
657
-
658
- #### Features
659
-
660
- - **Session-level tracking** - Each warning shown only once per session
661
- - **Debounced output** - Groups warnings and displays after a configurable quiet period (default 10s)
662
- - **Multiple warning types** - Supports deprecation warnings and data integrity warnings
663
- - **Beautiful formatting** - Tree-structured console output with emojis and clear grouping
664
- - **Configurable** - Runtime API and environment variables for customization
665
- - **Backward compatible** - `DeprecationWarningManager` alias provided
666
-
667
- #### Basic Usage
668
-
669
- ```typescript
670
- import { WarningManager } from '@memberjunction/global';
671
-
672
- const wm = WarningManager.Instance;
673
-
674
- // Record deprecation warnings
675
- wm.RecordEntityDeprecationWarning('LegacyEntity', 'MyComponent::method');
676
- wm.RecordFieldDeprecationWarning('Users', 'OldField', 'DataLoader::process');
677
-
678
- // Record field-not-found warnings (data integrity issues)
679
- wm.RecordFieldNotFoundWarning('Users', 'DeletedColumn', 'BaseEntity::SetMany during import');
680
-
681
- // Warnings are automatically batched and displayed after debounce period
682
- // Or manually flush immediately:
683
- wm.FlushWarnings();
684
- ```
685
-
686
- #### Example Output
687
-
688
- ```
689
- ⚠️ DEPRECATION WARNINGS - The following entities/fields are deprecated and may be removed in future versions:
690
-
691
- 📦 DEPRECATED ENTITIES:
692
- • "LegacyEntity" (called from: MyComponent::method)
693
-
694
- 📋 DEPRECATED ENTITY FIELDS:
695
- └─ "Users"
696
- └─ OldField (called from: DataLoader::process)
697
-
698
- 💡 Set ShowAll=true in configuration to see every occurrence.
699
-
700
-
701
- ⚠️ DATA INTEGRITY WARNINGS - The following fields were not found in entity definitions:
702
-
703
- 📋 MISSING FIELDS:
704
- └─ "Users"
705
- └─ DeletedColumn (context: BaseEntity::SetMany during import)
706
-
707
- 💡 These fields exist in your data but not in the entity schema. This may indicate:
708
- • Schema is out of sync with database
709
- • Data contains legacy fields that were removed
710
- • Field names have been changed
711
- ```
712
-
713
- #### Configuration
714
-
715
- Configure via runtime API:
716
-
717
- ```typescript
718
- wm.UpdateConfig({
719
- DebounceMs: 5000, // Wait 5 seconds after last warning
720
- ShowAll: false, // Show each warning once per session (default)
721
- DisableWarnings: false, // Enable warnings (default)
722
- GroupWarnings: true // Group warnings in tree format (default)
723
- });
724
-
725
- // Get current configuration
726
- const config = wm.GetConfig();
727
- ```
728
-
729
- All configuration is done via the runtime API.
730
-
731
- #### Warning Types
732
-
733
- **Deprecation Warnings** indicate entities or fields that may be removed in future versions:
734
- - `RecordEntityDeprecationWarning(entityName, callerName)` - Deprecated entity
735
- - `RecordFieldDeprecationWarning(entityName, fieldName, callerName)` - Deprecated field
736
-
737
- **Data Integrity Warnings** indicate mismatches between data and schema:
738
- - `RecordFieldNotFoundWarning(entityName, fieldName, context)` - Field exists in data but not in schema
739
-
740
- #### Advanced Usage
741
-
742
- ```typescript
743
- // Reset all tracking (useful for testing)
744
- wm.Reset();
745
-
746
- // Backward compatibility - DeprecationWarningManager is an alias
747
- import { DeprecationWarningManager } from '@memberjunction/global';
748
- const dwm = DeprecationWarningManager.Instance; // Same as WarningManager.Instance
749
- ```
750
-
751
- #### Use Cases
752
-
753
- 1. **Framework-level warnings** - Alert developers about deprecated APIs
754
- 2. **Data migration** - Track fields that don't match current schema
755
- 3. **Development debugging** - Identify outdated code patterns
756
- 4. **Testing** - Verify no deprecated features are used
757
-
758
- ### Safe Expression Evaluator
759
-
760
- Secure boolean expression evaluation for conditional logic without allowing arbitrary code execution:
761
-
762
- ```typescript
763
- import { SafeExpressionEvaluator } from '@memberjunction/global';
764
-
765
- // Create evaluator instance
766
- const evaluator = new SafeExpressionEvaluator();
767
-
768
- // Simple comparisons
769
- const result1 = evaluator.evaluate(
770
- "status == 'active' && score > 80",
771
- { status: 'active', score: 95 }
772
- );
773
- console.log(result1.success); // true
774
- console.log(result1.value); // true
775
-
776
- // Nested property access with dot notation
777
- const result2 = evaluator.evaluate(
778
- "user.role == 'admin' && user.permissions.includes('write')",
779
- {
780
- user: {
781
- role: 'admin',
782
- permissions: ['read', 'write', 'delete']
783
- }
784
- }
785
- );
786
- console.log(result2.value); // true
787
-
788
- // Array methods and complex conditions
789
- const result3 = evaluator.evaluate(
790
- "items.some(item => item.price > 100) && items.length >= 2",
791
- {
792
- items: [
793
- { name: 'Item 1', price: 50 },
794
- { name: 'Item 2', price: 150 }
795
- ]
796
- }
797
- );
798
- console.log(result3.value); // true
799
-
800
- // Error handling for invalid expressions
801
- const result4 = evaluator.evaluate(
802
- "eval('malicious code')", // Dangerous patterns are blocked
803
- { data: 'test' }
804
- );
805
- console.log(result4.success); // false
806
- console.log(result4.error); // "Expression contains forbidden construct: /\beval\s*\(/i"
807
-
808
- // With diagnostics enabled
809
- const result5 = evaluator.evaluate(
810
- "payload.status == 'complete'",
811
- { payload: { status: 'complete' } },
812
- true // Enable diagnostics
813
- );
814
- console.log(result5.diagnostics);
815
- // {
816
- // expression: "payload.status == 'complete'",
817
- // context: { payload: { status: 'complete' } },
818
- // evaluationTime: 2
819
- // }
820
- ```
821
-
822
- #### Supported Operations
823
-
824
- **Comparison Operators:**
825
- - `==`, `===`, `!=`, `!==`
826
- - `<`, `>`, `<=`, `>=`
827
-
828
- **Logical Operators:**
829
- - `&&`, `||`, `!`
830
-
831
- **Property Access:**
832
- - Dot notation: `object.property.nested`
833
- - Array access: `array[0]`, `array[index]`
834
-
835
- **Safe Methods:**
836
- - String: `.length`, `.includes()`, `.startsWith()`, `.endsWith()`, `.toLowerCase()`, `.toUpperCase()`, `.trim()`
837
- - Array: `.length`, `.includes()`, `.some()`, `.every()`, `.find()`, `.filter()`, `.map()`
838
- - Type checking: `typeof`, limited `instanceof`
839
-
840
- **Type Coercion:**
841
- - `Boolean(value)`
842
- - String concatenation with `+`
843
-
844
- #### Security Features
845
-
846
- The evaluator blocks dangerous patterns including:
847
- - `eval()`, `Function()`, `new Function()`
848
- - `require()`, `import` statements
849
- - Access to `global`, `window`, `document`, `process`
850
- - Template literals and string interpolation
851
- - Code blocks with `{}` and `;`
852
- - `this` keyword usage
853
- - `constructor`, `prototype`, `__proto__` access
854
-
855
- #### Use Cases
856
-
857
- 1. **Workflow Conditions:**
858
- ```typescript
859
- // Evaluate workflow paths
860
- const canProceed = evaluator.evaluate(
861
- "order.status == 'approved' && order.total < budget",
862
- { order: { status: 'approved', total: 500 }, budget: 1000 }
863
- ).value;
864
- ```
865
-
866
- 2. **Feature Flags:**
867
- ```typescript
868
- // Check feature availability
869
- const featureEnabled = evaluator.evaluate(
870
- "user.tier == 'premium' || user.roles.includes('beta')",
871
- { user: { tier: 'standard', roles: ['beta', 'tester'] } }
872
- ).value;
873
- ```
874
-
875
- 3. **Validation Rules:**
876
- ```typescript
877
- // Dynamic validation
878
- const isValid = evaluator.evaluate(
879
- "form.password.length >= 8 && form.password != form.username",
880
- { form: { username: 'john', password: 'secretpass123' } }
881
- ).value;
882
- ```
883
-
884
- 4. **Agent Decision Logic:**
885
- ```typescript
886
- // AI agent path selection
887
- const shouldDelegate = evaluator.evaluate(
888
- "confidence < 0.7 || taskComplexity > 8",
889
- { confidence: 0.6, taskComplexity: 5 }
890
- ).value;
891
- ```
892
-
893
- #### Batch Evaluation
894
-
895
- Evaluate multiple expressions at once:
896
-
897
- ```typescript
898
- const results = evaluator.evaluateMultiple([
899
- { expression: "status == 'active'", name: 'isActive' },
900
- { expression: "score > threshold", name: 'passedThreshold' },
901
- { expression: "tags.includes('priority')", name: 'isPriority' }
902
- ], {
903
- status: 'active',
904
- score: 85,
905
- threshold: 80,
906
- tags: ['urgent', 'priority']
907
- });
908
-
909
- // Results:
910
- // {
911
- // isActive: { success: true, value: true },
912
- // passedThreshold: { success: true, value: true },
913
- // isPriority: { success: true, value: true }
914
- // }
915
- ```
916
-
917
- ### Pattern Matching Utilities
918
-
919
- Convert string patterns to RegExp objects with support for simple wildcards and full regex syntax:
920
-
921
- ```typescript
922
- import {
923
- parsePattern,
924
- parsePatterns,
925
- ensureRegExp,
926
- ensureRegExps,
927
- matchesAnyPattern,
928
- matchesAllPatterns
929
- } from '@memberjunction/global';
930
-
931
- // Parse simple wildcard patterns
932
- parsePattern('*AIPrompt*'); // Returns: /AIPrompt/i (case-insensitive)
933
- parsePattern('spCreate*'); // Returns: /^spCreate/i
934
- parsePattern('*Run'); // Returns: /Run$/i
935
- parsePattern('exact'); // Returns: /^exact$/i
936
-
937
- // Parse regex string patterns
938
- parsePattern('/spCreate.*Run/i'); // Returns: /spCreate.*Run/i
939
- parsePattern('/^SELECT.*FROM.*vw/'); // Returns: /^SELECT.*FROM.*vw/
940
- parsePattern('/INSERT INTO (Users|Roles)/i'); // Returns: /INSERT INTO (Users|Roles)/i
941
-
942
- // Parse multiple patterns at once
943
- const patterns = parsePatterns([
944
- '*User*', // Simple wildcard
945
- '/^EXEC sp_/i', // Regex string
946
- '*EntityFieldValue*' // Simple wildcard
947
- ]);
948
-
949
- // Convert mixed string/RegExp arrays
950
- const mixed = ['*User*', /^Admin/i, '/DELETE.*WHERE/i'];
951
- const regexps = ensureRegExps(mixed); // All converted to RegExp objects
952
-
953
- // Test if text matches any pattern
954
- const sql = 'SELECT * FROM Users WHERE Active = 1';
955
- matchesAnyPattern(sql, ['*User*', '*Role*', '/^UPDATE/i']); // true
956
-
957
- // Test if text matches all patterns
958
- const filename = 'UserRoleManager.ts';
959
- matchesAllPatterns(filename, ['*User*', '*Role*', '*.ts']); // true
960
- ```
961
-
962
- #### Pattern Syntax
963
-
964
- **Simple Wildcard Patterns** (Recommended for most users):
965
- - `*` acts as a wildcard matching any characters
966
- - Case-insensitive by default
967
- - Examples:
968
- - `*pattern*` - Contains "pattern" anywhere
969
- - `pattern*` - Starts with "pattern"
970
- - `*pattern` - Ends with "pattern"
971
- - `pattern` - Exact match only
972
-
973
- **Regex String Patterns** (For advanced users):
974
- - Must start with `/` to be recognized as regex
975
- - Optionally end with flags like `/pattern/i`
976
- - Full JavaScript regex syntax supported
977
- - Examples:
978
- - `/^start/i` - Case-insensitive start match
979
- - `/end$/` - Case-sensitive end match
980
- - `/(option1|option2)/` - Match alternatives
981
-
982
- #### Common Use Cases
983
-
984
- ```typescript
985
- // SQL statement filtering
986
- const sqlFilters = [
987
- '*AIPrompt*', // Exclude AI prompt operations
988
- '/^EXEC sp_/i', // Exclude system stored procedures
989
- '*EntityFieldValue*' // Exclude field value operations
990
- ];
991
-
992
- const shouldLog = !matchesAnyPattern(sqlStatement, sqlFilters);
993
-
994
- // File pattern matching
995
- const includePatterns = ['*.ts', '*.js', '/^(?!test)/']; // TS/JS files not starting with "test"
996
- const shouldProcess = matchesAnyPattern(filename, includePatterns);
997
-
998
- // User input validation
999
- const allowedFormats = ['*@*.com', '*@*.org', '*@company.net'];
1000
- const isValidEmail = matchesAnyPattern(email, allowedFormats);
1001
- ```
1002
-
1003
- ### Global Object Store
1004
-
1005
- Access the global object store for cross-module state sharing:
1006
-
1007
- ```typescript
1008
- import { GetGlobalObjectStore } from '@memberjunction/global';
1009
-
1010
- const globalStore = GetGlobalObjectStore();
1011
- // Returns window object in browser, global in Node.js
1012
- ```
1013
-
1014
- ### Manual Resize Request
1015
-
1016
- Trigger a manual resize event across components:
1017
-
1018
- ```typescript
1019
- import { InvokeManualResize } from '@memberjunction/global';
1020
-
1021
- // Request resize after 50ms delay
1022
- InvokeManualResize(50, myComponent);
1023
- ```
1024
-
1025
- ## Advanced Usage
1026
-
1027
- ### Class Factory with Root Class Detection
1028
-
1029
- The Class Factory automatically detects and uses root classes for registration, ensuring proper priority ordering in inheritance hierarchies:
1030
-
1031
- ```typescript
1032
- class BaseEntity {} // Root class
1033
-
1034
- class UserEntity extends BaseEntity {}
1035
-
1036
- // This automatically registers with BaseEntity (the root)
1037
- @RegisterClass(UserEntity, 'Admin')
1038
- class AdminUserEntity extends UserEntity {}
1039
-
1040
- // Also registers with BaseEntity, gets higher priority
1041
- @RegisterClass(AdminUserEntity, 'SuperAdmin')
1042
- class SuperAdminEntity extends AdminUserEntity {}
1043
-
1044
- // All of these create SuperAdminEntity (highest priority)
1045
- factory.CreateInstance(BaseEntity, 'SuperAdmin'); // ✓ Works
1046
- factory.CreateInstance(UserEntity, 'SuperAdmin'); // ✓ Works
1047
- factory.CreateInstance(AdminUserEntity, 'SuperAdmin'); // ✓ Works
1048
- ```
1049
-
1050
- ### Disabling Auto-Root Registration
1051
-
1052
- Sometimes you want to register at a specific level in the hierarchy:
1053
-
1054
- ```typescript
1055
- // Register directly to UserEntity, not BaseEntity
1056
- @RegisterClass(UserEntity, 'Special', 0, false, false) // Last param = false
1057
- class SpecialUserEntity extends UserEntity {
1058
- // This only matches when creating from UserEntity, not BaseEntity
1059
- }
1060
-
1061
- // Direct registration queries
1062
- factory.CreateInstance(UserEntity, 'Special'); // ✓ Returns SpecialUserEntity
1063
- factory.CreateInstance(BaseEntity, 'Special'); // ✗ Returns BaseEntity instance
1064
- ```
1065
-
1066
- ### Class Factory with Parameters
1067
-
1068
- ```typescript
1069
- // Register a class that requires constructor parameters
1070
- @RegisterClass(BaseService, 'api')
1071
- class ApiService extends BaseService {
1072
- constructor(private apiUrl: string) {
1073
- super();
1074
- }
1075
- }
1076
-
1077
- // Create with parameters
1078
- const service = factory.CreateInstance<BaseService>(
1079
- BaseService,
1080
- 'api',
1081
- 'https://api.example.com'
1082
- );
1083
- ```
1084
-
1085
- ### Priority-based Registration
1086
-
1087
- ```typescript
1088
- // Lower priority (registered first)
1089
- @RegisterClass(BaseHandler, 'data', 10)
1090
- class BasicDataHandler extends BaseHandler {}
1091
-
1092
- // Higher priority (overrides BasicDataHandler)
1093
- @RegisterClass(BaseHandler, 'data', 20)
1094
- class AdvancedDataHandler extends BaseHandler {}
1095
-
1096
- // Will create AdvancedDataHandler instance
1097
- const handler = factory.CreateInstance<BaseHandler>(BaseHandler, 'data');
1098
- ```
1099
-
1100
- ### Inspecting Registrations
1101
-
1102
- ```typescript
1103
- // Get all registrations for a base class
1104
- const registrations = factory.GetAllRegistrations(BaseEntity, 'Users');
1105
-
1106
- // Get registrations by root class
1107
- const rootRegistrations = factory.GetRegistrationsByRootClass(BaseEntity);
1108
-
1109
- // Each registration contains:
1110
- // - BaseClass: The class it's registered to (usually root)
1111
- // - SubClass: The actual implementation class
1112
- // - RootClass: The detected root of the hierarchy
1113
- // - Key: The registration key
1114
- // - Priority: The priority number
1115
- ```
1116
-
1117
- ### Global Properties
1118
-
1119
- Store and retrieve global properties:
1120
-
1121
- ```typescript
1122
- const properties = MJGlobal.Instance.Properties;
1123
- properties.push({
1124
- key: 'apiEndpoint',
1125
- value: 'https://api.example.com'
1126
- });
1127
- ```
1128
-
1129
- ## Integration with MemberJunction
1130
-
1131
- This package is a core dependency for most MemberJunction packages. It provides the foundation for:
1132
-
1133
- - Entity registration and instantiation
1134
- - Cross-component event communication
1135
- - Singleton service management
1136
- - Global state coordination
1137
-
1138
- When building MemberJunction applications or extensions, use this package to ensure proper integration with the framework's architecture.
1139
-
1140
- ## TypeScript Support
1141
-
1142
- This package is written in TypeScript and includes full type definitions. All exports are properly typed for excellent IDE support and compile-time type checking.
1143
-
1144
- ## Dependencies
1145
-
1146
- - **rxjs** (^7.8.1) - For reactive event handling
1147
-
1148
- ## Development
1149
-
1150
- ```bash
1151
- # Build the package
1152
- npm run build
1153
-
1154
- # Start in development mode with hot reload
1155
- npm run start
1156
-
1157
- # Run tests (when implemented)
1158
- npm test
1159
- ```
1160
-
1161
- ## License
1162
-
1163
- ISC
1164
-
1165
- ## Author
1166
-
1167
- MemberJunction.com
1168
-