@query-graph/core 1.1.0 → 1.1.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.
package/README.md CHANGED
@@ -716,3 +716,62 @@ relation `many` для него допустим. Для пагинации вл
716
716
 
717
717
  Полный пример графа, отображения, операции, сгенерированного SQL и замера
718
718
  производительности компиляции находится в `benchmark/bench.ts`.
719
+
720
+ ## Batch-связи и двухфазное выполнение
721
+
722
+ Поля из отдельного запроса подключаются без изменения обычного relational-графа:
723
+
724
+ ```ts
725
+ const childrenQuery = batchQuery({
726
+ graph: childrenGraph,
727
+ key: {
728
+ path: 'parentId',
729
+ parameter: parentIds,
730
+ },
731
+ })
732
+
733
+ const children = batchRelation({
734
+ name: 'children',
735
+ from: 'id',
736
+ query: childrenQuery,
737
+ cardinality: 'many',
738
+ })
739
+
740
+ const graph = composeGraph({ root: rootGraph, relations: [children] })
741
+ const plan = graph.compileOraclePlan({
742
+ select: ['id', 'children.id'],
743
+ parameters: {},
744
+ limit: 20,
745
+ })
746
+ ```
747
+
748
+ `batchQuery` принадлежит child-модулю и один раз закрепляет его graph,
749
+ projection path ключа и list-параметр. Поэтому разные root-графы могут
750
+ переиспользовать query, не повторяя внутренний контракт child-запроса.
751
+
752
+ `composeGraph` оставляет в JavaScript только декларативный фасад. Проверка
753
+ совместимости ключей и параметров, разделение operation на root и batch-шаги и
754
+ компиляция SQL выполняются в Rust. `compileOraclePlan` или
755
+ `compileSqlServerPlan` сразу компилирует только `plan.root`; child SQL создаётся
756
+ при вызове `compileBatch`. Plan сохраняет выбранные dialect и version, поэтому
757
+ отложенный statement компилируется с теми же настройками, что и root.
758
+
759
+ Для подготовки child bindings каждый шаг в `plan.batches` также содержит имя
760
+ ключевого параметра `keyParameter` и снимок статических `parameters`. Executor
761
+ объединяет их с `{ [batch.keyParameter]: keys }` и сопоставляет полученные значения
762
+ с возвращёнными `statement.bindings`.
763
+
764
+ Executor потребителя выполняет `plan.root`, собирает уникальные ненулевые
765
+ значения `parentKey` из `plan.batches`, вызывает
766
+ `plan.compileBatch('children', parentIds)`, выполняет child statement и
767
+ связывает строки по `childKey`. `cardinality: 'one'` означает объект или `null`,
768
+ а `many` — массив. Query-graph не подключается к БД, не дедуплицирует ключи, не
769
+ выполняет statements и не гидратирует результат; при пустом наборе ключей
770
+ executor должен пропустить child-запрос.
771
+
772
+ Ordering, offset и limit корневой operation применяются только к `plan.root`.
773
+ Batch-связь может задать собственный `ordering`, но child pagination не
774
+ добавляется. Batch-поля выбираются только явно (`children.id`); без prefixed
775
+ path соответствующего шага в `plan.batches` нет. Флаги injection в metadata
776
+ показывают executor, какие ключи были добавлены исключительно для связывания и
777
+ не должны попасть в публичный результат.
package/composition.js ADDED
@@ -0,0 +1,126 @@
1
+ 'use strict'
2
+
3
+ const BATCH_QUERY_KEYS = new Set(['graph', 'key'])
4
+ const BATCH_QUERY_KEY_KEYS = new Set(['path', 'parameter'])
5
+ const BATCH_RELATION_KEYS = new Set(['name', 'from', 'query', 'cardinality', 'parameters', 'ordering'])
6
+ const COMPOSE_KEYS = new Set(['root', 'relations'])
7
+ const batchQueryBrand = Symbol('BatchQuery')
8
+ const batchBrand = Symbol('BatchRelation')
9
+
10
+ function configurationOf(factory, value, allowedKeys) {
11
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
12
+ throw new TypeError(`${factory} expects a configuration object`)
13
+ }
14
+
15
+ const unknownKeys = Reflect.ownKeys(value).filter((key) => typeof key !== 'string' || !allowedKeys.has(key))
16
+ if (unknownKeys.length > 0) {
17
+ const label = unknownKeys.length === 1 ? 'field' : 'fields'
18
+ const keys = unknownKeys.map((key) => JSON.stringify(String(key))).join(', ')
19
+ throw new TypeError(`${factory} received unknown configuration ${label} ${keys}`)
20
+ }
21
+
22
+ return value
23
+ }
24
+
25
+ function nonEmptyString(value, label) {
26
+ if (typeof value !== 'string' || value.trim() === '') {
27
+ throw new TypeError(`${label} must be a non-empty string`)
28
+ }
29
+ return value
30
+ }
31
+
32
+ function relationalGraph(value, label) {
33
+ if (value === null || typeof value !== 'object' || typeof value.compose !== 'function') {
34
+ throw new TypeError(`${label} must be a RelationalQueryGraph`)
35
+ }
36
+ return value
37
+ }
38
+
39
+ function batchQueryOf(value, label) {
40
+ if (value === null || typeof value !== 'object' || value[batchQueryBrand] !== true) {
41
+ throw new TypeError(`${label} must be created by batchQuery`)
42
+ }
43
+ return value
44
+ }
45
+
46
+ function batchQuery(value) {
47
+ const configuration = configurationOf('batchQuery', value, BATCH_QUERY_KEYS)
48
+ const graph = relationalGraph(configuration.graph, 'batchQuery.graph')
49
+ const keyConfiguration = configurationOf('batchQuery.key', configuration.key, BATCH_QUERY_KEY_KEYS)
50
+ const path = nonEmptyString(keyConfiguration.path, 'batchQuery.key.path')
51
+ const parameter = nonEmptyString(
52
+ typeof keyConfiguration.parameter === 'string' ? keyConfiguration.parameter : keyConfiguration.parameter?.name,
53
+ 'batchQuery.key.parameter',
54
+ )
55
+
56
+ return Object.freeze({
57
+ graph,
58
+ key: Object.freeze({
59
+ path,
60
+ parameter,
61
+ }),
62
+ [batchQueryBrand]: true,
63
+ })
64
+ }
65
+
66
+ function batchRelation(value) {
67
+ const configuration = configurationOf('batchRelation', value, BATCH_RELATION_KEYS)
68
+ const name = nonEmptyString(configuration.name, 'batchRelation.name')
69
+ if (name.includes('.')) {
70
+ throw new TypeError('batchRelation.name must be a single projection path segment')
71
+ }
72
+
73
+ const from = nonEmptyString(configuration.from, 'batchRelation.from')
74
+ const query = batchQueryOf(configuration.query, 'batchRelation.query')
75
+
76
+ if (configuration.cardinality !== 'one' && configuration.cardinality !== 'many') {
77
+ throw new TypeError("batchRelation.cardinality must be 'one' or 'many'")
78
+ }
79
+ if (
80
+ configuration.parameters !== undefined &&
81
+ (configuration.parameters === null ||
82
+ typeof configuration.parameters !== 'object' ||
83
+ Array.isArray(configuration.parameters))
84
+ ) {
85
+ throw new TypeError('batchRelation.parameters must be an object')
86
+ }
87
+ if (configuration.ordering !== undefined) {
88
+ nonEmptyString(configuration.ordering, 'batchRelation.ordering')
89
+ }
90
+
91
+ return Object.freeze({
92
+ name,
93
+ from,
94
+ query,
95
+ cardinality: configuration.cardinality,
96
+ parameters: Object.freeze({ ...configuration.parameters }),
97
+ ...(configuration.ordering === undefined ? {} : { ordering: configuration.ordering }),
98
+ [batchBrand]: true,
99
+ })
100
+ }
101
+
102
+ function composeGraph(value) {
103
+ const configuration = configurationOf('composeGraph', value, COMPOSE_KEYS)
104
+ const root = relationalGraph(configuration.root, 'composeGraph.root')
105
+ if (!Array.isArray(configuration.relations)) {
106
+ throw new TypeError('composeGraph.relations must be an array')
107
+ }
108
+
109
+ return configuration.relations.reduce((graph, relation, index) => {
110
+ if (relation?.[batchBrand] !== true) {
111
+ throw new TypeError(`composeGraph.relations[${index}] must be created by batchRelation`)
112
+ }
113
+
114
+ return graph.withBatchRelation(relation.query.graph, {
115
+ name: relation.name,
116
+ from: relation.from,
117
+ to: relation.query.key.path,
118
+ parameter: relation.query.key.parameter,
119
+ cardinality: relation.cardinality,
120
+ parameters: relation.parameters,
121
+ ...(relation.ordering === undefined ? {} : { ordering: relation.ordering }),
122
+ })
123
+ }, root.compose())
124
+ }
125
+
126
+ module.exports = { batchQuery, batchRelation, composeGraph }
package/definition.js CHANGED
@@ -102,6 +102,9 @@ exports.relation = relation
102
102
  exports.constraint = constraint
