@finos/legend-graph 30.0.2 → 30.0.4

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 (30) hide show
  1. package/lib/graph/DependencyManager.d.ts +1 -0
  2. package/lib/graph/DependencyManager.d.ts.map +1 -1
  3. package/lib/graph/DependencyManager.js +1 -1
  4. package/lib/graph/DependencyManager.js.map +1 -1
  5. package/lib/graph-manager/protocol/pure/PureProtocolProcessorPlugin.d.ts +10 -0
  6. package/lib/graph-manager/protocol/pure/PureProtocolProcessorPlugin.d.ts.map +1 -1
  7. package/lib/graph-manager/protocol/pure/PureProtocolProcessorPlugin.js.map +1 -1
  8. package/lib/graph-manager/protocol/pure/extensions/DSL_ExternalFormat_PureProtocolProcessorPlugin.d.ts +2 -1
  9. package/lib/graph-manager/protocol/pure/extensions/DSL_ExternalFormat_PureProtocolProcessorPlugin.d.ts.map +1 -1
  10. package/lib/graph-manager/protocol/pure/extensions/DSL_ExternalFormat_PureProtocolProcessorPlugin.js +5 -0
  11. package/lib/graph-manager/protocol/pure/extensions/DSL_ExternalFormat_PureProtocolProcessorPlugin.js.map +1 -1
  12. package/lib/graph-manager/protocol/pure/v1/V1_PureGraphManager.d.ts +4 -1
  13. package/lib/graph-manager/protocol/pure/v1/V1_PureGraphManager.d.ts.map +1 -1
  14. package/lib/graph-manager/protocol/pure/v1/V1_PureGraphManager.js +66 -23
  15. package/lib/graph-manager/protocol/pure/v1/V1_PureGraphManager.js.map +1 -1
  16. package/lib/graph-manager/protocol/pure/v1/engine/execution/V1_ExecuteInput.d.ts.map +1 -1
  17. package/lib/graph-manager/protocol/pure/v1/engine/execution/V1_ExecuteInput.js +2 -2
  18. package/lib/graph-manager/protocol/pure/v1/engine/execution/V1_ExecuteInput.js.map +1 -1
  19. package/lib/index.d.ts +1 -1
  20. package/lib/index.d.ts.map +1 -1
  21. package/lib/index.js +1 -1
  22. package/lib/index.js.map +1 -1
  23. package/lib/package.json +1 -1
  24. package/package.json +1 -1
  25. package/src/graph/DependencyManager.ts +3 -2
  26. package/src/graph-manager/protocol/pure/PureProtocolProcessorPlugin.ts +23 -0
  27. package/src/graph-manager/protocol/pure/extensions/DSL_ExternalFormat_PureProtocolProcessorPlugin.ts +15 -0
  28. package/src/graph-manager/protocol/pure/v1/V1_PureGraphManager.ts +97 -33
  29. package/src/graph-manager/protocol/pure/v1/engine/execution/V1_ExecuteInput.ts +2 -5
  30. package/src/index.ts +1 -0
@@ -19,6 +19,7 @@ import type { PackageableElement } from '../../../graph/metamodel/pure/packageab
19
19
  import type { V1_PackageableElement } from './v1/model/packageableElements/V1_PackageableElement.js';
20
20
  import type { V1_ElementBuilder } from './v1/transformation/pureGraph/to/V1_ElementBuilder.js';
21
21
  import type { V1_PureModelContextData } from './v1/model/context/V1_PureModelContextData.js';
22
+ import type { PureModel } from '../../../graph/PureModel.js';
22
23
  import type { V1_GraphTransformerContext } from './v1/transformation/pureGraph/from/V1_GraphTransformerContext.js';
23
24
  import type { V1_ValueSpecification } from './v1/model/valueSpecification/V1_ValueSpecification.js';
24
25
  import type { V1_GraphBuilderContext } from './v1/transformation/pureGraph/to/V1_GraphBuilderContext.js';
@@ -63,6 +64,21 @@ export type V1_FunctionExpressionBuilder = (
63
64
  processingContext: V1_ProcessingContext,
64
65
  ) => SimpleFunctionExpression | undefined;
65
66
 
