@powersync/service-core-tests 0.13.2 → 0.15.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 (35) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/test-utils/general-utils.d.ts +9 -3
  3. package/dist/test-utils/general-utils.js +26 -26
  4. package/dist/test-utils/general-utils.js.map +1 -1
  5. package/dist/tests/register-compacting-tests.d.ts +1 -1
  6. package/dist/tests/register-compacting-tests.js +136 -93
  7. package/dist/tests/register-compacting-tests.js.map +1 -1
  8. package/dist/tests/register-data-storage-checkpoint-tests.d.ts +1 -1
  9. package/dist/tests/register-data-storage-checkpoint-tests.js +44 -27
  10. package/dist/tests/register-data-storage-checkpoint-tests.js.map +1 -1
  11. package/dist/tests/register-data-storage-data-tests.d.ts +2 -2
  12. package/dist/tests/register-data-storage-data-tests.js +715 -207
  13. package/dist/tests/register-data-storage-data-tests.js.map +1 -1
  14. package/dist/tests/register-data-storage-parameter-tests.d.ts +1 -1
  15. package/dist/tests/register-data-storage-parameter-tests.js +123 -58
  16. package/dist/tests/register-data-storage-parameter-tests.js.map +1 -1
  17. package/dist/tests/register-parameter-compacting-tests.d.ts +1 -1
  18. package/dist/tests/register-parameter-compacting-tests.js +13 -13
  19. package/dist/tests/register-parameter-compacting-tests.js.map +1 -1
  20. package/dist/tests/register-sync-tests.d.ts +4 -1
  21. package/dist/tests/register-sync-tests.js +63 -34
  22. package/dist/tests/register-sync-tests.js.map +1 -1
  23. package/dist/tests/util.d.ts +6 -1
  24. package/dist/tests/util.js +31 -2
  25. package/dist/tests/util.js.map +1 -1
  26. package/package.json +3 -3
  27. package/src/test-utils/general-utils.ts +42 -28
  28. package/src/tests/register-compacting-tests.ts +153 -103
  29. package/src/tests/register-data-storage-checkpoint-tests.ts +70 -22
  30. package/src/tests/register-data-storage-data-tests.ts +732 -110
  31. package/src/tests/register-data-storage-parameter-tests.ts +168 -59
  32. package/src/tests/register-parameter-compacting-tests.ts +18 -13
  33. package/src/tests/register-sync-tests.ts +71 -35
  34. package/src/tests/util.ts +52 -2
  35. package/tsconfig.tsbuildinfo +1 -1
@@ -5,22 +5,20 @@ import {
5
5
  StreamingSyncCheckpoint,
6
6
  StreamingSyncCheckpointDiff,
7
7
  sync,
8
+ updateSyncRulesFromYaml,
8
9
  utils
9
10
  } from '@powersync/service-core';
10
11
  import { JSONBig } from '@powersync/service-jsonbig';
11
- import { BucketSourceType, RequestParameters } from '@powersync/service-sync-rules';
12
12
  import path from 'path';
13
13
  import * as timers from 'timers/promises';
14
14
  import { fileURLToPath } from 'url';
15
15
  import { expect, test } from 'vitest';
16
16
  import * as test_utils from '../test-utils/test-utils-index.js';
17
- import { METRICS_HELPER } from '../test-utils/test-utils-index.js';
17
+ import { bucketRequest, METRICS_HELPER } from '../test-utils/test-utils-index.js';
18
18
 
19
19
  const __filename = fileURLToPath(import.meta.url);
20
20
  const __dirname = path.dirname(__filename);
21
21
 
22
- const TEST_TABLE = test_utils.makeTestTable('test', ['id']);
23
-
24
22
  const BASIC_SYNC_RULES = `
25
23
  bucket_definitions:
26
24
  mybucket:
@@ -38,7 +36,15 @@ export const SYNC_SNAPSHOT_PATH = path.resolve(__dirname, '../__snapshots/sync.t
38
36
  * });
39
37
  * ```