103
103
  exports.ordering = objectDsl.ordering
104
104
  exports.project = project
105
+ exports.batchQuery = objectDsl.batchQuery
106
+ exports.batchRelation = objectDsl.batchRelation
107
+ exports.composeGraph = objectDsl.composeGraph
105
108
  exports.dimension = dimension
106
109
  exports.measure = measure
107
110
  exports.asc = objectDsl.asc
package/dsl.d.ts CHANGED
@@ -512,6 +512,278 @@ export interface RelationalQueryGraph<Definition extends GraphDefinitionInput =
512
512
  ): import('./index.js').CompiledSqlStatement
513
513
  }
514
514
 
515
+ export type BatchCardinality = RelationCardinality
516
+
517
+ export interface BatchRelationWire {
518
+ name: string
519
+ from: string
520
+ to: string
521
+ parameter: string
522
+ cardinality: BatchCardinality
523
+ parameters?: Record<string, unknown>
524
+ ordering?: string
525
+ }
526
+
527
+ type ListDefinitionParameter<Definition extends GraphDefinitionInput> =
528
+ DefinitionParameter<Definition> extends infer Parameter extends ParameterDefinition
529
+ ? Parameter extends { shape: 'list' }
530
+ ? Parameter
531
+ : never
532
+ : never
533
+
534
+ type ListParameterReference<Definition extends GraphDefinitionInput> =
535
+ | ListDefinitionParameter<Definition>
536
+ | ListDefinitionParameter<Definition>['name']
537
+
538
+ type ParameterReferenceName<Reference> = Reference extends { name: infer Name extends string }
539
+ ? Name
540
+ : Reference extends string
541
+ ? Reference
542
+ : never
543
+
544
+ type ResolveListParameter<Definition extends GraphDefinitionInput, Reference> = Extract<
545
+ ListDefinitionParameter<Definition>,
546
+ { name: ParameterReferenceName<Reference> }
547
+ >
548
+
549
+ type BatchStaticParameterCandidate<
550
+ Parameter extends ParameterDefinition,
551
+ KeyName extends string,
552
+ > = Parameter extends ParameterDefinition ? (Parameter['name'] extends KeyName ? never : Parameter) : never
553
+
554
+ type BatchStaticParameter<
555
+ Definition extends GraphDefinitionInput,
556
+ KeyName extends string,
557
+ > = BatchStaticParameterCandidate<DefinitionParameter<Definition>, KeyName>
558
+
559
+ type BatchStaticParameters<Definition extends GraphDefinitionInput, KeyName extends string> = {
560
+ [Parameter in RequiredParameter<
561
+ BatchStaticParameter<Definition, KeyName>
562
+ > as Parameter['name']]-?: ParameterValue<Parameter>
563
+ } & {
564
+ [Parameter in OptionalParameter<
565
+ BatchStaticParameter<Definition, KeyName>
566
+ > as Parameter['name']]?: ParameterValue<Parameter>
567
+ }
568
+
569
+ type BatchStaticParameterInput<Definition extends GraphDefinitionInput, KeyName extends string> = [
570
+ BatchStaticParameter<Definition, KeyName>,
571
+ ] extends [never]
572
+ ? { parameters?: never }
573
+ : [RequiredParameter<BatchStaticParameter<Definition, KeyName>>] extends [never]
574
+ ? { parameters?: BatchStaticParameters<Definition, KeyName> }
575
+ : { parameters: BatchStaticParameters<Definition, KeyName> }
576
+
577
+ declare const batchQueryType: unique symbol
578
+
579
+ export interface BatchQuery<
580
+ Child extends RelationalQueryGraph = RelationalQueryGraph,
581
+ KeyPath extends string = string,
582
+ KeyParameter extends ParameterDefinition & { shape: 'list' } = ListParameterRef,
583
+ > {
584
+ readonly graph: Child
585
+ readonly key: {
586
+ readonly path: KeyPath
587
+ readonly parameter: KeyParameter['name']
588
+ }
589
+ readonly [batchQueryType]?: KeyParameter
590
+ }
591
+
592
+ export type BatchQueryConfiguration<
593
+ Child extends RelationalQueryGraph,
594
+ KeyPath extends DefinitionProjectionPath<DefinitionOf<Child>>,
595
+ ParameterReference extends ListParameterReference<DefinitionOf<Child>>,
596
+ > = {
597
+ graph: Child
598
+ key: {
599
+ path: KeyPath
600
+ parameter: ParameterReference
601
+ }
602
+ }
603
+
604
+ type CompatibleBatchQueryConfiguration<
605
+ Child extends RelationalQueryGraph,
606
+ KeyPath extends DefinitionProjectionPath<DefinitionOf<Child>>,
607
+ KeyParameter extends ParameterDefinition & { shape: 'list' },
608
+ > =
609
+ EqualScalarType<ProjectionScalarTypeAtPath<DefinitionOf<Child>, KeyPath>, KeyParameter['scalarType']> extends true
610
+ ? unknown
611
+ : never
612
+
613
+ export function batchQuery<
614
+ const Child extends RelationalQueryGraph,
615
+ const KeyPath extends DefinitionProjectionPath<DefinitionOf<Child>>,
616
+ const ParameterReference extends ListParameterReference<DefinitionOf<Child>>,
617
+ >(
618
+ configuration: BatchQueryConfiguration<Child, KeyPath, ParameterReference> &
619
+ CompatibleBatchQueryConfiguration<
620
+ Child,
621
+ KeyPath,
622
+ ResolveListParameter<DefinitionOf<Child>, NoInfer<ParameterReference>>
623
+ >,
624
+ ): BatchQuery<Child, KeyPath, ResolveListParameter<DefinitionOf<Child>, ParameterReference>>
625
+
626
+ type BatchQueryGraph<Query extends BatchQuery> =
627
+ Query extends BatchQuery<infer Child, infer _KeyPath, infer _KeyParameter> ? Child : never
628
+
629
+ type BatchQueryKeyPath<Query extends BatchQuery> =
630
+ Query extends BatchQuery<infer _Child, infer KeyPath, infer _KeyParameter> ? KeyPath : never
631
+
632
+ type BatchQueryKeyParameter<Query extends BatchQuery> =
633
+ Query extends BatchQuery<infer _Child, infer _KeyPath, infer KeyParameter> ? KeyParameter : never
634
+
635
+ declare const batchRelationType: unique symbol
636
+
637
+ export interface BatchRelation<
638
+ Name extends string = string,
639
+ Query extends BatchQuery = BatchQuery,
640
+ From extends string = string,
641
+ Cardinality extends BatchCardinality = BatchCardinality,
642
+ > {
643
+ readonly name: Name
644
+ readonly from: From
645
+ readonly query: Query
646
+ readonly cardinality: Cardinality
647
+ readonly parameters: BatchStaticParameters<
648
+ DefinitionOf<BatchQueryGraph<Query>>,
649
+ BatchQueryKeyParameter<Query>['name']
650
+ >
651
+ readonly ordering?: DefinitionOrderingName<DefinitionOf<BatchQueryGraph<Query>>>
652
+ readonly [batchRelationType]?: Query
653
+ }
654
+
655
+ export type BatchRelationConfiguration<
656
+ Name extends string,
657
+ Query extends BatchQuery,
658
+ From extends string,
659
+ Cardinality extends BatchCardinality,
660
+ > = {
661
+ name: Name
662
+ from: From
663
+ query: Query
664
+ cardinality: Cardinality
665
+ ordering?: DefinitionOrderingName<DefinitionOf<BatchQueryGraph<Query>>>
666
+ } & BatchStaticParameterInput<DefinitionOf<BatchQueryGraph<Query>>, BatchQueryKeyParameter<Query>['name']>
667
+
668
+ export function batchRelation<
669
+ const Name extends string,
670
+ const Query extends BatchQuery,
671
+ const From extends string,
672
+ const Cardinality extends BatchCardinality,
673
+ >(
674
+ configuration: BatchRelationConfiguration<Name, Query, From, Cardinality>,
675
+ ): BatchRelation<Name, Query, From, Cardinality>
676
+
677
+ type ProjectionScalarTypeAtPath<Definition extends GraphDefinitionInput, Path extends string> =
678
+ ProjectionFieldByPath<DefinitionProjectionField<Definition>, Path> extends infer Field
679
+ ? Field extends ProjectionTypeMetadata<infer _Path, infer Type, infer _Nullability, infer _SelectedByDefault>
680
+ ? Type
681
+ : Field extends ProjectionFieldDefinition<infer _Path, infer Type>
682
+ ? Type
683
+ : never
684
+ : never
685
+
686
+ type EqualScalarType<Left, Right> = [Left] extends [Right] ? ([Right] extends [Left] ? true : false) : false
687
+
688
+ type CompatibleBatchRelation<Root extends RelationalQueryGraph, Relation extends BatchRelation> =
689
+ Relation extends BatchRelation<infer Name, infer Query, infer From, infer _Cardinality>
690
+ ? From extends DefinitionProjectionPath<DefinitionOf<Root>>
691
+ ? Extract<DefinitionProjectionPath<DefinitionOf<Root>>, Name | `${Name}.${string}`> extends never
692
+ ? EqualScalarType<
693
+ ProjectionScalarTypeAtPath<DefinitionOf<Root>, From>,
694
+ ProjectionScalarTypeAtPath<DefinitionOf<BatchQueryGraph<Query>>, BatchQueryKeyPath<Query>>
695
+ > extends true
696
+ ? EqualScalarType<
697
+ ProjectionScalarTypeAtPath<DefinitionOf<BatchQueryGraph<Query>>, BatchQueryKeyPath<Query>>,
698
+ BatchQueryKeyParameter<Query>['scalarType']
699
+ > extends true
700
+ ? Relation
701
+ : never
702
+ : never
703
+ : never
704
+ : never
705
+ : never
706
+
707
+ type CompatibleBatchRelations<Root extends RelationalQueryGraph, Relations extends readonly BatchRelation[]> = {
708
+ readonly [Index in keyof Relations]: Relations[Index] extends BatchRelation
709
+ ? CompatibleBatchRelation<Root, Relations[Index]>
710
+ : never
711
+ }
712
+
713
+ type RelationName<Relations extends readonly BatchRelation[]> = Relations[number]['name']
714
+ type ChildPathsForRelation<Relation extends BatchRelation> = Relation extends BatchRelation
715
+ ? `${Relation['name']}.${DefinitionProjectionPath<DefinitionOf<BatchQueryGraph<Relation['query']>>>}`
716
+ : never
717
+ type ChildPaths<Relations extends readonly BatchRelation[]> = ChildPathsForRelation<Relations[number]>
718
+
719
+ export type ComposedSelection<Root extends RelationalQueryGraph, Relations extends readonly BatchRelation[]> =
720
+ | DefinitionProjectionPath<DefinitionOf<Root>>
721
+ | ChildPaths<Relations>
722
+
723
+ export interface BatchPlanMetadata<Relation extends BatchRelation = BatchRelation> {
724
+ name: Relation['name']
725
+ parentKey: Relation['from']
726
+ childKey: BatchQueryKeyPath<Relation['query']>
727
+ keyParameter: BatchQueryKeyParameter<Relation['query']>['name']
728
+ parameters: Readonly<Relation['parameters']>
729
+ cardinality: Relation['cardinality']
730
+ parentKeyInjected: boolean
731
+ childKeyInjected: boolean
732
+ }
733
+
734
+ type BatchRelationNamed<Relation extends BatchRelation, Name extends string> = Relation extends BatchRelation
735
+ ? Relation['name'] extends Name
736
+ ? Relation
737
+ : never
738
+ : never
739
+
740
+ type BatchRelationByName<Relations extends readonly BatchRelation[], Name extends string> = BatchRelationNamed<
741
+ Relations[number],
742
+ Name
743
+ >
744
+
745
+ type BatchKeyValue<Relation extends BatchRelation> = ScalarParameterValue<
746
+ BatchQueryKeyParameter<Relation['query']>['scalarType']
747
+ >
748
+
749
+ export interface CompiledQueryPlan<Relations extends readonly BatchRelation[] = readonly BatchRelation[]> {
750
+ readonly root: import('./index.js').CompiledSqlStatement
751
+ readonly batches: readonly BatchPlanMetadata<Relations[number]>[]
752
+ compileBatch<const Name extends RelationName<Relations>>(
753
+ name: Name,
754
+ keys: readonly BatchKeyValue<BatchRelationByName<Relations, Name>>[],
755
+ ): import('./index.js').CompiledSqlStatement
756
+ }
757
+
758
+ export type ComposedQueryOperation<
759
+ Root extends RelationalQueryGraph,
760
+ Relations extends readonly BatchRelation[],
761
+ > = QueryOperationBase<ComposedSelection<Root, Relations>, DefinitionOrderingName<DefinitionOf<Root>>> &
762
+ OperationParameterInput<DefinitionOf<Root>>
763
+
764
+ export interface ComposedQueryGraph<
765
+ Root extends RelationalQueryGraph = RelationalQueryGraph,
766
+ Relations extends readonly BatchRelation[] = readonly BatchRelation[],
767
+ > {
768
+ readonly name: string
769
+ compileOraclePlan(
770
+ operation: ComposedQueryOperation<Root, Relations>,
771
+ options?: OracleCompileOptions,
772
+ ): CompiledQueryPlan<Relations>
773
+ compileSqlServerPlan(
774
+ operation: ComposedQueryOperation<Root, Relations>,
775
+ options?: SqlServerCompileOptions,
776
+ ): CompiledQueryPlan<Relations>
777
+ }
778
+
779
+ export function composeGraph<
780
+ const Root extends RelationalQueryGraph,
781
+ const Relations extends readonly BatchRelation[],
782
+ >(configuration: {
783
+ root: Root
784
+ relations: Relations & CompatibleBatchRelations<Root, Relations>
785
+ }): ComposedQueryGraph<Root, Relations>
786
+
515
787
  export interface ScalarOutputTypeMap {
516
788
  boolean: unknown
517
789
  int32: unknown
@@ -753,14 +1025,60 @@ type BuildProjectionResult<Entry> = [Entry] extends [never]
753
1025
  }