67
+ export type V1_ExecutionInputCollector = (
68
+ graph: PureModel,
69
+ protocolGraph: V1_PureModelContextData,
70
+ ) => V1_PackageableElement[];
71
+
72
+ export type V1_MappingModelCoverageAnalysisInputCollector = (
73
+ graph: PureModel,
74
+ protocolGraph: V1_PureModelContextData,
75
+ ) => V1_PackageableElement[];
76
+
77
+ export type V1_MappingModelRuntimeCompatibilityAnalysisInputCollector = (
78
+ graph: PureModel,
79
+ protocolGraph: V1_PureModelContextData,
80
+ ) => V1_PackageableElement[];
81
+
66
82
  export type V1_PropertyExpressionTypeInferrer = (
67
83
  variable: ValueSpecification | undefined,
68
84
  ) => Type | undefined;
@@ -182,6 +198,13 @@ export abstract class PureProtocolProcessorPlugin extends AbstractPlugin {
182
198
  */
183
199
  V1_getExtraFunctionExpressionBuilders?(): V1_FunctionExpressionBuilder[];
184
200
 
201
+ /**
202
+ * Get the list of collectors of graph elements to build execution input.
203
+ *
204
+ * In particular, these collectors are used to produce the minimal graph that is needed for such execution.
205
+ */
206
+ V1_getExtraExecutionInputCollectors?(): V1_ExecutionInputCollector[];
207
+
185
208
  /**
186
209
  * Get the list of type inferrers for property expression.
187
210
  */
@@ -23,6 +23,7 @@ import {
23
23
  guaranteeNonNullable,
24
24
  } from '@finos/legend-shared';
25
25
  import { deserialize, serialize } from 'serializr';
26
+ import type { PureModel } from '../../../../graph/PureModel.js';
26
27
  import {
27
28
  getOwnBinding,
28
29
  getOwnSchemaSet,
@@ -49,8 +50,10 @@ import {
49
50
  type V1_ElementProtocolDeserializer,
50
51
  type V1_ElementProtocolSerializer,
51
52
  type V1_ElementTransformer,
53
+ type V1_ExecutionInputCollector,
52
54
  PureProtocolProcessorPlugin,
53
55
  } from '../PureProtocolProcessorPlugin.js';
56
+ import type { V1_PureModelContextData } from '../v1/model/context/V1_PureModelContextData.js';
54
57
  import type { V1_Connection } from '../v1/model/packageableElements/connection/V1_Connection.js';
55
58
  import { V1_ExternalFormatConnection } from '../v1/model/packageableElements/externalFormat/connection/V1_DSL_ExternalFormat_ExternalFormatConnection.js';
56
59
  import { V1_UrlStream } from '../v1/model/packageableElements/externalFormat/connection/V1_DSL_ExternalFormat_UrlStream.js';
@@ -289,6 +292,18 @@ export class DSL_ExternalFormat_PureProtocolProcessorPlugin
289
292
  ];
290
293
  }
291
294
 
