@memberjunction/data-context 2.43.0 → 2.44.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 (2) hide show
  1. package/package.json +4 -4
  2. package/readme.md +304 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/data-context",
3
- "version": "2.43.0",
3
+ "version": "2.44.0",
4
4
  "description": "This library provides a set of objects that handle run-time loading of data contexts as well as types to be able to use across application tiers for interacting with data contexts.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,8 +19,8 @@
19
19
  "typescript": "^5.4.5"
20
20
  },
21
21
  "dependencies": {
22
- "@memberjunction/global": "2.43.0",
23
- "@memberjunction/core-entities": "2.43.0",
24
- "@memberjunction/core": "2.43.0"
22
+ "@memberjunction/global": "2.44.0",
23
+ "@memberjunction/core-entities": "2.44.0",
24
+ "@memberjunction/core": "2.44.0"
25
25
  }
26
26
  }
package/readme.md CHANGED
@@ -1,3 +1,306 @@
1
1
  # @memberjunction/data-context
2
2
 
3
- The `@memberjunction/data-context` library provides a set of objects that handle run-time loading of data contexts as well as types to be able to use across application tiers for interacting with data contexts.
3
+ The `@memberjunction/data-context` library provides a comprehensive framework for managing data contexts in MemberJunction applications. It enables developers to define, load, and manipulate collections of related data items across different tiers of an application.
4
+
5
+ ## Overview
6
+
7
+ A Data Context in MemberJunction represents a collection of data items that can include:
8
+ - **Views**: Filtered and customized views of entity data
9
+ - **Queries**: Pre-defined SQL queries registered in the system
10
+ - **Full Entities**: Complete data sets from an entity
11
+ - **Single Records**: Individual entity records with optional related data
12
+ - **SQL Statements**: Direct SQL queries (server-side only)
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @memberjunction/data-context
18
+ ```
19
+
20
+ ## Key Features
21
+
22
+ - **Type-safe data context management**: Full TypeScript support with proper typing
23
+ - **Flexible data loading**: Support for various data sources including views, queries, entities, and SQL
24
+ - **Metadata-driven**: Automatic loading of metadata from the MemberJunction system
25
+ - **Transaction support**: Save multiple data context items in a single transaction
26
+ - **Cross-tier compatibility**: Works across server and client tiers with appropriate implementations
27
+ - **Data persistence**: Optional saving of loaded data to the database
28
+
29
+ ## Usage
30
+
31
+ ### Basic Example
32
+
33
+ ```typescript
34
+ import { DataContext, DataContextItem } from '@memberjunction/data-context';
35
+ import { Metadata } from '@memberjunction/core';
36
+
37
+ // Create a new data context
38
+ const context = new DataContext();
39
+
40
+ // Load metadata and data for an existing data context
41
+ const dataContextID = 'your-data-context-id';
42
+ const loaded = await context.Load(
43
+ dataContextID,
44
+ dataSource, // Required for SQL type items (server-side only)
45
+ false, // forceRefresh
46
+ true, // loadRelatedDataOnSingleRecords
47
+ 10, // maxRecordsPerRelationship
48
+ userInfo // contextUser
49
+ );
50
+
51
+ if (loaded) {
52
+ // Access the loaded data
53
+ context.Items.forEach(item => {
54
+ console.log(`Item: ${item.Description}`);
55
+ console.log(`Data rows: ${item.Data?.length || 0}`);
56
+ });
57
+ }
58
+ ```
59
+
60
+ ### Creating Data Context Items
61
+
62
+ #### From a View
63
+
64
+ ```typescript
65
+ import { UserViewEntityExtended } from '@memberjunction/core-entities';
66
+
67
+ // Assuming you have a view entity loaded
68
+ const viewEntity: UserViewEntityExtended = await md.GetEntityObject<UserViewEntityExtended>('User Views');
69
+ await viewEntity.Load(viewID);
70
+
71
+ const viewItem = DataContextItem.FromViewEntity(viewEntity);
72
+ context.Items.push(viewItem);
73
+ ```
74
+
75
+ #### From a Single Record
76
+
77
+ ```typescript
78
+ import { BaseEntity } from '@memberjunction/core';
79
+
80
+ // Assuming you have an entity record loaded
81
+ const record: BaseEntity = await md.GetEntityObject('Customers');
82
+ await record.Load(recordID);
83
+
84
+ const recordItem = DataContextItem.FromSingleRecord(record);
85
+ context.Items.push(recordItem);
86
+ ```
87
+
88
+ #### From a Query
89
+
90
+ ```typescript
91
+ import { QueryInfo } from '@memberjunction/core';
92
+
93
+ // Get query info from metadata
94
+ const queryInfo = md.Queries.find(q => q.Name === 'My Query');
95
+ if (queryInfo) {
96
+ const queryItem = DataContextItem.FromQuery(queryInfo);
97
+ context.Items.push(queryItem);
98
+ }
99
+ ```
100
+
101
+ #### From a Full Entity
102
+
103
+ ```typescript
104
+ import { EntityInfo } from '@memberjunction/core';
105
+
106
+ // Get entity info from metadata
107
+ const entityInfo = md.Entities.find(e => e.Name === 'Products');
108
+ if (entityInfo) {
109
+ const entityItem = DataContextItem.FromFullEntity(entityInfo);
110
+ context.Items.push(entityItem);
111
+ }
112
+ ```
113
+
114
+ ### Loading Data for Items
115
+
116
+ ```typescript
117
+ // Load data for all items in the context
118
+ const dataLoaded = await context.LoadData(
119
+ dataSource, // Required for SQL type items
120
+ false, // forceRefresh
121
+ true, // loadRelatedDataOnSingleRecords
122
+ 10 // maxRecordsPerRelationship
123
+ );
124
+
125
+ // Or load data for a specific item
126
+ const itemLoaded = await context.Items[0].LoadData(
127
+ dataSource,
128
+ false,
129
+ true,
130
+ 10
131
+ );
132
+ ```
133
+
134
+ ### Saving Data Context Items
135
+
136
+ ```typescript
137
+ // Save all items in the context to the database
138
+ const saved = await context.SaveItems(
139
+ userInfo, // contextUser
140
+ true // persistItemData - saves actual data, not just metadata
141
+ );
142
+
143
+ if (saved) {
144
+ console.log('Data context items saved successfully');
145
+ // Each item now has a DataContextItemID populated
146
+ }
147
+ ```
148
+
149
+ ### Working with Data
150
+
151
+ ```typescript
152
+ // Validate that all items have data loaded
153
+ if (context.ValidateDataExists()) {
154
+ // Convert to a simple object for easier manipulation
155
+ const simpleData = context.ConvertToSimpleObject('item_', false);
156
+ // Result: { item_0: [...], item_1: [...], ... }
157
+
158
+ // Get type definition for the data structure
159
+ const typeDef = context.CreateSimpleObjectTypeDefinition('item_');
160
+ console.log(typeDef);
161
+ // Output: {item_0: []; // View: Customer List, From Entity: Customers\n...}
162
+ }
163
+
164
+ // Access individual item data
165
+ context.Items.forEach(item => {
166
+ if (item.DataLoaded && item.Data) {
167
+ console.log(`${item.Description}: ${item.Data.length} rows`);
168
+
169
+ // Process the data
170
+ item.Data.forEach(row => {
171
+ // Work with row data
172
+ });
173
+ } else if (item.DataLoadingError) {
174
+ console.error(`Error loading ${item.Description}: ${item.DataLoadingError}`);
175
+ }
176
+ });
177
+ ```
178
+
179
+ ### Cloning Data Contexts
180
+
181
+ ```typescript
182
+ // Clone an existing data context
183
+ const clonedContext = await DataContext.Clone(
184
+ originalContext,
185
+ true, // includeData - copies the data along with metadata
186
+ userInfo // contextUser
187
+ );
188
+
189
+ if (clonedContext) {
190
+ console.log(`Cloned context ID: ${clonedContext.ID}`);
191
+ }
192
+ ```
193
+
194
+ ## API Reference
195
+
196
+ ### DataContext Class
197
+
198
+ #### Properties
199
+
200
+ - `ID: string` - The unique identifier of the data context
201
+ - `DataContextEntity: DataContextEntity` - The metadata entity for the data context
202
+ - `Items: DataContextItem[]` - Array of data context items
203
+
204
+ #### Methods
205
+
206
+ - `async LoadMetadata(DataContextID: string, contextUser?: UserInfo, provider?: IMetadataProvider): Promise<boolean>`
207
+ - Loads only the metadata for the data context and its items
208
+
209
+ - `async LoadData(dataSource: any, forceRefresh?: boolean, loadRelatedDataOnSingleRecords?: boolean, maxRecordsPerRelationship?: number, contextUser?: UserInfo): Promise<boolean>`
210
+ - Loads data for all items in the context
211
+
212
+ - `async Load(DataContextID: string, dataSource: any, forceRefresh?: boolean, loadRelatedDataOnSingleRecords?: boolean, maxRecordsPerRelationship?: number, contextUser?: UserInfo): Promise<boolean>`
213
+ - Loads both metadata and data in one operation
214
+
215
+ - `async SaveItems(contextUser?: UserInfo, persistItemData?: boolean): Promise<boolean>`
216
+ - Saves all data context items to the database
217
+
218
+ - `AddDataContextItem(): DataContextItem`
219
+ - Creates and adds a new item to the context
220
+
221
+ - `ValidateDataExists(ignoreFailedLoadItems?: boolean): boolean`
222
+ - Checks if all items have data loaded
223
+
224
+ - `ConvertToSimpleObject(itemPrefix?: string, includeFailedLoadItems?: boolean): any`
225
+ - Converts the context to a simple object structure
226
+
227
+ - `CreateSimpleObjectTypeDefinition(itemPrefix?: string, includeFailedLoadItems?: boolean): string`
228
+ - Generates TypeScript type definition for the data structure
229
+
230
+ - `LoadDataFromObject(data: any[][]): boolean`
231
+ - Loads pre-fetched data into the context
232
+
233
+ - `static async Clone(context: DataContext, includeData?: boolean, contextUser?: UserInfo): Promise<DataContext>`
234
+ - Creates a deep copy of a data context
235
+
236
+ - `static async FromRawData(rawData: any): Promise<DataContext>`
237
+ - Creates a context from raw data object
238
+
239
+ ### DataContextItem Class
240
+
241
+ #### Properties
242
+
243
+ - `Type: 'view' | 'query' | 'full_entity' | 'sql' | 'single_record'` - The type of data item
244
+ - `RecordID: string` - Primary key for single_record types
245
+ - `EntityID?: string` - Entity identifier
246
+ - `ViewID?: string` - View identifier
247
+ - `QueryID?: string` - Query identifier
248
+ - `RecordName: string` - Name of the view, query, or entity
249
+ - `SQL?: string` - SQL statement for 'sql' type
250
+ - `EntityName?: string` - Name of the entity
251
+ - `Fields: DataContextFieldInfo[]` - Field metadata
252
+ - `Data: any[]` - The loaded data
253
+ - `DataLoaded: boolean` - Indicates if data has been loaded
254
+ - `DataLoadingError?: string` - Error message if loading failed
255
+ - `Description: string` - Auto-generated description
256
+ - `AdditionalDescription?: string` - Optional custom description
257
+
258
+ #### Methods
259
+
260
+ - `async LoadData(dataSource: any, forceRefresh?: boolean, loadRelatedDataOnSingleRecords?: boolean, maxRecordsPerRelationship?: number, contextUser?: UserInfo): Promise<boolean>`
261
+ - Loads data for this specific item
262
+
263
+ - `LoadDataFromObject(data: any[]): boolean`
264
+ - Loads pre-fetched data into the item
265
+
266
+ - `ValidateDataExists(ignoreFailedLoad?: boolean): boolean`
267
+ - Validates that data has been loaded
268
+
269
+ - `static FromViewEntity(viewEntity: UserViewEntityExtended): DataContextItem`
270
+ - `static FromSingleRecord(singleRecord: BaseEntity): DataContextItem`
271
+ - `static FromQuery(query: QueryInfo): DataContextItem`
272
+ - `static FromFullEntity(entity: EntityInfo): DataContextItem`
273
+ - `static FromRawItem(rawItem: any): DataContextItem`
274
+
275
+ ### DataContextFieldInfo Class
276
+
277
+ ```typescript
278
+ class DataContextFieldInfo {
279
+ Name: string;
280
+ Type: string;
281
+ Description?: string;
282
+ }
283
+ ```
284
+
285
+ ## Server-Side Considerations
286
+
287
+ For SQL type data context items, you'll need to use the server-side implementation from `@memberjunction/data-context-server` which properly handles SQL execution with appropriate security and data source management.
288
+
289
+ ## Dependencies
290
+
291
+ - `@memberjunction/global`: Core global utilities and class factory
292
+ - `@memberjunction/core-entities`: Entity definitions for MemberJunction
293
+ - `@memberjunction/core`: Core MemberJunction functionality
294
+
295
+ ## Best Practices
296
+
297
+ 1. **Always load metadata before data**: Use `LoadMetadata()` before `LoadData()` or simply use `Load()` which does both
298
+ 2. **Handle loading errors**: Check `DataLoaded` and `DataLoadingError` properties on items
299
+ 3. **Use appropriate data sources**: SQL type items require server-side data sources
300
+ 4. **Consider performance**: Use `maxRecordsPerRelationship` to limit related data loading
301
+ 5. **Validate before use**: Call `ValidateDataExists()` before processing data
302
+ 6. **Use transactions**: When saving multiple items, they're automatically wrapped in a transaction
303
+
304
+ ## License
305
+
306
+ ISC