754
1026
 
755
1027
  export type ResultOf<
756
- Subject extends GraphDefinitionInput | QueryGraph | RelationalQueryGraph,
1028
+ Subject extends GraphDefinitionInput | QueryGraph | RelationalQueryGraph | ComposedQueryGraph,
757
1029
  Operation = undefined,
758
1030
  TypeMap extends ScalarOutputTypeMap = DefaultScalarOutputTypeMap,
759
1031
  > =
760
- DefinitionOf<Subject> extends infer Definition extends GraphDefinitionInput
761
- ? BuildProjectionResult<ProjectionEntry<Definition, SelectedProjectionField<Definition, Operation>, TypeMap>>
1032
+ Subject extends ComposedQueryGraph<infer Root, infer Relations>
1033
+ ? ComposedResult<Root, Relations, Operation, TypeMap>
1034
+ : DefinitionOf<
1035
+ Extract<Subject, GraphDefinitionInput | QueryGraph | RelationalQueryGraph>
1036
+ > extends infer Definition extends GraphDefinitionInput
1037
+ ? BuildProjectionResult<ProjectionEntry<Definition, SelectedProjectionField<Definition, Operation>, TypeMap>>
1038
+ : never
1039
+
1040
+ type SelectedPaths<Operation> = Operation extends { select: readonly (infer Path extends string)[] } ? Path : never
1041
+
1042
+ type RootOperation<Operation, Relations extends readonly BatchRelation[]> = Operation extends {
1043
+ select: readonly string[]
1044
+ }
1045
+ ? { select: readonly Exclude<SelectedPaths<Operation>, ChildPaths<Relations>>[] }
1046
+ : undefined
1047
+
1048
+ type SelectedChildPath<Operation, Name extends string> =
1049
+ Extract<SelectedPaths<Operation>, `${Name}.${string}`> extends `${Name}.${infer Path}` ? Path : never
1050
+
1051
+ type ChildOperation<Operation, Name extends string> = {
1052
+ select: readonly SelectedChildPath<Operation, Name>[]
1053
+ }
1054
+
1055
+ type SelectedRelationCandidate<Relation extends BatchRelation, Operation> = Relation extends BatchRelation
1056
+ ? Extract<SelectedPaths<Operation>, `${Relation['name']}.${string}`> extends never
1057
+ ? never
1058
+ : Relation
1059
+ : never
1060
+
1061
+ type SelectedRelation<Relations extends readonly BatchRelation[], Operation> = SelectedRelationCandidate<
1062
+ Relations[number],
1063
+ Operation
1064
+ >
1065
+
1066
+ type BatchResult<Relation extends BatchRelation, Operation, TypeMap extends ScalarOutputTypeMap> =
1067
+ ResultOf<BatchQueryGraph<Relation['query']>, ChildOperation<Operation, Relation['name']>, TypeMap> extends infer Child
1068
+ ? Relation['cardinality'] extends 'many'
1069
+ ? Child[]
1070
+ : Child | null
762
1071
  : never