295
+ override V1_getExtraExecutionInputCollectors(): V1_ExecutionInputCollector[] {
296
+ return [
297
+ (
298
+ graph: PureModel,
299
+ protocolGraph: V1_PureModelContextData,
300
+ ): V1_PackageableElement[] =>
301
+ protocolGraph.elements.filter(
302
+ (element) => element instanceof V1_SchemaSet,
303
+ ),
304
+ ];
305
+ }
306
+
292
307
  V1_getExtraConnectionBuilders(): V1_ConnectionBuilder[] {
293
308
  return [
294
309
  (
@@ -37,6 +37,7 @@ import {
37
37
  addUniqueEntry,
38
38
  uuid,
39
39
  deleteEntry,
40
+ uniq,
40
41
  IllegalStateError,
41
42
  filterByType,
42
43
  isString,
@@ -299,6 +300,7 @@ import {
299
300
  } from '../../../GraphData.js';
300
301
  import type { DEPRECATED__MappingTest } from '../../../../graph/metamodel/pure/packageableElements/mapping/DEPRECATED__MappingTest.js';
301
302
  import { DEPRECATED__validate_MappingTest } from '../../../action/validation/DSL_Mapping_ValidationHelper.js';
303
+ import { V1_SERVICE_ELEMENT_PROTOCOL_TYPE } from './transformation/pureProtocol/serializationHelpers/V1_ServiceSerializationHelper.js';
302
304
  import { V1_INTERNAL__UnknownPackageableElement } from './model/packageableElements/V1_INTERNAL__UnknownPackageableElement.js';
303
305
  import type { SourceInformation } from '../../../action/SourceInformation.js';
304
306
  import type { V1_SourceInformation } from './model/V1_SourceInformation.js';
@@ -2403,7 +2405,7 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
2403
2405
  graphData: GraphData,
2404
2406
  ): V1_PureModelContext {
2405
2407
  if (graphData instanceof InMemoryGraphData) {
2406
- return this.getFullGraphModelData(graphData.graph);
2408
+ return this.buildExecutionInputGraphData(graphData.graph);
2407
2409
  } else if (graphData instanceof GraphDataWithOrigin) {
2408
2410
  return this.buildPureModelSDLCPointer(
2409
2411
  graphData.origin,
@@ -2427,7 +2429,7 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
2427
2429
  this.createExecutionInputWithPureModelContext(
2428
2430
  graph.origin
2429
2431
  ? this.buildPureModelSDLCPointer(graph.origin, undefined)
2430
- : this.getFullGraphModelData(graph),
2432
+ : this.buildExecutionInputGraphData(graph),
2431
2433
  mapping,
2432
2434
  lambda,
2433
2435
  runtime,
@@ -2473,6 +2475,52 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
2473
2475
  return executeInput;
2474
2476
  };
2475
2477
 
2478
+ private buildExecutionInputGraphData(
2479
+ graph: PureModel,
2480
+ ): V1_PureModelContextData {
2481
+ /**
2482
+ * NOTE: to lessen network load, we might need to think of a way to only include relevant part of the pure model context data here
2483
+ *
2484
+ * Graph data models can be classified based on dependency hieararchy:
2485
+ * 1. Building blocks: models that all other models depend on: e.g. domain models, connections, etc.
2486
+ * 2. Consumers: models that depends on other models: e.g. mapping, service, etc.
2487
+ * 3. Unrelated: models that depends on nothing and vice versa: e.g. text
2488
+ *
2489
+ * It would be great if we can provide a way to walk the mapping to select only relevant part, but the problem is we cannot really walk the lambda
2490
+ * object to identify relevant classes yet. so the more economical way to to base on the classification above and the knowledge about hierarchy between
2491
+ * models (e.g. service can use mapping, runtime, connection, store, etc.) we can roughly prune the graph model data by group. Following is an example
2492
+ * for mapping used for execution, but this can generalized if we introduce hierarchy/ranking for model type
2493
+ */
2494
+ const graphData = this.getFullGraphModelData(graph);
2495
+ const prunedGraphData = this.prunePureModelContextData(
2496
+ graphData,
2497
+ (element) =>
2498
+ element instanceof V1_Class ||
2499
+ element instanceof V1_Enumeration ||
2500
+ element instanceof V1_Profile ||
2501
+ element instanceof V1_Association ||
2502
+ element instanceof V1_ConcreteFunctionDefinition ||
2503
+ element instanceof V1_FunctionActivator ||
2504
+ element instanceof V1_Measure ||
2505
+ element instanceof V1_Store ||
2506
+ element instanceof V1_PackageableConnection ||
2507
+ element instanceof V1_PackageableRuntime ||
2508
+ element instanceof V1_Mapping,
2509
+ undefined,
2510
+ );
2511
+ const extraExecutionElements = this.pluginManager
2512
+ .getPureProtocolProcessorPlugins()
2513
+ .flatMap(
2514
+ (element) => element.V1_getExtraExecutionInputCollectors?.() ?? [],
2515
+ )
2516
+ .flatMap((getter) => getter(graph, graphData));
2517
+ prunedGraphData.elements = uniq([
2518
+ ...prunedGraphData.elements,
2519
+ ...extraExecutionElements,
2520
+ ]);
2521
+ return prunedGraphData;
2522
+ }
2523
+
2476
2524
  async runQuery(
2477
2525
  lambda: RawLambda,
2478
2526
  mapping: Mapping,
@@ -2525,7 +2573,7 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
2525
2573
  const stopWatch = new StopWatch();
2526
2574
  const pureModelContext = graph.origin
2527
2575
  ? this.buildPureModelSDLCPointer(graph.origin, undefined)
2528
- : this.getFullGraphModelData(graph);
2576
+ : this.buildExecutionInputGraphData(graph);
2529
2577
  stopWatch.record(GRAPH_MANAGER_EVENT.V1_ENGINE_OPERATION_INPUT__SUCCESS);
2530
2578
  await Promise.all(
2531
2579
  tests.map((t) =>
@@ -2670,7 +2718,7 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
2670
2718
  this.createExecutionInputWithPureModelContext(
2671
2719
  graph.origin
2672
2720
  ? this.buildPureModelSDLCPointer(graph.origin, undefined)
2673
- : this.getFullGraphModelData(graph),
2721
+ : this.buildExecutionInputGraphData(graph),
2674
2722
  mapping,
2675
2723
  lambda,
2676
2724
  runtime,
@@ -2832,7 +2880,7 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
2832
2880
  input.mapping = mapping.path;
2833
2881
  input.model = graph.origin
2834
2882
  ? this.buildPureModelSDLCPointer(graph.origin, undefined)
2835
- : this.getFullGraphModelData(graph);
2883
+ : this.buildExecutionInputGraphData(graph);
2836
2884
  return V1_buildModelCoverageAnalysisResult(
2837
2885
  await this.engine.analyzeMappingModelCoverage(input),
2838
2886
  mapping,
@@ -3094,10 +3142,8 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
3094
3142
  );
3095
3143
  switch (executionMode) {
3096
3144
  case ServiceExecutionMode.FULL_INTERACTIVE: {
3097
- const data = this.TEMPORARY__prepareGraphDataForServiceRegistration(
3098
- this.getFullGraphModelData(graph),
3099
- this.elementToProtocol<V1_Service>(service),
3100
- );
3145
+ const data = this.createServiceRegistrationInputGraphData(graph);
3146
+ data.elements.push(this.elementToProtocol<V1_Service>(service));
3101
3147
  data.origin = new V1_PureModelContextPointer(protocol);
3102
3148
  input = data;
3103
3149
  break;
@@ -3326,25 +3372,28 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
3326
3372
  );
3327
3373
  }
3328
3374
 
3329
- // NOTE: This is somewhat hacky: service registration the input expects only the first service in the graph data
3330
- // to be the service used for registration.
3331
- // TODO: the service registration API should be modified to accept service as a parameter outside the model
3332
- private TEMPORARY__prepareGraphDataForServiceRegistration = (
3375
+ // NOTE: We almost should never be poking into dependency entities. However for service registration the input
3376
+ // expects only one service in the graph data. Perhaps, the service registration API should be modified to accept
3377
+ // service as a parameter outside the model
3378
+ private pruneServicesFromGraphForRegistration = (
3333
3379
  graphData: V1_PureModelContextData,
3334
- service: V1_Service,
3335
- ): V1_PureModelContextData => {
3336
- graphData.elements = graphData.elements.filter(
3337
- (element) => element.path !== service.path,
3380
+ ): V1_PureModelContextData =>
3381
+ this.prunePureModelContextData(
3382
+ graphData,
3383
+ (element: V1_PackageableElement) => !(element instanceof V1_Service),
3384
+ (entity: Entity) => {
3385
+ const content = entity.content as { _type: string };
3386
+ return content._type !== V1_SERVICE_ELEMENT_PROTOCOL_TYPE;
3387
+ },
3338
3388
  );
3339
- // insert the service as the first element so it gets indexed first
3340
- graphData.elements.unshift(service);
3341
- if (graphData.INTERNAL__rawDependencyEntities) {
3342
- graphData.INTERNAL__rawDependencyEntities =
3343
- graphData.INTERNAL__rawDependencyEntities.filter(
3344
- (entity) => entity.path !== service.path,
3345
- );
3346
- }
3347
- return graphData;
3389
+
3390
+ private createServiceRegistrationInputGraphData = (
3391
+ graph: PureModel,
3392
+ ): V1_PureModelContextData => {
3393
+ const graphData = this.getFullGraphModelData(graph);
3394
+ const prunedGraphData =
3395
+ this.pruneServicesFromGraphForRegistration(graphData);
3396
+ return prunedGraphData;
3348
3397
  };
3349
3398
 
3350
3399
  private createBulkServiceRegistrationInput = (
@@ -3354,13 +3403,12 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
3354
3403
  const graphData = this.getFullGraphModelData(graph);
3355
3404
  const results: ServiceRegistrationInput[] = [];
3356
3405
  services.forEach((service) => {
3357
- results.push({
3358
- service: service,
3359
- context: this.TEMPORARY__prepareGraphDataForServiceRegistration(
3360
- graphData,
3361
- this.elementToProtocol<V1_Service>(service),
3362
- ),
3363
- });
3406
+ const prunedGraphData =
3407
+ this.pruneServicesFromGraphForRegistration(graphData);
3408
+ prunedGraphData.elements.push(
3409
+ this.elementToProtocol<V1_Service>(service),
3410
+ );
3411
+ results.push({ service: service, context: prunedGraphData });
3364
3412
  });
3365
3413
  return results;
3366
3414
  };
@@ -3431,6 +3479,22 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
3431
3479
  return entity;
3432
3480
  };
3433
3481
 
3482
+ private prunePureModelContextData = (
3483
+ data: V1_PureModelContextData,
3484
+ elementFilter?: (val: V1_PackageableElement) => boolean,
3485
+ entityFilter?: (entity: Entity) => boolean,
3486
+ ): V1_PureModelContextData => {
3487
+ const prunedGraphData = new V1_PureModelContextData();
3488
+ prunedGraphData.elements = data.elements.filter((element) =>
3489
+ elementFilter ? elementFilter(element) : true,
3490
+ );
3491
+ prunedGraphData.INTERNAL__rawDependencyEntities =
3492
+ data.INTERNAL__rawDependencyEntities?.filter((entity) =>
3493
+ entityFilter ? entityFilter(entity) : true,
3494
+ );
3495
+ return prunedGraphData;
3496
+ };
3497
+
3434
3498
  private buildPureModelSDLCPointer(
3435
3499
  origin: GraphDataOrigin,
3436
3500
  clientVersion: string | undefined,
@@ -38,10 +38,7 @@ import {
38
38
  import type { V1_ParameterValue } from '../../model/packageableElements/service/V1_ParameterValue.js';
39
39
  import { V1_parameterValueModelSchema } from '../../transformation/pureProtocol/serializationHelpers/V1_ServiceSerializationHelper.js';
40
40
  import type { V1_PureModelContext } from '../../model/context/V1_PureModelContext.js';
41
- import {
42
- V1_pureModelContextDataPropSchema,
43
- V1_pureModelContextPropSchema,
44
- } from '../../transformation/pureProtocol/V1_PureProtocolSerialization.js';
41
+ import { V1_pureModelContextPropSchema } from '../../transformation/pureProtocol/V1_PureProtocolSerialization.js';
45
42
 
46
43
  export class V1_ExecuteInput {
47
44
  clientVersion: string | undefined;
@@ -82,7 +79,7 @@ export class V1_TestDataGenerationExecutionInput extends V1_ExecuteInput {
82
79
  clientVersion: optional(primitive()),
83
80
  function: usingModelSchema(V1_rawLambdaModelSchema),
84
81
  mapping: primitive(),
85
- model: V1_pureModelContextDataPropSchema,
82
+ model: V1_pureModelContextPropSchema,
86
83
  runtime: custom(
87
84
  (val) => V1_serializeRuntime(val),
88
85
  () => SKIP,
package/src/index.ts CHANGED
@@ -172,6 +172,7 @@ export * from './graph-manager/helpers/ValueSpecificationGraphManagerHelper.js';
172
172
 
173
173
  export {
174
174
  DependencyManager,
175
+ generateDependencyRootPackageName,
175
176
  extractDependencyGACoordinateFromRootPackageName,
176
177
  } from './graph/DependencyManager.js';
177
178
  export { BasicModel } from './graph/BasicModel.js';