40
38
  */
41
- export function registerSyncTests(factory: storage.TestStorageFactory) {
39
+ export function registerSyncTests(
40
+ configOrFactory: storage.TestStorageConfig | storage.TestStorageFactory,
41
+ options: { storageVersion?: number; tableIdStrings?: boolean } = {}
42
+ ) {
43
+ const config: storage.TestStorageConfig =
44
+ typeof configOrFactory == 'function'
45
+ ? { factory: configOrFactory, tableIdStrings: options.tableIdStrings ?? true }
46
+ : configOrFactory;
47
+ const factory = config.factory;
42
48
  createCoreAPIMetrics(METRICS_HELPER.metricsEngine);
43
49
  const tracker = new sync.RequestTracker(METRICS_HELPER.metricsEngine);
44
50
  const syncContext = new sync.SyncContext({
@@ -47,16 +53,28 @@ export function registerSyncTests(factory: storage.TestStorageFactory) {
47
53
  maxDataFetchConcurrency: 2
48
54
  });
49
55
 
56
+ const TEST_TABLE = test_utils.makeTestTable('test', ['id'], config);
57
+ const updateSyncRules = (bucketStorageFactory: storage.BucketStorageFactory, updateOptions: { content: string }) => {
58
+ return bucketStorageFactory.updateSyncRules(
59
+ updateSyncRulesFromYaml(updateOptions.content, {
60
+ validate: true,
61
+ storageVersion: options.storageVersion
62
+ })
63
+ );
64
+ };
65
+
50
66
  test('sync global data', async () => {
51
67
  await using f = await factory();
52
68
 
53
- const syncRules = await f.updateSyncRules({
69
+ const syncRules = await updateSyncRules(f, {
54
70
  content: BASIC_SYNC_RULES
55
71
  });
56
72
 
57
73
  const bucketStorage = f.getInstance(syncRules);
58
74
 
59
- const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
75
+ await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
76
+ await batch.markAllSnapshotDone('0/1');
77
+
60
78
  await batch.save({
61
79
  sourceTable: TEST_TABLE,
62
80
  tag: storage.SaveOperationTag.INSERT,
@@ -101,7 +119,7 @@ export function registerSyncTests(factory: storage.TestStorageFactory) {
101
119
  test('sync buckets in order', async () => {
102
120
  await using f = await factory();
103
121
 
104
- const syncRules = await f.updateSyncRules({
122
+ const syncRules = await updateSyncRules(f, {
105
123
  content: `
106
124
  bucket_definitions:
107
125
  b0:
@@ -117,7 +135,8 @@ bucket_definitions:
117
135
 
118
136
  const bucketStorage = f.getInstance(syncRules);
119
137
 
120
- const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
138
+ await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
139
+ await batch.markAllSnapshotDone('0/1');
121
140
  await batch.save({
122
141
  sourceTable: TEST_TABLE,
123
142
  tag: storage.SaveOperationTag.INSERT,
@@ -162,7 +181,7 @@ bucket_definitions:
162
181
  test('sync interrupts low-priority buckets on new checkpoints', async () => {
163
182
  await using f = await factory();
164
183
 
165
- const syncRules = await f.updateSyncRules({
184
+ const syncRules = await updateSyncRules(f, {
166
185
  content: `
167
186
  bucket_definitions:
168
187
  b0:
@@ -179,6 +198,7 @@ bucket_definitions:
179
198
  const bucketStorage = f.getInstance(syncRules);
180
199
 
181
200
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
201
+ await batch.markAllSnapshotDone('0/1');
182
202
  // Initial data: Add one priority row and 10k low-priority rows.
183
203
  await batch.save({
184
204
  sourceTable: TEST_TABLE,
@@ -271,7 +291,7 @@ bucket_definitions:
271
291
  test('sync interruptions with unrelated data', async () => {
272
292
  await using f = await factory();
273
293
 
274
- const syncRules = await f.updateSyncRules({
294
+ const syncRules = await updateSyncRules(f, {
275
295
  content: `
276
296
  bucket_definitions:
277
297
  b0:
@@ -289,6 +309,7 @@ bucket_definitions:
289
309
  const bucketStorage = f.getInstance(syncRules);
290
310
 
291
311
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
312
+ await batch.markAllSnapshotDone('0/1');
292
313
  // Initial data: Add one priority row and 10k low-priority rows.
293
314
  await batch.save({
294
315
  sourceTable: TEST_TABLE,
@@ -409,7 +430,7 @@ bucket_definitions:
409
430
  // then interrupt checkpoint with new data for all buckets
410
431
  // -> data for all buckets should be sent in the new checkpoint
411
432
 
412
- const syncRules = await f.updateSyncRules({
433
+ const syncRules = await updateSyncRules(f, {
413
434
  content: `
414
435
  bucket_definitions:
415
436
  b0a:
@@ -430,6 +451,7 @@ bucket_definitions:
430
451
  const bucketStorage = f.getInstance(syncRules);
431
452
 
432
453
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
454
+ await batch.markAllSnapshotDone('0/1');
433
455
  // Initial data: Add one priority row and 10k low-priority rows.
434
456
  await batch.save({
435
457
  sourceTable: TEST_TABLE,
@@ -553,12 +575,13 @@ bucket_definitions:
553
575
  test('sends checkpoint complete line for empty checkpoint', async () => {
554
576
  await using f = await factory();
555
577
 
556
- const syncRules = await f.updateSyncRules({
578
+ const syncRules = await updateSyncRules(f, {
557
579
  content: BASIC_SYNC_RULES
558
580
  });
559
581
  const bucketStorage = f.getInstance(syncRules);
560
582
 
561
583
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
584
+ await batch.markAllSnapshotDone('0/1');
562
585
  await batch.save({
563
586
  sourceTable: TEST_TABLE,
564
587
  tag: storage.SaveOperationTag.INSERT,
@@ -616,13 +639,14 @@ bucket_definitions:
616
639
  test('sync legacy non-raw data', async () => {
617
640
  const f = await factory();
618
641
 
619
- const syncRules = await f.updateSyncRules({
642
+ const syncRules = await updateSyncRules(f, {
620
643
  content: BASIC_SYNC_RULES
621
644
  });
622
645
 
623
646
  const bucketStorage = await f.getInstance(syncRules);
624
647
 
625
648
  const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
649
+ await batch.markAllSnapshotDone('0/1');
626
650
  await batch.save({
627
651
  sourceTable: TEST_TABLE,
628
652
  tag: storage.SaveOperationTag.INSERT,
@@ -660,7 +684,7 @@ bucket_definitions:
660
684
  test('expired token', async () => {
661
685
  await using f = await factory();
662
686
 
663
- const syncRules = await f.updateSyncRules({
687
+ const syncRules = await updateSyncRules(f, {
664
688
  content: BASIC_SYNC_RULES
665
689
  });
666
690
 
@@ -687,13 +711,14 @@ bucket_definitions:
687
711
  test('sync updates to global data', async (context) => {
688
712
  await using f = await factory();
689
713
 
690
- const syncRules = await f.updateSyncRules({
714
+ const syncRules = await updateSyncRules(f, {
691
715
  content: BASIC_SYNC_RULES
692
716
  });
693
717
 
694
718
  const bucketStorage = await f.getInstance(syncRules);
695
719
  // Activate
696
720
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
721
+ await batch.markAllSnapshotDone('0/0');
697
722
  await batch.keepalive('0/0');
698
723
  });
699
724
 
@@ -753,7 +778,7 @@ bucket_definitions:
753
778
  test('sync updates to parameter query only', async (context) => {
754
779
  await using f = await factory();
755
780
 
756
- const syncRules = await f.updateSyncRules({
781
+ const syncRules = await updateSyncRules(f, {
757
782
  content: `bucket_definitions:
758
783
  by_user:
759
784
  parameters: select users.id as user_id from users where users.id = request.user_id()
@@ -762,12 +787,13 @@ bucket_definitions:
762
787
  `
763
788
  });
764
789
 
765
- const usersTable = test_utils.makeTestTable('users', ['id']);
766
- const listsTable = test_utils.makeTestTable('lists', ['id']);
790
+ const usersTable = test_utils.makeTestTable('users', ['id'], config);
791
+ const listsTable = test_utils.makeTestTable('lists', ['id'], config);
767
792
 
768
793
  const bucketStorage = await f.getInstance(syncRules);
769
794
  // Activate
770
795
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
796
+ await batch.markAllSnapshotDone('0/0');
771
797
  await batch.keepalive('0/0');
772
798
  });
773
799
 
@@ -809,17 +835,18 @@ bucket_definitions:
809
835
  await batch.commit('0/1');
810
836
  });
811
837
 
838
+ const { bucket } = bucketRequest(syncRules, 'by_user["user1"]');
812
839
  const checkpoint2 = await getCheckpointLines(iter);
813
840
  expect(
814
841
  (checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
815
- ).toEqual(['by_user["user1"]']);
842
+ ).toEqual([bucket]);
816
843
  expect(checkpoint2).toMatchSnapshot();
817
844
  });
818
845
 
819
846
  test('sync updates to data query only', async (context) => {
820
847
  await using f = await factory();
821
848
 
822
- const syncRules = await f.updateSyncRules({
849
+ const syncRules = await updateSyncRules(f, {
823
850
  content: `bucket_definitions:
824
851
  by_user:
825
852
  parameters: select users.id as user_id from users where users.id = request.user_id()
@@ -828,12 +855,13 @@ bucket_definitions:
828
855
  `
829
856
  });
830
857
 
831
- const usersTable = test_utils.makeTestTable('users', ['id']);
832
- const listsTable = test_utils.makeTestTable('lists', ['id']);
858
+ const usersTable = test_utils.makeTestTable('users', ['id'], config);
859
+ const listsTable = test_utils.makeTestTable('lists', ['id'], config);
833
860
 
834
861
  const bucketStorage = await f.getInstance(syncRules);
835
862
 
836
863
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
864
+ await batch.markAllSnapshotDone('0/1');
837
865
  await batch.save({
838
866
  sourceTable: usersTable,
839
867
  tag: storage.SaveOperationTag.INSERT,
@@ -865,10 +893,9 @@ bucket_definitions:
865
893
  iter.return?.();
866
894
  });
867
895
 
896
+ const { bucket } = bucketRequest(syncRules, 'by_user["user1"]');
868
897
  const checkpoint1 = await getCheckpointLines(iter);
869
- expect((checkpoint1[0] as StreamingSyncCheckpoint).checkpoint?.buckets?.map((b) => b.bucket)).toEqual([
870
- 'by_user["user1"]'
871
- ]);
898
+ expect((checkpoint1[0] as StreamingSyncCheckpoint).checkpoint?.buckets?.map((b) => b.bucket)).toEqual([bucket]);
872
899
  expect(checkpoint1).toMatchSnapshot();
873
900
 
874
901
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
@@ -889,14 +916,14 @@ bucket_definitions:
889
916
  const checkpoint2 = await getCheckpointLines(iter);
890
917
  expect(
891
918
  (checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
892
- ).toEqual(['by_user["user1"]']);
919
+ ).toEqual([bucket]);
893
920
  expect(checkpoint2).toMatchSnapshot();
894
921
  });
895
922
 
896
923
  test('sync updates to parameter query + data', async (context) => {
897
924
  await using f = await factory();
898
925
 
899
- const syncRules = await f.updateSyncRules({
926
+ const syncRules = await updateSyncRules(f, {
900
927
  content: `bucket_definitions:
901
928
  by_user:
902
929
  parameters: select users.id as user_id from users where users.id = request.user_id()
@@ -905,12 +932,13 @@ bucket_definitions:
905
932
  `
906
933
  });
907
934
 
908
- const usersTable = test_utils.makeTestTable('users', ['id']);
909
- const listsTable = test_utils.makeTestTable('lists', ['id']);
935
+ const usersTable = test_utils.makeTestTable('users', ['id'], config);
936
+ const listsTable = test_utils.makeTestTable('lists', ['id'], config);
910
937
 
911
938
  const bucketStorage = await f.getInstance(syncRules);
912
939
  // Activate
913
940
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
941
+ await batch.markAllSnapshotDone('0/0');
914
942
  await batch.keepalive('0/0');
915
943
  });
916
944
 
@@ -936,6 +964,7 @@ bucket_definitions:
936
964
  expect(await getCheckpointLines(iter)).toMatchSnapshot();
937
965
 
938
966
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
967
+ await batch.markAllSnapshotDone('0/1');
939
968
  await batch.save({
940
969
  sourceTable: listsTable,
941
970
  tag: storage.SaveOperationTag.INSERT,
@@ -960,23 +989,25 @@ bucket_definitions:
960
989
  await batch.commit('0/1');
961
990
  });
962
991
 
992
+ const { bucket } = bucketRequest(syncRules, 'by_user["user1"]');
963
993
  const checkpoint2 = await getCheckpointLines(iter);
964
994
  expect(
965
995
  (checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
966
- ).toEqual(['by_user["user1"]']);
996
+ ).toEqual([bucket]);
967
997
  expect(checkpoint2).toMatchSnapshot();
968
998
  });
969
999
 
970
1000
  test('expiring token', async (context) => {
971
1001
  await using f = await factory();
972
1002
 
973
- const syncRules = await f.updateSyncRules({
1003
+ const syncRules = await updateSyncRules(f, {
974
1004
  content: BASIC_SYNC_RULES
975
1005
  });
976
1006
 
977
1007
  const bucketStorage = await f.getInstance(syncRules);
978
1008
  // Activate
979
1009
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
1010
+ await batch.markAllSnapshotDone('0/0');
980
1011
  await batch.keepalive('0/0');
981
1012
  });
982
1013
 
@@ -1015,13 +1046,14 @@ bucket_definitions:
1015
1046
 
1016
1047
  await using f = await factory();
1017
1048
 
1018
- const syncRules = await f.updateSyncRules({
1049
+ const syncRules = await updateSyncRules(f, {
1019
1050
  content: BASIC_SYNC_RULES
1020
1051
  });
1021
1052
 
1022
1053
  const bucketStorage = await f.getInstance(syncRules);
1023
1054
 
1024
1055
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
1056
+ await batch.markAllSnapshotDone('0/1');
1025
1057
  await batch.save({
1026
1058
  sourceTable: TEST_TABLE,
1027
1059
  tag: storage.SaveOperationTag.INSERT,
@@ -1077,6 +1109,7 @@ bucket_definitions:
1077
1109
  // This invalidates the checkpoint we've received above.
1078
1110
 
1079
1111
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
1112
+ await batch.markAllSnapshotDone('0/1');
1080
1113
  await batch.save({
1081
1114
  sourceTable: TEST_TABLE,
1082
1115
  tag: storage.SaveOperationTag.UPDATE,
@@ -1158,13 +1191,14 @@ bucket_definitions:
1158
1191
  test('write checkpoint', async () => {
1159
1192
  await using f = await factory();
1160
1193
 
1161
- const syncRules = await f.updateSyncRules({
1194
+ const syncRules = await updateSyncRules(f, {
1162
1195
  content: BASIC_SYNC_RULES
1163
1196
  });
1164
1197
 
1165
1198
  const bucketStorage = f.getInstance(syncRules);
1166
1199
 
1167
1200
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
1201
+ await batch.markAllSnapshotDone('0/1');
1168
1202
  // <= the managed write checkpoint LSN below
1169
1203
  await batch.commit('0/1');
1170
1204
  });
@@ -1200,6 +1234,7 @@ bucket_definitions:
1200
1234
  });
1201
1235
 
1202
1236
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
1237
+ await batch.markAllSnapshotDone('0/1');
1203
1238
  // must be >= the managed write checkpoint LSN
1204
1239
  await batch.commit('1/0');
1205
1240
  });
@@ -1229,12 +1264,13 @@ config:
1229
1264
  `;
1230
1265
 
1231
1266
  for (let i = 0; i < 2; i++) {
1232
- const syncRules = await f.updateSyncRules({
1267
+ const syncRules = await updateSyncRules(f, {
1233
1268
  content: rules
1234
1269
  });
1235
1270
  const bucketStorage = f.getInstance(syncRules);
1236
1271
 
1237
1272
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
1273
+ await batch.markAllSnapshotDone('0/1');
1238
1274
  await batch.save({
1239
1275
  sourceTable: TEST_TABLE,
1240
1276
  tag: storage.SaveOperationTag.INSERT,
package/src/tests/util.ts CHANGED
@@ -1,3 +1,53 @@
1
- import { test_utils } from '../index.js';
1
+ import { storage } from '@powersync/service-core';
2
+ import {
3
+ ParameterIndexLookupCreator,
4
+ SourceTableInterface,
5
+ SqliteRow,
6
+ TablePattern
7
+ } from '@powersync/service-sync-rules';
8
+ import { ParameterLookupScope } from '@powersync/service-sync-rules/src/HydrationState.js';
9
+ import { bucketRequest } from '../test-utils/general-utils.js';
2
10
 
3
- export const TEST_TABLE = test_utils.makeTestTable('test', ['id']);
11
+ export function bucketRequestMap(
12
+ syncRules: storage.PersistedSyncRulesContent,
13
+ buckets: Iterable<readonly [string, bigint]>
14
+ ): storage.BucketDataRequest[] {
15
+ return Array.from(buckets, ([bucketName, opId]) => bucketRequest(syncRules, bucketName, opId));
16
+ }
17
+
18
+ export function bucketRequests(
19
+ syncRules: storage.PersistedSyncRulesContent,
20
+ bucketNames: string[]
21
+ ): storage.BucketChecksumRequest[] {
22
+ return bucketNames.map((bucketName) => {
23
+ const request = bucketRequest(syncRules, bucketName, 0n);
24
+ return { bucket: request.bucket, source: request.source };
25
+ });
26
+ }
27
+
28
+ const EMPTY_LOOKUP_SOURCE: ParameterIndexLookupCreator = {
29
+ get defaultLookupScope(): ParameterLookupScope {
30
+ return {
31
+ lookupName: 'lookup',
32
+ queryId: '0',
33
+ source: EMPTY_LOOKUP_SOURCE
34
+ };
35
+ },
36
+ getSourceTables(): Set<TablePattern> {
37
+ return new Set();
38
+ },
39
+ evaluateParameterRow(_sourceTable: SourceTableInterface, _row: SqliteRow) {
40
+ return [];
41
+ },
42
+ tableSyncsParameters(_table: SourceTableInterface): boolean {
43
+ return false;
44
+ }
45
+ };
46
+
47
+ export function parameterLookupScope(
48
+ lookupName: string,
49
+ queryId: string,
50
+ source: ParameterIndexLookupCreator = EMPTY_LOOKUP_SOURCE
51
+ ): ParameterLookupScope {
52
+ return { lookupName, queryId, source };
53
+ }