763
1072
 
1073
+ type ComposedResult<
1074
+ Root extends RelationalQueryGraph,
1075
+ Relations extends readonly BatchRelation[],
1076
+ Operation,
1077
+ TypeMap extends ScalarOutputTypeMap,
1078
+ > = ResultOf<Root, RootOperation<Operation, Relations>, TypeMap> & {
1079
+ [Relation in SelectedRelation<Relations, Operation> as Relation['name']]: BatchResult<Relation, Operation, TypeMap>
1080
+ }
1081
+
764
1082
  export type SqlServerVersion = '2008' | '2012' | '2016' | '2019' | '2022'
765
1083
  export type OracleVersion = '11g' | '12c' | '19c' | '21c' | '23ai'
766
1084
 
@@ -772,7 +1090,7 @@ export interface OracleCompileOptions {
772
1090
  version?: OracleVersion
773
1091
  }
774
1092
 
775
- export type QueryGraphErrorPhase = 'definition' | 'mapping' | 'operation' | 'sql'
1093
+ export type QueryGraphErrorPhase = 'definition' | 'mapping' | 'composition' | 'operation' | 'sql'
776
1094
 
777
1095
  export interface QueryGraphDiagnostic {
778
1096
  code: string
package/dsl.js CHANGED
@@ -740,3 +740,6 @@ exports.defineGraphModule = defineGraphModule
740
740
  exports.defineGraph = defineGraph
741
741
  exports.defineSummaryGraph = defineSummaryGraph
742
742
  exports.firstBy = firstBy
743
+ exports.batchQuery = require('./composition.js').batchQuery
744
+ exports.batchRelation = require('./composition.js').batchRelation
745
+ exports.composeGraph = require('./composition.js').composeGraph
package/index.d.ts CHANGED
@@ -1,5 +1,24 @@
1
1
  /* auto-generated by NAPI-RS */
2
2
  /* eslint-disable */
3
+ export declare class CompiledQueryPlan {
4
+ get root(): CompiledSqlStatement
5
+ get batches(): Array<CompiledBatchStep>
6
+ compileBatch(name: string, keys: readonly unknown[]): CompiledSqlStatement
7
+ }
8
+
9
+ export declare class ComposedQueryGraph {
10
+ get name(): string
11
+ withBatchRelation(graph: RelationalQueryGraph, relation: import('./dsl.js').BatchRelationWire): ComposedQueryGraph
12
+ compileSqlServerPlan(
13
+ operation: import('./definition.js').QueryOperation,
14
+ options?: import('./definition.js').SqlServerCompileOptions,
15
+ ): CompiledQueryPlan
16
+ compileOraclePlan(
17
+ operation: import('./definition.js').QueryOperation,
18
+ options?: import('./definition.js').OracleCompileOptions,
19
+ ): CompiledQueryPlan
20
+ }
21
+
3
22
  export declare class QueryGraph {
4
23
  get name(): string
5
24
  get root(): string
@@ -15,6 +34,7 @@ export declare class QueryGraph {
15
34
 
16
35
  export declare class RelationalQueryGraph {
17
36
  get name(): string
37
+ compose(): ComposedQueryGraph
18
38
  compileSqlServer(
19
39
  operation: import('./definition.js').QueryOperation,
20
40
  options?: import('./definition.js').SqlServerCompileOptions,
@@ -25,6 +45,17 @@ export declare class RelationalQueryGraph {
25
45
  ): CompiledSqlStatement
26
46
  }
27
47
 
48
+ export interface CompiledBatchStep {
49
+ name: string
50
+ parentKey: string
51
+ childKey: string
52
+ keyParameter: string
53
+ parameters: Readonly<Record<string, unknown>>
54
+ cardinality: import('./dsl.js').BatchCardinality
55
+ parentKeyInjected: boolean
56
+ childKeyInjected: boolean
57
+ }
58
+
28
59
  export interface CompiledSqlColumn {
29
60
  name: string
30
61
  path: string
@@ -58,3 +89,5 @@ export interface SqlBinding {
58
89
  scalarType: import('./definition.js').ScalarType
59
90
  index?: number
60
91
  }
92
+
93
+ export { batchQuery, batchRelation, composeGraph } from './dsl.js'
package/index.js CHANGED
@@ -80,8 +80,8 @@ function requireNative() {
80
80
  try {
81
81
  const binding = require('@query-graph/core-android-arm64')
82
82
  const bindingPackageVersion = require('@query-graph/core-android-arm64/package.json').version
83
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
84
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
83
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
84
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
85
85
  }
86
86
  return binding
87
87
  } catch (e) {
@@ -96,8 +96,8 @@ function requireNative() {
96
96
  try {
97
97
  const binding = require('@query-graph/core-android-arm-eabi')
98
98
  const bindingPackageVersion = require('@query-graph/core-android-arm-eabi/package.json').version
99
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
100
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
99
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
100
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
101
101
  }
102
102
  return binding
103
103
  } catch (e) {
@@ -116,8 +116,8 @@ function requireNative() {
116
116
  try {
117
117
  const binding = require('@query-graph/core-win32-x64-msvc')
118
118
  const bindingPackageVersion = require('@query-graph/core-win32-x64-msvc/package.json').version
119
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
120
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
119
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
120
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
121
121
  }
122
122
  return binding
123
123
  } catch (e) {
@@ -132,8 +132,8 @@ function requireNative() {
132
132
  try {
133
133
  const binding = require('@query-graph/core-win32-ia32-msvc')
134
134
  const bindingPackageVersion = require('@query-graph/core-win32-ia32-msvc/package.json').version
135
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
136
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
135
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
136
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
137
137
  }
138
138
  return binding
139
139
  } catch (e) {
@@ -148,8 +148,8 @@ function requireNative() {
148
148
  try {
149
149
  const binding = require('@query-graph/core-win32-arm64-msvc')
150
150
  const bindingPackageVersion = require('@query-graph/core-win32-arm64-msvc/package.json').version
151
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
152
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
151
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
152
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
153
153
  }
154
154
  return binding
155
155
  } catch (e) {
@@ -167,8 +167,8 @@ function requireNative() {
167
167
  try {
168
168
  const binding = require('@query-graph/core-darwin-universal')
169
169
  const bindingPackageVersion = require('@query-graph/core-darwin-universal/package.json').version
170
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
171
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
170
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
171
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
172
172
  }
173
173
  return binding
174
174
  } catch (e) {
@@ -183,8 +183,8 @@ function requireNative() {
183
183
  try {
184
184
  const binding = require('@query-graph/core-darwin-x64')
185
185
  const bindingPackageVersion = require('@query-graph/core-darwin-x64/package.json').version
186
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
187
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
186
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
187
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
188
188
  }
189
189
  return binding
190
190
  } catch (e) {
@@ -199,8 +199,8 @@ function requireNative() {
199
199
  try {
200
200
  const binding = require('@query-graph/core-darwin-arm64')
201
201
  const bindingPackageVersion = require('@query-graph/core-darwin-arm64/package.json').version
202
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
203
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
202
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
203
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
204
204
  }
205
205
  return binding
206
206
  } catch (e) {
@@ -219,8 +219,8 @@ function requireNative() {
219
219
  try {
220
220
  const binding = require('@query-graph/core-freebsd-x64')
221
221
  const bindingPackageVersion = require('@query-graph/core-freebsd-x64/package.json').version
222
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
223
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
222
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
223
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
224
224
  }
225
225
  return binding
226
226
  } catch (e) {
@@ -235,8 +235,8 @@ function requireNative() {
235
235
  try {
236
236
  const binding = require('@query-graph/core-freebsd-arm64')
237
237
  const bindingPackageVersion = require('@query-graph/core-freebsd-arm64/package.json').version
238
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
239
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
238
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
239
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
240
240
  }
241
241
  return binding
242
242
  } catch (e) {
@@ -256,8 +256,8 @@ function requireNative() {
256
256
  try {
257
257
  const binding = require('@query-graph/core-linux-x64-musl')
258
258
  const bindingPackageVersion = require('@query-graph/core-linux-x64-musl/package.json').version
259
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
260
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
259
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
260
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
261
261
  }
262
262
  return binding
263
263
  } catch (e) {
@@ -272,8 +272,8 @@ function requireNative() {
272
272
  try {
273
273
  const binding = require('@query-graph/core-linux-x64-gnu')
274
274
  const bindingPackageVersion = require('@query-graph/core-linux-x64-gnu/package.json').version
275
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
276
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
275
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
276
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
277
277
  }
278
278
  return binding
279
279
  } catch (e) {
@@ -290,8 +290,8 @@ function requireNative() {
290
290
  try {
291
291
  const binding = require('@query-graph/core-linux-arm64-musl')
292
292
  const bindingPackageVersion = require('@query-graph/core-linux-arm64-musl/package.json').version
293
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
294
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
293
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
294
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
295
295
  }
296
296
  return binding
297
297
  } catch (e) {
@@ -306,8 +306,8 @@ function requireNative() {
306
306
  try {
307
307
  const binding = require('@query-graph/core-linux-arm64-gnu')
308
308
  const bindingPackageVersion = require('@query-graph/core-linux-arm64-gnu/package.json').version
309
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
310
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
309
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
310
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
311
311
  }
312
312
  return binding
313
313
  } catch (e) {
@@ -324,8 +324,8 @@ function requireNative() {
324
324
  try {
325
325
  const binding = require('@query-graph/core-linux-arm-musleabihf')
326
326
  const bindingPackageVersion = require('@query-graph/core-linux-arm-musleabihf/package.json').version
327
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
328
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
327
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
328
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
329
329
  }
330
330
  return binding
331
331
  } catch (e) {
@@ -340,8 +340,8 @@ function requireNative() {
340
340
  try {
341
341
  const binding = require('@query-graph/core-linux-arm-gnueabihf')
342
342
  const bindingPackageVersion = require('@query-graph/core-linux-arm-gnueabihf/package.json').version
343
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
344
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
343
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
344
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
345
345
  }
346
346
  return binding
347
347
  } catch (e) {
@@ -358,8 +358,8 @@ function requireNative() {
358
358
  try {
359
359
  const binding = require('@query-graph/core-linux-loong64-musl')
360
360
  const bindingPackageVersion = require('@query-graph/core-linux-loong64-musl/package.json').version
361
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
362
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
361
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
362
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
363
363
  }
364
364
  return binding
365
365
  } catch (e) {
@@ -374,8 +374,8 @@ function requireNative() {
374
374
  try {
375
375
  const binding = require('@query-graph/core-linux-loong64-gnu')
376
376
  const bindingPackageVersion = require('@query-graph/core-linux-loong64-gnu/package.json').version
377
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
378
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
377
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
378
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
379
379
  }
380
380
  return binding
381
381
  } catch (e) {
@@ -392,8 +392,8 @@ function requireNative() {
392
392
  try {
393
393
  const binding = require('@query-graph/core-linux-riscv64-musl')
394
394
  const bindingPackageVersion = require('@query-graph/core-linux-riscv64-musl/package.json').version
395
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
396
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
395
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
396
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
397
397
  }
398
398
  return binding
399
399
  } catch (e) {
@@ -408,8 +408,8 @@ function requireNative() {
408
408
  try {
409
409
  const binding = require('@query-graph/core-linux-riscv64-gnu')
410
410
  const bindingPackageVersion = require('@query-graph/core-linux-riscv64-gnu/package.json').version
411
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
412
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
411
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
412
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
413
413
  }
414
414
  return binding
415
415
  } catch (e) {
@@ -425,8 +425,8 @@ function requireNative() {
425
425
  try {
426
426
  const binding = require('@query-graph/core-linux-ppc64-gnu')
427
427
  const bindingPackageVersion = require('@query-graph/core-linux-ppc64-gnu/package.json').version
428
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
429
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
428
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
429
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
430
430
  }
431
431
  return binding
432
432
  } catch (e) {
@@ -441,8 +441,8 @@ function requireNative() {
441
441
  try {
442
442
  const binding = require('@query-graph/core-linux-s390x-gnu')
443
443
  const bindingPackageVersion = require('@query-graph/core-linux-s390x-gnu/package.json').version
444
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
445
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
444
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
445
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
446
446
  }
447
447
  return binding
448
448
  } catch (e) {
@@ -461,8 +461,8 @@ function requireNative() {
461
461
  try {
462
462
  const binding = require('@query-graph/core-openharmony-arm64')
463
463
  const bindingPackageVersion = require('@query-graph/core-openharmony-arm64/package.json').version
464
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
465
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
464
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
465
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
466
466
  }
467
467
  return binding
468
468
  } catch (e) {
@@ -477,8 +477,8 @@ function requireNative() {
477
477
  try {
478
478
  const binding = require('@query-graph/core-openharmony-x64')
479
479
  const bindingPackageVersion = require('@query-graph/core-openharmony-x64/package.json').version
480
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
481
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
480
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
481
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
482
482
  }
483
483
  return binding
484
484
  } catch (e) {
@@ -493,8 +493,8 @@ function requireNative() {
493
493
  try {
494
494
  const binding = require('@query-graph/core-openharmony-arm')
495
495
  const bindingPackageVersion = require('@query-graph/core-openharmony-arm/package.json').version
496
- if (bindingPackageVersion !== '1.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
497
- throw new Error(`Native binding package version mismatch, expected 1.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
496
+ if (bindingPackageVersion !== '1.1.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
497
+ throw new Error(`Native binding package version mismatch, expected 1.1.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
498
498
  }
499
499
  return binding
500
500
  } catch (e) {
@@ -557,6 +557,12 @@ if (!nativeBinding) {
557
557
  }
558
558
 
559
559
  module.exports = nativeBinding
560
+ module.exports.CompiledQueryPlan = nativeBinding.CompiledQueryPlan
561
+ module.exports.ComposedQueryGraph = nativeBinding.ComposedQueryGraph
560
562
  module.exports.QueryGraph = nativeBinding.QueryGraph
561
563
  module.exports.RelationalQueryGraph = nativeBinding.RelationalQueryGraph
562
564
  module.exports.registerDefinition = nativeBinding.registerDefinition
565
+
566
+ module.exports.batchQuery = require('./composition.js').batchQuery
567
+ module.exports.batchRelation = require('./composition.js').batchRelation
568
+ module.exports.composeGraph = require('./composition.js').composeGraph
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@query-graph/core",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Native query graph planner and SQL compiler for Node.js",
5
5
  "workspaces": [
6
6
  "packages/*"
@@ -41,6 +41,7 @@
41
41
  "node-addon"
42
42
  ],
43
43
  "files": [
44
+ "composition.js",
44
45
  "definition.d.ts",
45
46
  "definition.js",
46
47
  "dsl.d.ts",
@@ -135,9 +136,9 @@
135
136
  },
136
137
  "packageManager": "yarn@4.13.0",
137
138
  "optionalDependencies": {
138
- "@query-graph/core-win32-x64-msvc": "1.1.0",
139
- "@query-graph/core-darwin-x64": "1.1.0",
140
- "@query-graph/core-linux-x64-gnu": "1.1.0",
141
- "@query-graph/core-darwin-arm64": "1.1.0"
139
+ "@query-graph/core-win32-x64-msvc": "1.1.1",
140
+ "@query-graph/core-darwin-x64": "1.1.1",
141
+ "@query-graph/core-linux-x64-gnu": "1.1.1",
142
+ "@query-graph/core-darwin-arm64": "1.1.1"
142
143
  }
143
144
  }