@salesforce/lds-ads-bridge 1.428.0-dev1 → 1.428.0-dev10

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.
@@ -483,7 +483,7 @@ const callbacks$1 = [];
483
483
  function register(r) {
484
484
  callbacks$1.forEach((callback) => callback(r));
485
485
  }
486
- // version: 1.428.0-dev1-c95a813572
486
+ // version: 1.428.0-dev10-1e665d263f
487
487
 
488
488
  /**
489
489
  * Returns true if the value acts like a Promise, i.e. has a "then" function,
@@ -7920,6 +7920,9 @@ function isSpanningRecord(fieldValue) {
7920
7920
  function isStoreKeyRecordId(key) {
7921
7921
  return key.indexOf(RECORD_ID_PREFIX) > -1 && key.indexOf(RECORD_FIELDS_KEY_JUNCTION) === -1;
7922
7922
  }
7923
+ function isStoreKeyRecordField(key) {
7924
+ return key.indexOf(RECORD_ID_PREFIX) > -1 && key.indexOf(RECORD_FIELDS_KEY_JUNCTION) > -1;
7925
+ }
7923
7926
  /**
7924
7927
  * Returns a shallow copy of a record with its field values if it is a scalar and a reference and a
7925
7928
  * a RecordRepresentation with no field if the value if a spanning record.
@@ -8214,6 +8217,33 @@ class AdsBridge {
8214
8217
  this.isRecordEmitLocked = false;
8215
8218
  }
8216
8219
  }
8220
+ filterAndSynthesizeBaseIds(updatedEntries) {
8221
+ // Collect base record IDs that are directly present in the entries.
8222
+ const directBaseIds = new Set();
8223
+ for (let i = 0; i < updatedEntries.length; i++) {
8224
+ if (isStoreKeyRecordId(updatedEntries[i].id)) {
8225
+ directBaseIds.add(updatedEntries[i].id);
8226
+ }
8227
+ }
8228
+ // For field entries whose base record ID has no direct entry, synthesize one.
8229
+ const syntheticBaseIds = new Set();
8230
+ for (let i = 0; i < updatedEntries.length; i++) {
8231
+ if (isStoreKeyRecordField(updatedEntries[i].id)) {
8232
+ const baseId = updatedEntries[i].id.split(RECORD_FIELDS_KEY_JUNCTION)[0];
8233
+ if (!directBaseIds.has(baseId)) {
8234
+ syntheticBaseIds.add(baseId);
8235
+ }
8236
+ }
8237
+ }
8238
+ // Exclude all the store record ids not matching with the record id pattern.
8239
+ // Note: FieldValueRepresentation have the same prefix than RecordRepresentation so we
8240
+ // need to filter them out.
8241
+ const filteredUpdatedEntries = updatedEntries.filter((entry) => isStoreKeyRecordId(entry.id));
8242
+ syntheticBaseIds.forEach((baseId) => {
8243
+ push.call(filteredUpdatedEntries, { id: baseId });
8244
+ });
8245
+ return filteredUpdatedEntries;
8246
+ }
8217
8247
  /**
8218
8248
  * This method retrieves queries the store with with passed record ids to retrieve their
8219
8249
  * associated records and object info. Note that the passed ids are not Salesforce record id
@@ -8224,14 +8254,10 @@ class AdsBridge {
8224
8254
  let shouldEmit = false;
8225
8255
  const adsRecordMap = {};
8226
8256
  const adsObjectMap = {};
8227
- for (let i = 0; i < updatedEntries.length; i++) {
8228
- const storeRecordId = updatedEntries[i].id;
8229
- // Exclude all the store record ids not matching with the record id pattern.
8230
- // Note: FieldValueRepresentation have the same prefix than RecordRepresentation so we
8231
- // need to filter them out.
8232
- if (!isStoreKeyRecordId(storeRecordId)) {
8233
- continue;
8234
- }
8257
+ // Context for change: W-21715343
8258
+ const filteredUpdatedEntries = this.filterAndSynthesizeBaseIds(updatedEntries);
8259
+ for (let i = 0; i < filteredUpdatedEntries.length; i++) {
8260
+ const storeRecordId = filteredUpdatedEntries[i].id;
8235
8261
  const record = this.recordRepresentationIngestOverride !== undefined
8236
8262
  ? getShallowRecordDenormalized(luvio, storeRecordId)
8237
8263
  : getShallowRecord(luvio, storeRecordId);
package/dist/adsBridge.js CHANGED
@@ -58,6 +58,9 @@ function isSpanningRecord(fieldValue) {
58
58
  function isStoreKeyRecordId(key) {
59
59
  return key.indexOf(RECORD_ID_PREFIX) > -1 && key.indexOf(RECORD_FIELDS_KEY_JUNCTION) === -1;
60
60
  }
61
+ function isStoreKeyRecordField(key) {
62
+ return key.indexOf(RECORD_ID_PREFIX) > -1 && key.indexOf(RECORD_FIELDS_KEY_JUNCTION) > -1;
63
+ }
61
64
  /**
62
65
  * Returns a shallow copy of a record with its field values if it is a scalar and a reference and a
63
66
  * a RecordRepresentation with no field if the value if a spanning record.
@@ -356,6 +359,33 @@ class AdsBridge {
356
359
  this.isRecordEmitLocked = false;
357
360
  }
358
361
  }
362
+ filterAndSynthesizeBaseIds(updatedEntries) {
363
+ // Collect base record IDs that are directly present in the entries.
364
+ const directBaseIds = new Set();
365
+ for (let i = 0; i < updatedEntries.length; i++) {
366
+ if (isStoreKeyRecordId(updatedEntries[i].id)) {
367
+ directBaseIds.add(updatedEntries[i].id);
368
+ }
369
+ }
370
+ // For field entries whose base record ID has no direct entry, synthesize one.
371
+ const syntheticBaseIds = new Set();
372
+ for (let i = 0; i < updatedEntries.length; i++) {
373
+ if (isStoreKeyRecordField(updatedEntries[i].id)) {
374
+ const baseId = updatedEntries[i].id.split(RECORD_FIELDS_KEY_JUNCTION)[0];
375
+ if (!directBaseIds.has(baseId)) {
376
+ syntheticBaseIds.add(baseId);
377
+ }
378
+ }
379
+ }
380
+ // Exclude all the store record ids not matching with the record id pattern.
381
+ // Note: FieldValueRepresentation have the same prefix than RecordRepresentation so we
382
+ // need to filter them out.
383
+ const filteredUpdatedEntries = updatedEntries.filter((entry) => isStoreKeyRecordId(entry.id));
384
+ syntheticBaseIds.forEach((baseId) => {
385
+ push.call(filteredUpdatedEntries, { id: baseId });
386
+ });
387
+ return filteredUpdatedEntries;
388
+ }
359
389
  /**
360
390
  * This method retrieves queries the store with with passed record ids to retrieve their
361
391
  * associated records and object info. Note that the passed ids are not Salesforce record id
@@ -367,14 +397,10 @@ class AdsBridge {
367
397
  let shouldEmit = false;
368
398
  const adsRecordMap = {};
369
399
  const adsObjectMap = {};
370
- for (let i = 0; i < updatedEntries.length; i++) {
371
- const storeRecordId = updatedEntries[i].id;
372
- // Exclude all the store record ids not matching with the record id pattern.
373
- // Note: FieldValueRepresentation have the same prefix than RecordRepresentation so we
374
- // need to filter them out.
375
- if (!isStoreKeyRecordId(storeRecordId)) {
376
- continue;
377
- }
400
+ // Context for change: W-21715343
401
+ const filteredUpdatedEntries = this.filterAndSynthesizeBaseIds(updatedEntries);
402
+ for (let i = 0; i < filteredUpdatedEntries.length; i++) {
403
+ const storeRecordId = filteredUpdatedEntries[i].id;
378
404
  const record = this.recordRepresentationIngestOverride !== undefined
379
405
  ? getShallowRecordDenormalized(luvio, storeRecordId)
380
406
  : getShallowRecord(luvio, storeRecordId);
@@ -435,4 +461,4 @@ function withAdsBridge(callback) {
435
461
  }
436
462
 
437
463
  export { instrument, withAdsBridge };
438
- // version: 1.428.0-dev1-c95a813572
464
+ // version: 1.428.0-dev10-1e665d263f
@@ -78,6 +78,7 @@ export default class AdsBridge {
78
78
  * mutations triggered by ADS to be emit back to ADS.
79
79
  */
80
80
  private lockLdsRecordEmit;
81
+ private filterAndSynthesizeBaseIds;
81
82
  /**
82
83
  * This method retrieves queries the store with with passed record ids to retrieve their
83
84
  * associated records and object info. Note that the passed ids are not Salesforce record id
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-ads-bridge",
3
- "version": "1.428.0-dev1",
3
+ "version": "1.428.0-dev10",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "Bridge to sync data between LDS and ADS",
6
6
  "main": "dist/adsBridge.js",
@@ -30,9 +30,9 @@
30
30
  "release:corejar": "yarn build && ../core-build/scripts/core.js --name=lds-ads-bridge"
31
31
  },
32
32
  "devDependencies": {
33
- "@salesforce/lds-adapters-uiapi": "^1.428.0-dev1",
34
- "@salesforce/lds-runtime-mobile": "^1.428.0-dev1",
35
- "@salesforce/lds-uiapi-record-utils-mobile": "^1.428.0-dev1"
33
+ "@salesforce/lds-adapters-uiapi": "^1.428.0-dev10",
34
+ "@salesforce/lds-runtime-mobile": "^1.428.0-dev10",
35
+ "@salesforce/lds-uiapi-record-utils-mobile": "^1.428.0-dev10"
36
36
  },
37
37
  "volta": {
38
38
  "extends": "../../package.json"
@@ -41,9 +41,9 @@
41
41
  {
42
42
  "path": "./dist/adsBridge.js",
43
43
  "maxSize": {
44
- "none": "17 kB",
45
- "min": "5.51 kB",
46
- "compressed": "4 kB"
44
+ "none": "18.4 kB",
45
+ "min": "6 kB",
46
+ "compressed": "4.3 kB"
47
47
  }
48
48
  }
49
49
  ]
@@ -1,5 +1,10 @@
1
1
  import { Luvio, InMemoryStore, Environment } from '@luvio/engine';
2
- import { keyBuilderRecord, ingestRecord, type Registration } from '@salesforce/lds-adapters-uiapi';
2
+ import {
3
+ keyBuilderRecord,
4
+ ingestRecord,
5
+ type Registration,
6
+ ingestRecordSuccess,
7
+ } from '@salesforce/lds-adapters-uiapi';
3
8
  import { expect } from '@jest/globals';
4
9
 
5
10
  import AdsBridge from '../ads-bridge';
@@ -417,6 +422,159 @@ describe('AdsBridge', () => {
417
422
  });
418
423
  });
419
424
 
425
+ // W-21715343
426
+ // Context for change: https://docs.google.com/document/d/1iF6M9jldEX_K9FOpdttLqVwO9uESUUrlyWi2mWnXtAQ/edit?usp=sharing
427
+ it('correctly emits the updated Case record to ADS when refreshSnapshot is called, and the Case record was updated via spanning record updates on the Task record', async () => {
428
+ const initialLdsState = JSON.parse(JSON.stringify(require('./initial_record.json')));
429
+ const addRecordsGet = JSON.parse(JSON.stringify(require('./task_record_gvp_get.json')));
430
+ const addRecordsSave = JSON.parse(
431
+ JSON.stringify(require('./task_record_gvp_save.json'))
432
+ );
433
+ const addRecordsGet2 = JSON.parse(
434
+ JSON.stringify(require('./task_record_gvp_get2.json'))
435
+ );
436
+
437
+ const { bridge, luvio } = createBridge();
438
+ const caseId: string = initialLdsState.id;
439
+
440
+ const selector = {
441
+ recordId: keyBuilderRecord(luvio, { recordId: caseId }),
442
+ node: { kind: 'Fragment' as const, private: [] as string[] },
443
+ variables: {},
444
+ };
445
+
446
+ // Creating a refreshable snapshot of the Case record as we don't have the wire adapter bindings available to us in jest environment to refresh the snapshot manually.
447
+ const snapshot = luvio.storeLookup(selector, {
448
+ config: { recordId: caseId },
449
+ resolve: async () => {
450
+ const response = await luvio.dispatchResourceRequest({
451
+ baseUri: '',
452
+ basePath: `/ui-api/records/${caseId}`,
453
+ method: 'get',
454
+ body: null,
455
+ queryParams: {},
456
+ urlParams: {},
457
+ headers: {},
458
+ priority: 'normal',
459
+ });
460
+ const config = {
461
+ optionalFields: ['Case.Id'],
462
+ recordId: caseId,
463
+ };
464
+ const trackedFields = ['Case.Status'];
465
+ ingestRecordSuccess(luvio, config, caseId, trackedFields, response as any, 0);
466
+ await luvio.storeBroadcast();
467
+ return luvio.storeLookup(selector);
468
+ },
469
+ });
470
+
471
+ // 1. Prime LDS with the Case fixture (via addRecord → storeIngest + storeBroadcast).
472
+ addRecord(luvio, initialLdsState);
473
+
474
+ const expectedStatus = queryRecord(luvio, { recordId: caseId }).data.fields.Status;
475
+ expect(expectedStatus).toEqual({ value: 'New', displayValue: 'New' });
476
+
477
+ luvio.dispatchResourceRequest = jest.fn();
478
+
479
+ const fn = jest.fn();
480
+ bridge.receiveFromLdsCallback = fn;
481
+
482
+ // 2. Ingest the Task (+ spanning Case__r) via addRecords().
483
+ bridge.addRecords(addRecordsGet); // A RecordGvp.getRecord call is made to get the initial Task record when switching from the Case record to the Task record in console mode.
484
+ bridge.addRecords(addRecordsSave); // Clicking the complete button on the Task record which does a RecordGvp.saveRecord call.
485
+ bridge.addRecords(addRecordsGet2); // A RecordGvp.getRecord call is made to get the updated Task record.
486
+
487
+ expect(luvio.dispatchResourceRequest).toHaveBeenCalledTimes(0);
488
+
489
+ // 3. Synthesize the closed Case record server response which is expected to be received when the refreshSnapshot is called.
490
+ const closedCaseResponse = JSON.parse(JSON.stringify(require('./initial_record.json')));
491
+ closedCaseResponse.fields.Status = { value: 'Closed', displayValue: 'Closed' };
492
+ closedCaseResponse.weakEtag = addRecordsGet2[0].weakEtag;
493
+ closedCaseResponse.systemModstamp = addRecordsGet2[0].systemModstamp;
494
+ closedCaseResponse.lastModifiedDate = addRecordsGet2[0].lastModifiedDate;
495
+
496
+ luvio.dispatchResourceRequest = jest
497
+ .fn()
498
+ .mockResolvedValueOnce({ body: closedCaseResponse })
499
+ .mockImplementation(() => new Promise(() => {}));
500
+
501
+ // 4. Refresh the snapshot to get the updated Case record. This was previously not working because the interactions on the ADS-Bridge had updated the Case record with the latest weakEtag, but NOT the updated Status field value.
502
+ const refreshedSnapshot = await luvio.refreshSnapshot(snapshot);
503
+ expect((refreshedSnapshot.data as any).fields.Status).toEqual(
504
+ expect.objectContaining({ value: 'Closed' })
505
+ );
506
+
507
+ // 5. With the ADS-Bridge changes, the Case record is now emitted when the refreshSnapshot is called.
508
+ expect(fn.mock.calls[0]).toMatchInlineSnapshot(`
509
+ Array [
510
+ Object {
511
+ "500xx000000boDJAAY": Object {
512
+ "Case": Object {
513
+ "isPrimary": true,
514
+ "record": Object {
515
+ "apiName": "Case",
516
+ "childRelationships": Object {},
517
+ "eTag": "",
518
+ "fields": Object {
519
+ "CaseNumber": Object {
520
+ "displayValue": null,
521
+ "value": "00001026",
522
+ },
523
+ "Id": Object {
524
+ "displayValue": null,
525
+ "value": "500xx000000boDJAAY",
526
+ },
527
+ "IsEscalated": Object {
528
+ "displayValue": null,
529
+ "value": false,
530
+ },
531
+ "MasterRecordId": Object {
532
+ "displayValue": null,
533
+ "value": null,
534
+ },
535
+ "Priority": Object {
536
+ "displayValue": "Medium",
537
+ "value": "Medium",
538
+ },
539
+ "RecordTypeId": Object {
540
+ "displayValue": null,
541
+ "value": "012000000000000AAA",
542
+ },
543
+ "Status": Object {
544
+ "displayValue": "Closed",
545
+ "value": "Closed",
546
+ },
547
+ "Subject": Object {
548
+ "displayValue": null,
549
+ "value": "Fixture subject",
550
+ },
551
+ "SystemModstamp": Object {
552
+ "displayValue": null,
553
+ "value": "2026-04-11T00:46:56.000Z",
554
+ },
555
+ },
556
+ "id": "500xx000000boDJAAY",
557
+ "lastModifiedById": "005xx000001X8gHAAS",
558
+ "lastModifiedDate": "2026-04-13T20:54:41.000Z",
559
+ "recordTypeId": "012000000000000AAA",
560
+ "recordTypeInfo": null,
561
+ "systemModstamp": "2026-04-13T20:54:41.000Z",
562
+ "weakEtag": 1776113681000,
563
+ },
564
+ },
565
+ },
566
+ },
567
+ Object {
568
+ "Case": Object {
569
+ "_entityLabel": "Case",
570
+ "_keyPrefix": "500",
571
+ "_nameField": "Name",
572
+ },
573
+ },
574
+ ]
575
+ `);
576
+ });
577
+
420
578
  describe('displayValue', () => {
421
579
  it('does not let null overwrite non-null displayValue', () => {
422
580
  const { bridge, luvio } = createBridge();
@@ -1383,6 +1541,82 @@ describe('AdsBridge', () => {
1383
1541
  });
1384
1542
  });
1385
1543
 
1544
+ describe('filterAndSynthesizeBaseIds', () => {
1545
+ const BASE_KEY = 'UiApi::RecordRepresentation:001xx000000001AAA';
1546
+ const FIELD_KEY = 'UiApi::RecordRepresentation:001xx000000001AAA__fields__Name';
1547
+ const BASE_KEY_2 = 'UiApi::RecordRepresentation:001xx000000002AAA';
1548
+ const FIELD_KEY_2A = 'UiApi::RecordRepresentation:001xx000000002AAA__fields__Name';
1549
+ const FIELD_KEY_2B = 'UiApi::RecordRepresentation:001xx000000002AAA__fields__Id';
1550
+ const NON_RECORD_KEY = 'SomeOther::Thing:abc123';
1551
+
1552
+ function callFilter(bridge: AdsBridge, entries: { id: string }[]): { id: string }[] {
1553
+ return (bridge as any).filterAndSynthesizeBaseIds(entries);
1554
+ }
1555
+
1556
+ it('returns an empty array when given an empty array', () => {
1557
+ const { bridge } = createBridge();
1558
+ expect(callFilter(bridge, [])).toEqual([]);
1559
+ });
1560
+
1561
+ it('filters out non-record entries', () => {
1562
+ const { bridge } = createBridge();
1563
+ const result = callFilter(bridge, [{ id: NON_RECORD_KEY }]);
1564
+ expect(result).toEqual([]);
1565
+ });
1566
+
1567
+ it('returns base record entries unchanged', () => {
1568
+ const { bridge } = createBridge();
1569
+ const result = callFilter(bridge, [{ id: BASE_KEY }]);
1570
+ expect(result).toEqual([{ id: BASE_KEY }]);
1571
+ });
1572
+
1573
+ it('synthesizes a base record entry for a field entry with no direct base entry', () => {
1574
+ const { bridge } = createBridge();
1575
+ const result = callFilter(bridge, [{ id: FIELD_KEY }]);
1576
+ expect(result).toEqual([{ id: BASE_KEY }]);
1577
+ });
1578
+
1579
+ it('does not synthesize a duplicate base entry when a direct base entry is already present', () => {
1580
+ const { bridge } = createBridge();
1581
+ const result = callFilter(bridge, [{ id: BASE_KEY }, { id: FIELD_KEY }]);
1582
+ expect(result).toHaveLength(1);
1583
+ expect(result).toEqual([{ id: BASE_KEY }]);
1584
+ });
1585
+
1586
+ it('synthesizes exactly one base entry for multiple field entries sharing the same base', () => {
1587
+ const { bridge } = createBridge();
1588
+ const result = callFilter(bridge, [{ id: FIELD_KEY_2A }, { id: FIELD_KEY_2B }]);
1589
+ expect(result).toHaveLength(1);
1590
+ expect(result).toEqual([{ id: BASE_KEY_2 }]);
1591
+ });
1592
+
1593
+ it('returns base entries and synthesizes entries for fields whose base is not directly present', () => {
1594
+ const { bridge } = createBridge();
1595
+ const entries = [
1596
+ { id: BASE_KEY },
1597
+ { id: FIELD_KEY },
1598
+ { id: FIELD_KEY_2A },
1599
+ { id: FIELD_KEY_2B },
1600
+ ];
1601
+ const result = callFilter(bridge, entries);
1602
+ expect(result).toHaveLength(2);
1603
+ expect(result).toContainEqual({ id: BASE_KEY });
1604
+ expect(result).toContainEqual({ id: BASE_KEY_2 });
1605
+ });
1606
+
1607
+ it('filters out non-record entries while still processing valid entries', () => {
1608
+ const { bridge } = createBridge();
1609
+ const result = callFilter(bridge, [
1610
+ { id: NON_RECORD_KEY },
1611
+ { id: BASE_KEY },
1612
+ { id: FIELD_KEY_2A },
1613
+ ]);
1614
+ expect(result).toHaveLength(2);
1615
+ expect(result).toContainEqual({ id: BASE_KEY });
1616
+ expect(result).toContainEqual({ id: BASE_KEY_2 });
1617
+ });
1618
+ });
1619
+
1386
1620
  describe('isDMOEntity', () => {
1387
1621
  it('should return true for DMO record', () => {
1388
1622
  const record = createRecord({
@@ -0,0 +1,50 @@
1
+ {
2
+ "apiName": "Case",
3
+ "childRelationships": {},
4
+ "eTag": "",
5
+ "fields": {
6
+ "Id": {
7
+ "displayValue": null,
8
+ "value": "500xx000000boDJAAY"
9
+ },
10
+ "RecordTypeId": {
11
+ "displayValue": null,
12
+ "value": "012000000000000AAA"
13
+ },
14
+ "IsEscalated": {
15
+ "displayValue": null,
16
+ "value": false
17
+ },
18
+ "MasterRecordId": {
19
+ "displayValue": null,
20
+ "value": null
21
+ },
22
+ "SystemModstamp": {
23
+ "displayValue": null,
24
+ "value": "2026-04-11T00:46:56.000Z"
25
+ },
26
+ "CaseNumber": {
27
+ "displayValue": null,
28
+ "value": "00001026"
29
+ },
30
+ "Priority": {
31
+ "displayValue": "Medium",
32
+ "value": "Medium"
33
+ },
34
+ "Status": {
35
+ "displayValue": "New",
36
+ "value": "New"
37
+ },
38
+ "Subject": {
39
+ "displayValue": null,
40
+ "value": "Fixture subject"
41
+ }
42
+ },
43
+ "id": "500xx000000boDJAAY",
44
+ "lastModifiedById": "005xx000001X8gHAAS",
45
+ "lastModifiedDate": "2026-04-13T20:50:18.000Z",
46
+ "recordTypeId": "012000000000000AAA",
47
+ "recordTypeInfo": null,
48
+ "systemModstamp": "2026-04-13T20:50:18.000Z",
49
+ "weakEtag": 1776113418000
50
+ }
@@ -0,0 +1,233 @@
1
+ [
2
+ {
3
+ "apiName": "Task",
4
+ "childRelationships": {},
5
+ "eTag": "2d24f5c26414c4f90731ba59a83c8d71",
6
+ "fields": {
7
+ "ActivityDate": {
8
+ "displayValue": null,
9
+ "value": null
10
+ },
11
+ "Case__c": {
12
+ "displayValue": null,
13
+ "value": "500xx000000boDJAAY"
14
+ },
15
+ "Case__r": {
16
+ "displayValue": "00001027",
17
+ "value": {
18
+ "apiName": "Case",
19
+ "childRelationships": {},
20
+ "eTag": "f9130f3feb968a9bb7e0c222a78ef1dc",
21
+ "fields": {
22
+ "CaseNumber": {
23
+ "displayValue": null,
24
+ "value": "00001027"
25
+ },
26
+ "Id": {
27
+ "displayValue": null,
28
+ "value": "500xx000000boDJAAY"
29
+ }
30
+ },
31
+ "id": "500xx000000boDJAAY",
32
+ "lastModifiedById": "005xx000001X8gHAAS",
33
+ "lastModifiedDate": "2026-04-13T20:50:18.000Z",
34
+ "recordTypeId": "012000000000000AAA",
35
+ "recordTypeInfo": null,
36
+ "systemModstamp": "2026-04-13T20:50:18.000Z",
37
+ "weakEtag": 1776113418000
38
+ }
39
+ },
40
+ "CreatedBy": {
41
+ "displayValue": "Ethan Chan",
42
+ "value": {
43
+ "apiName": "User",
44
+ "childRelationships": {},
45
+ "eTag": "2ca65e8b3117284d9253195c82c5f03d",
46
+ "fields": {
47
+ "FirstName": {
48
+ "displayValue": null,
49
+ "value": "Ethan"
50
+ },
51
+ "Id": {
52
+ "displayValue": null,
53
+ "value": "005xx000001X8gHAAS"
54
+ },
55
+ "LastName": {
56
+ "displayValue": null,
57
+ "value": "Chan"
58
+ },
59
+ "Name": {
60
+ "displayValue": null,
61
+ "value": "Ethan Chan"
62
+ }
63
+ },
64
+ "id": "005xx000001X8gHAAS",
65
+ "lastModifiedById": "005xx000001X8gHAAS",
66
+ "lastModifiedDate": "2026-04-13T19:07:57.000Z",
67
+ "recordTypeId": null,
68
+ "recordTypeInfo": null,
69
+ "systemModstamp": "2026-04-13T19:07:57.000Z",
70
+ "weakEtag": 1776107277000
71
+ }
72
+ },
73
+ "CreatedById": {
74
+ "displayValue": null,
75
+ "value": "005xx000001X8gHAAS"
76
+ },
77
+ "CreatedDate": {
78
+ "displayValue": "4/13/2026, 12:09 PM",
79
+ "value": "2026-04-13T19:09:48.000Z"
80
+ },
81
+ "Description": {
82
+ "displayValue": null,
83
+ "value": null
84
+ },
85
+ "Id": {
86
+ "displayValue": null,
87
+ "value": "00Txx000003rIcmEAE"
88
+ },
89
+ "IsClosed": {
90
+ "displayValue": null,
91
+ "value": false
92
+ },
93
+ "LastModifiedBy": {
94
+ "displayValue": "Ethan Chan",
95
+ "value": {
96
+ "apiName": "User",
97
+ "childRelationships": {},
98
+ "eTag": "2ca65e8b3117284d9253195c82c5f03d",
99
+ "fields": {
100
+ "FirstName": {
101
+ "displayValue": null,
102
+ "value": "Ethan"
103
+ },
104
+ "Id": {
105
+ "displayValue": null,
106
+ "value": "005xx000001X8gHAAS"
107
+ },
108
+ "LastName": {
109
+ "displayValue": null,
110
+ "value": "Chan"
111
+ },
112
+ "Name": {
113
+ "displayValue": null,
114
+ "value": "Ethan Chan"
115
+ }
116
+ },
117
+ "id": "005xx000001X8gHAAS",
118
+ "lastModifiedById": "005xx000001X8gHAAS",
119
+ "lastModifiedDate": "2026-04-13T19:07:57.000Z",
120
+ "recordTypeId": null,
121
+ "recordTypeInfo": null,
122
+ "systemModstamp": "2026-04-13T19:07:57.000Z",
123
+ "weakEtag": 1776107277000
124
+ }
125
+ },
126
+ "LastModifiedById": {
127
+ "displayValue": null,
128
+ "value": "005xx000001X8gHAAS"
129
+ },
130
+ "LastModifiedDate": {
131
+ "displayValue": "4/13/2026, 1:50 PM",
132
+ "value": "2026-04-13T20:50:05.000Z"
133
+ },
134
+ "Owner": {
135
+ "displayValue": "Ethan Chan",
136
+ "value": {
137
+ "apiName": "Name",
138
+ "childRelationships": {},
139
+ "eTag": "202a115a07830e8af0343368d4d309d4",
140
+ "fields": {
141
+ "FirstName": {
142
+ "displayValue": null,
143
+ "value": "Ethan"
144
+ },
145
+ "Id": {
146
+ "displayValue": null,
147
+ "value": "005xx000001X8gHAAS"
148
+ },
149
+ "LastName": {
150
+ "displayValue": null,
151
+ "value": "Chan"
152
+ },
153
+ "Name": {
154
+ "displayValue": null,
155
+ "value": "Ethan Chan"
156
+ }
157
+ },
158
+ "id": "005xx000001X8gHAAS",
159
+ "lastModifiedById": null,
160
+ "lastModifiedDate": null,
161
+ "recordTypeId": null,
162
+ "recordTypeInfo": null,
163
+ "systemModstamp": null,
164
+ "weakEtag": 0
165
+ }
166
+ },
167
+ "OwnerId": {
168
+ "displayValue": null,
169
+ "value": "005xx000001X8gHAAS"
170
+ },
171
+ "Priority": {
172
+ "displayValue": "High",
173
+ "value": "High"
174
+ },
175
+ "Status": {
176
+ "displayValue": "Not Started",
177
+ "value": "Not Started"
178
+ },
179
+ "Subject": {
180
+ "displayValue": null,
181
+ "value": "Call"
182
+ },
183
+ "SystemModstamp": {
184
+ "displayValue": "4/13/2026, 1:50 PM",
185
+ "value": "2026-04-13T20:50:05.000Z"
186
+ },
187
+ "What": {
188
+ "displayValue": "00001027",
189
+ "value": {
190
+ "apiName": "Name",
191
+ "childRelationships": {},
192
+ "eTag": "deffd76450e8f3c8fc116a1cb6a0bb6b",
193
+ "fields": {
194
+ "Id": {
195
+ "displayValue": null,
196
+ "value": "500xx000000boDJAAY"
197
+ },
198
+ "Name": {
199
+ "displayValue": null,
200
+ "value": "00001027"
201
+ }
202
+ },
203
+ "id": "500xx000000boDJAAY",
204
+ "lastModifiedById": null,
205
+ "lastModifiedDate": null,
206
+ "recordTypeId": null,
207
+ "recordTypeInfo": null,
208
+ "systemModstamp": null,
209
+ "weakEtag": 0
210
+ }
211
+ },
212
+ "WhatId": {
213
+ "displayValue": null,
214
+ "value": "500xx000000boDJAAY"
215
+ },
216
+ "Who": {
217
+ "displayValue": null,
218
+ "value": null
219
+ },
220
+ "WhoId": {
221
+ "displayValue": null,
222
+ "value": null
223
+ }
224
+ },
225
+ "id": "00Txx000003rIcmEAE",
226
+ "lastModifiedById": "005xx000001X8gHAAS",
227
+ "lastModifiedDate": "2026-04-13T20:50:05.000Z",
228
+ "recordTypeId": "012000000000000AAA",
229
+ "recordTypeInfo": null,
230
+ "systemModstamp": "2026-04-13T20:50:05.000Z",
231
+ "weakEtag": 1776113405000
232
+ }
233
+ ]
@@ -0,0 +1,233 @@
1
+ [
2
+ {
3
+ "apiName": "Task",
4
+ "childRelationships": {},
5
+ "eTag": "49e9f990d8b63da61c32917c3a0ef32b",
6
+ "fields": {
7
+ "ActivityDate": {
8
+ "displayValue": null,
9
+ "value": null
10
+ },
11
+ "Case__c": {
12
+ "displayValue": null,
13
+ "value": "500xx000000boDJAAY"
14
+ },
15
+ "Case__r": {
16
+ "displayValue": "00001027",
17
+ "value": {
18
+ "apiName": "Case",
19
+ "childRelationships": {},
20
+ "eTag": "d1912a07365b1f4f276cc2b60f857107",
21
+ "fields": {
22
+ "CaseNumber": {
23
+ "displayValue": null,
24
+ "value": "00001027"
25
+ },
26
+ "Id": {
27
+ "displayValue": null,
28
+ "value": "500xx000000boDJAAY"
29
+ }
30
+ },
31
+ "id": "500xx000000boDJAAY",
32
+ "lastModifiedById": "005xx000001X8gHAAS",
33
+ "lastModifiedDate": "2026-04-13T20:54:41.000Z",
34
+ "recordTypeId": "012000000000000AAA",
35
+ "recordTypeInfo": null,
36
+ "systemModstamp": "2026-04-13T20:54:41.000Z",
37
+ "weakEtag": 1776113681000
38
+ }
39
+ },
40
+ "CreatedBy": {
41
+ "displayValue": "Ethan Chan",
42
+ "value": {
43
+ "apiName": "User",
44
+ "childRelationships": {},
45
+ "eTag": "2ca65e8b3117284d9253195c82c5f03d",
46
+ "fields": {
47
+ "FirstName": {
48
+ "displayValue": null,
49
+ "value": "Ethan"
50
+ },
51
+ "Id": {
52
+ "displayValue": null,
53
+ "value": "005xx000001X8gHAAS"
54
+ },
55
+ "LastName": {
56
+ "displayValue": null,
57
+ "value": "Chan"
58
+ },
59
+ "Name": {
60
+ "displayValue": null,
61
+ "value": "Ethan Chan"
62
+ }
63
+ },
64
+ "id": "005xx000001X8gHAAS",
65
+ "lastModifiedById": "005xx000001X8gHAAS",
66
+ "lastModifiedDate": "2026-04-13T19:07:57.000Z",
67
+ "recordTypeId": null,
68
+ "recordTypeInfo": null,
69
+ "systemModstamp": "2026-04-13T19:07:57.000Z",
70
+ "weakEtag": 1776107277000
71
+ }
72
+ },
73
+ "CreatedById": {
74
+ "displayValue": null,
75
+ "value": "005xx000001X8gHAAS"
76
+ },
77
+ "CreatedDate": {
78
+ "displayValue": "4/13/2026, 12:09 PM",
79
+ "value": "2026-04-13T19:09:48.000Z"
80
+ },
81
+ "Description": {
82
+ "displayValue": null,
83
+ "value": null
84
+ },
85
+ "Id": {
86
+ "displayValue": null,
87
+ "value": "00Txx000003rIcmEAE"
88
+ },
89
+ "IsClosed": {
90
+ "displayValue": null,
91
+ "value": true
92
+ },
93
+ "LastModifiedBy": {
94
+ "displayValue": "Ethan Chan",
95
+ "value": {
96
+ "apiName": "User",
97
+ "childRelationships": {},
98
+ "eTag": "2ca65e8b3117284d9253195c82c5f03d",
99
+ "fields": {
100
+ "FirstName": {
101
+ "displayValue": null,
102
+ "value": "Ethan"
103
+ },
104
+ "Id": {
105
+ "displayValue": null,
106
+ "value": "005xx000001X8gHAAS"
107
+ },
108
+ "LastName": {
109
+ "displayValue": null,
110
+ "value": "Chan"
111
+ },
112
+ "Name": {
113
+ "displayValue": null,
114
+ "value": "Ethan Chan"
115
+ }
116
+ },
117
+ "id": "005xx000001X8gHAAS",
118
+ "lastModifiedById": "005xx000001X8gHAAS",
119
+ "lastModifiedDate": "2026-04-13T19:07:57.000Z",
120
+ "recordTypeId": null,
121
+ "recordTypeInfo": null,
122
+ "systemModstamp": "2026-04-13T19:07:57.000Z",
123
+ "weakEtag": 1776107277000
124
+ }
125
+ },
126
+ "LastModifiedById": {
127
+ "displayValue": null,
128
+ "value": "005xx000001X8gHAAS"
129
+ },
130
+ "LastModifiedDate": {
131
+ "displayValue": "4/13/2026, 1:54 PM",
132
+ "value": "2026-04-13T20:54:41.000Z"
133
+ },
134
+ "Owner": {
135
+ "displayValue": "Ethan Chan",
136
+ "value": {
137
+ "apiName": "Name",
138
+ "childRelationships": {},
139
+ "eTag": "202a115a07830e8af0343368d4d309d4",
140
+ "fields": {
141
+ "FirstName": {
142
+ "displayValue": null,
143
+ "value": "Ethan"
144
+ },
145
+ "Id": {
146
+ "displayValue": null,
147
+ "value": "005xx000001X8gHAAS"
148
+ },
149
+ "LastName": {
150
+ "displayValue": null,
151
+ "value": "Chan"
152
+ },
153
+ "Name": {
154
+ "displayValue": null,
155
+ "value": "Ethan Chan"
156
+ }
157
+ },
158
+ "id": "005xx000001X8gHAAS",
159
+ "lastModifiedById": null,
160
+ "lastModifiedDate": null,
161
+ "recordTypeId": null,
162
+ "recordTypeInfo": null,
163
+ "systemModstamp": null,
164
+ "weakEtag": 0
165
+ }
166
+ },
167
+ "OwnerId": {
168
+ "displayValue": null,
169
+ "value": "005xx000001X8gHAAS"
170
+ },
171
+ "Priority": {
172
+ "displayValue": "High",
173
+ "value": "High"
174
+ },
175
+ "Status": {
176
+ "displayValue": "Completed",
177
+ "value": "Completed"
178
+ },
179
+ "Subject": {
180
+ "displayValue": null,
181
+ "value": "Call"
182
+ },
183
+ "SystemModstamp": {
184
+ "displayValue": "4/13/2026, 1:54 PM",
185
+ "value": "2026-04-13T20:54:41.000Z"
186
+ },
187
+ "What": {
188
+ "displayValue": "00001027",
189
+ "value": {
190
+ "apiName": "Name",
191
+ "childRelationships": {},
192
+ "eTag": "deffd76450e8f3c8fc116a1cb6a0bb6b",
193
+ "fields": {
194
+ "Id": {
195
+ "displayValue": null,
196
+ "value": "500xx000000boDJAAY"
197
+ },
198
+ "Name": {
199
+ "displayValue": null,
200
+ "value": "00001027"
201
+ }
202
+ },
203
+ "id": "500xx000000boDJAAY",
204
+ "lastModifiedById": null,
205
+ "lastModifiedDate": null,
206
+ "recordTypeId": null,
207
+ "recordTypeInfo": null,
208
+ "systemModstamp": null,
209
+ "weakEtag": 0
210
+ }
211
+ },
212
+ "WhatId": {
213
+ "displayValue": null,
214
+ "value": "500xx000000boDJAAY"
215
+ },
216
+ "Who": {
217
+ "displayValue": null,
218
+ "value": null
219
+ },
220
+ "WhoId": {
221
+ "displayValue": null,
222
+ "value": null
223
+ }
224
+ },
225
+ "id": "00Txx000003rIcmEAE",
226
+ "lastModifiedById": "005xx000001X8gHAAS",
227
+ "lastModifiedDate": "2026-04-13T20:54:41.000Z",
228
+ "recordTypeId": "012000000000000AAA",
229
+ "recordTypeInfo": null,
230
+ "systemModstamp": "2026-04-13T20:54:41.000Z",
231
+ "weakEtag": 1776113681000
232
+ }
233
+ ]
@@ -0,0 +1,233 @@
1
+ [
2
+ {
3
+ "apiName": "Task",
4
+ "childRelationships": {},
5
+ "eTag": "e339e322e2906b92f0faa82d0b0987e2",
6
+ "fields": {
7
+ "ActivityDate": {
8
+ "displayValue": null,
9
+ "value": null
10
+ },
11
+ "Case__c": {
12
+ "displayValue": null,
13
+ "value": "500xx000000boDJAAY"
14
+ },
15
+ "Case__r": {
16
+ "displayValue": "00001027",
17
+ "value": {
18
+ "apiName": "Case",
19
+ "childRelationships": {},
20
+ "eTag": "1e500759421709c0bff030ea20a7485d",
21
+ "fields": {
22
+ "CaseNumber": {
23
+ "displayValue": null,
24
+ "value": "00001027"
25
+ },
26
+ "Id": {
27
+ "displayValue": null,
28
+ "value": "500xx000000boDJAAY"
29
+ }
30
+ },
31
+ "id": "500xx000000boDJAAY",
32
+ "lastModifiedById": null,
33
+ "lastModifiedDate": null,
34
+ "recordTypeId": "012000000000000AAA",
35
+ "recordTypeInfo": null,
36
+ "systemModstamp": null,
37
+ "weakEtag": 0
38
+ }
39
+ },
40
+ "CreatedBy": {
41
+ "displayValue": "Ethan Chan",
42
+ "value": {
43
+ "apiName": "User",
44
+ "childRelationships": {},
45
+ "eTag": "6209fb69d2a4b5c09799b1bd5f93bcca",
46
+ "fields": {
47
+ "FirstName": {
48
+ "displayValue": null,
49
+ "value": "Ethan"
50
+ },
51
+ "Id": {
52
+ "displayValue": null,
53
+ "value": "005xx000001X8gHAAS"
54
+ },
55
+ "LastName": {
56
+ "displayValue": null,
57
+ "value": "Chan"
58
+ },
59
+ "Name": {
60
+ "displayValue": null,
61
+ "value": "Ethan Chan"
62
+ }
63
+ },
64
+ "id": "005xx000001X8gHAAS",
65
+ "lastModifiedById": null,
66
+ "lastModifiedDate": null,
67
+ "recordTypeId": null,
68
+ "recordTypeInfo": null,
69
+ "systemModstamp": null,
70
+ "weakEtag": 0
71
+ }
72
+ },
73
+ "CreatedById": {
74
+ "displayValue": null,
75
+ "value": "005xx000001X8gHAAS"
76
+ },
77
+ "CreatedDate": {
78
+ "displayValue": "4/13/2026, 12:09 PM",
79
+ "value": "2026-04-13T19:09:48.000Z"
80
+ },
81
+ "Description": {
82
+ "displayValue": null,
83
+ "value": null
84
+ },
85
+ "Id": {
86
+ "displayValue": null,
87
+ "value": "00Txx000003rIcmEAE"
88
+ },
89
+ "IsClosed": {
90
+ "displayValue": null,
91
+ "value": true
92
+ },
93
+ "LastModifiedBy": {
94
+ "displayValue": "Ethan Chan",
95
+ "value": {
96
+ "apiName": "User",
97
+ "childRelationships": {},
98
+ "eTag": "6209fb69d2a4b5c09799b1bd5f93bcca",
99
+ "fields": {
100
+ "FirstName": {
101
+ "displayValue": null,
102
+ "value": "Ethan"
103
+ },
104
+ "Id": {
105
+ "displayValue": null,
106
+ "value": "005xx000001X8gHAAS"
107
+ },
108
+ "LastName": {
109
+ "displayValue": null,
110
+ "value": "Chan"
111
+ },
112
+ "Name": {
113
+ "displayValue": null,
114
+ "value": "Ethan Chan"
115
+ }
116
+ },
117
+ "id": "005xx000001X8gHAAS",
118
+ "lastModifiedById": null,
119
+ "lastModifiedDate": null,
120
+ "recordTypeId": null,
121
+ "recordTypeInfo": null,
122
+ "systemModstamp": null,
123
+ "weakEtag": 0
124
+ }
125
+ },
126
+ "LastModifiedById": {
127
+ "displayValue": null,
128
+ "value": "005xx000001X8gHAAS"
129
+ },
130
+ "LastModifiedDate": {
131
+ "displayValue": "4/13/2026, 1:54 PM",
132
+ "value": "2026-04-13T20:54:41.000Z"
133
+ },
134
+ "Owner": {
135
+ "displayValue": "Ethan Chan",
136
+ "value": {
137
+ "apiName": "Name",
138
+ "childRelationships": {},
139
+ "eTag": "202a115a07830e8af0343368d4d309d4",
140
+ "fields": {
141
+ "FirstName": {
142
+ "displayValue": null,
143
+ "value": "Ethan"
144
+ },
145
+ "Id": {
146
+ "displayValue": null,
147
+ "value": "005xx000001X8gHAAS"
148
+ },
149
+ "LastName": {
150
+ "displayValue": null,
151
+ "value": "Chan"
152
+ },
153
+ "Name": {
154
+ "displayValue": null,
155
+ "value": "Ethan Chan"
156
+ }
157
+ },
158
+ "id": "005xx000001X8gHAAS",
159
+ "lastModifiedById": null,
160
+ "lastModifiedDate": null,
161
+ "recordTypeId": null,
162
+ "recordTypeInfo": null,
163
+ "systemModstamp": null,
164
+ "weakEtag": 0
165
+ }
166
+ },
167
+ "OwnerId": {
168
+ "displayValue": null,
169
+ "value": "005xx000001X8gHAAS"
170
+ },
171
+ "Priority": {
172
+ "displayValue": "High",
173
+ "value": "High"
174
+ },
175
+ "Status": {
176
+ "displayValue": "Completed",
177
+ "value": "Completed"
178
+ },
179
+ "Subject": {
180
+ "displayValue": null,
181
+ "value": "Call"
182
+ },
183
+ "SystemModstamp": {
184
+ "displayValue": "4/13/2026, 1:54 PM",
185
+ "value": "2026-04-13T20:54:41.000Z"
186
+ },
187
+ "What": {
188
+ "displayValue": "00001027",
189
+ "value": {
190
+ "apiName": "Name",
191
+ "childRelationships": {},
192
+ "eTag": "deffd76450e8f3c8fc116a1cb6a0bb6b",
193
+ "fields": {
194
+ "Id": {
195
+ "displayValue": null,
196
+ "value": "500xx000000boDJAAY"
197
+ },
198
+ "Name": {
199
+ "displayValue": null,
200
+ "value": "00001027"
201
+ }
202
+ },
203
+ "id": "500xx000000boDJAAY",
204
+ "lastModifiedById": null,
205
+ "lastModifiedDate": null,
206
+ "recordTypeId": null,
207
+ "recordTypeInfo": null,
208
+ "systemModstamp": null,
209
+ "weakEtag": 0
210
+ }
211
+ },
212
+ "WhatId": {
213
+ "displayValue": null,
214
+ "value": "500xx000000boDJAAY"
215
+ },
216
+ "Who": {
217
+ "displayValue": null,
218
+ "value": null
219
+ },
220
+ "WhoId": {
221
+ "displayValue": null,
222
+ "value": null
223
+ }
224
+ },
225
+ "id": "00Txx000003rIcmEAE",
226
+ "lastModifiedById": "005xx000001X8gHAAS",
227
+ "lastModifiedDate": "2026-04-13T20:54:41.000Z",
228
+ "recordTypeId": "012000000000000AAA",
229
+ "recordTypeInfo": null,
230
+ "systemModstamp": "2026-04-13T20:54:41.000Z",
231
+ "weakEtag": 1776113681000
232
+ }
233
+ ]
package/src/ads-bridge.ts CHANGED
@@ -107,6 +107,10 @@ function isStoreKeyRecordId(key: string) {
107
107
  return key.indexOf(RECORD_ID_PREFIX) > -1 && key.indexOf(RECORD_FIELDS_KEY_JUNCTION) === -1;
108
108
  }
109
109
 
110
+ function isStoreKeyRecordField(key: string) {
111
+ return key.indexOf(RECORD_ID_PREFIX) > -1 && key.indexOf(RECORD_FIELDS_KEY_JUNCTION) > -1;
112
+ }
113
+
110
114
  /**
111
115
  * Returns a shallow copy of a record with its field values if it is a scalar and a reference and a
112
116
  * a RecordRepresentation with no field if the value if a spanning record.
@@ -488,6 +492,37 @@ export default class AdsBridge {
488
492
  }
489
493
  }
490
494
 
495
+ private filterAndSynthesizeBaseIds(updatedEntries: { id: string }[]): { id: string }[] {
496
+ // Collect base record IDs that are directly present in the entries.
497
+ const directBaseIds = new Set<string>();
498
+ for (let i = 0; i < updatedEntries.length; i++) {
499
+ if (isStoreKeyRecordId(updatedEntries[i].id)) {
500
+ directBaseIds.add(updatedEntries[i].id);
501
+ }
502
+ }
503
+
504
+ // For field entries whose base record ID has no direct entry, synthesize one.
505
+ const syntheticBaseIds = new Set<string>();
506
+ for (let i = 0; i < updatedEntries.length; i++) {
507
+ if (isStoreKeyRecordField(updatedEntries[i].id)) {
508
+ const baseId = updatedEntries[i].id.split(RECORD_FIELDS_KEY_JUNCTION)[0];
509
+ if (!directBaseIds.has(baseId)) {
510
+ syntheticBaseIds.add(baseId);
511
+ }
512
+ }
513
+ }
514
+ // Exclude all the store record ids not matching with the record id pattern.
515
+ // Note: FieldValueRepresentation have the same prefix than RecordRepresentation so we
516
+ // need to filter them out.
517
+ const filteredUpdatedEntries: { id: string }[] = updatedEntries.filter((entry) =>
518
+ isStoreKeyRecordId(entry.id)
519
+ );
520
+ syntheticBaseIds.forEach((baseId) => {
521
+ ArrayPrototypePush.call(filteredUpdatedEntries, { id: baseId });
522
+ });
523
+ return filteredUpdatedEntries;
524
+ }
525
+
491
526
  /**
492
527
  * This method retrieves queries the store with with passed record ids to retrieve their
493
528
  * associated records and object info. Note that the passed ids are not Salesforce record id
@@ -504,16 +539,10 @@ export default class AdsBridge {
504
539
  const adsRecordMap: AdsRecordMap = {};
505
540
  const adsObjectMap: AdsObjectMetadataMap = {};
506
541
 
507
- for (let i = 0; i < updatedEntries.length; i++) {
508
- const storeRecordId = updatedEntries[i].id;
509
-
510
- // Exclude all the store record ids not matching with the record id pattern.
511
- // Note: FieldValueRepresentation have the same prefix than RecordRepresentation so we
512
- // need to filter them out.
513
- if (!isStoreKeyRecordId(storeRecordId)) {
514
- continue;
515
- }
516
-
542
+ // Context for change: W-21715343
543
+ const filteredUpdatedEntries = this.filterAndSynthesizeBaseIds(updatedEntries);
544
+ for (let i = 0; i < filteredUpdatedEntries.length; i++) {
545
+ const storeRecordId = filteredUpdatedEntries[i].id;
517
546
  const record =
518
547
  this.recordRepresentationIngestOverride !== undefined
519
548
  ? getShallowRecordDenormalized(luvio, storeRecordId)