@salesforce/lds-runtime-mobile 1.332.0-dev20 → 1.332.0-dev21
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/dist/main.js
CHANGED
|
@@ -52682,6 +52682,12 @@ function buildFieldUnionArray(existingRecord, incomingRecord, objectInfo) {
|
|
|
52682
52682
|
fieldUnion.push(`${fieldName}.Id`);
|
|
52683
52683
|
includesSpanningFields = true;
|
|
52684
52684
|
}
|
|
52685
|
+
else {
|
|
52686
|
+
// Field exists on record but not in object info.
|
|
52687
|
+
// Fall back to getRecords resolver in this case.
|
|
52688
|
+
fieldUnion.push(fieldName);
|
|
52689
|
+
includesSpanningFields = true;
|
|
52690
|
+
}
|
|
52685
52691
|
}
|
|
52686
52692
|
else {
|
|
52687
52693
|
fieldUnion.push(fieldName);
|
|
@@ -52909,6 +52915,7 @@ class ConflictPool {
|
|
|
52909
52915
|
|
|
52910
52916
|
const DEFAULT_BATCH_SIZE = 500;
|
|
52911
52917
|
const DEFAULT_CONCURRENCY = 6;
|
|
52918
|
+
const MAX_RETRY_COUNT = 2;
|
|
52912
52919
|
class PrimingSession extends EventEmitter {
|
|
52913
52920
|
constructor(config) {
|
|
52914
52921
|
super();
|
|
@@ -52920,6 +52927,7 @@ class PrimingSession extends EventEmitter {
|
|
|
52920
52927
|
this.ldsRecordRefresher = config.ldsRecordRefresher;
|
|
52921
52928
|
this.networkWorkerPool = new AsyncWorkerPool(this.concurrency);
|
|
52922
52929
|
this.conflictPool = new ConflictPool(config.store, this.objectInfoLoader);
|
|
52930
|
+
this.retryTracker = new Map();
|
|
52923
52931
|
}
|
|
52924
52932
|
// function that enqueues priming work
|
|
52925
52933
|
async enqueue(work) {
|
|
@@ -52938,6 +52946,9 @@ class PrimingSession extends EventEmitter {
|
|
|
52938
52946
|
unavailableTypes,
|
|
52939
52947
|
});
|
|
52940
52948
|
if (unavailableIds.length > 0) {
|
|
52949
|
+
for (const id of unavailableIds) {
|
|
52950
|
+
this.retryTracker.delete(id);
|
|
52951
|
+
}
|
|
52941
52952
|
this.emit('error', {
|
|
52942
52953
|
ids: unavailableIds,
|
|
52943
52954
|
code: 'precondition-error',
|
|
@@ -52962,6 +52973,9 @@ class PrimingSession extends EventEmitter {
|
|
|
52962
52973
|
.fetchRecordData(batch, abortController)
|
|
52963
52974
|
.then(async (results) => {
|
|
52964
52975
|
if (abortController.aborted) {
|
|
52976
|
+
for (const id of batch.ids) {
|
|
52977
|
+
this.retryTracker.delete(id);
|
|
52978
|
+
}
|
|
52965
52979
|
return;
|
|
52966
52980
|
}
|
|
52967
52981
|
this.emit('batch-fetched', {
|
|
@@ -52998,6 +53012,9 @@ class PrimingSession extends EventEmitter {
|
|
|
52998
53012
|
code: primingError,
|
|
52999
53013
|
message: `${result.messages.join(',')}`,
|
|
53000
53014
|
});
|
|
53015
|
+
for (const id of result.missingIds) {
|
|
53016
|
+
this.retryTracker.delete(id);
|
|
53017
|
+
}
|
|
53001
53018
|
return;
|
|
53002
53019
|
}
|
|
53003
53020
|
const { missingIds } = result;
|
|
@@ -53021,6 +53038,17 @@ class PrimingSession extends EventEmitter {
|
|
|
53021
53038
|
duration: Date.now() - beforeWrite,
|
|
53022
53039
|
});
|
|
53023
53040
|
if (abortController.aborted) {
|
|
53041
|
+
for (const id of written) {
|
|
53042
|
+
this.retryTracker.delete(id);
|
|
53043
|
+
}
|
|
53044
|
+
for (const id of conflicted) {
|
|
53045
|
+
this.retryTracker.delete(id);
|
|
53046
|
+
}
|
|
53047
|
+
for (const error of errors) {
|
|
53048
|
+
for (const id of error.ids) {
|
|
53049
|
+
this.retryTracker.delete(id);
|
|
53050
|
+
}
|
|
53051
|
+
}
|
|
53024
53052
|
return;
|
|
53025
53053
|
}
|
|
53026
53054
|
if (errors.length > 0) {
|
|
@@ -53030,11 +53058,17 @@ class PrimingSession extends EventEmitter {
|
|
|
53030
53058
|
code: 'unknown',
|
|
53031
53059
|
message: message,
|
|
53032
53060
|
});
|
|
53061
|
+
for (const id of ids) {
|
|
53062
|
+
this.retryTracker.delete(id);
|
|
53063
|
+
}
|
|
53033
53064
|
});
|
|
53034
53065
|
}
|
|
53035
53066
|
// now that the records are persisted, emit the primed event
|
|
53036
53067
|
if (written.length > 0) {
|
|
53037
53068
|
this.emit('primed', Array.from(written));
|
|
53069
|
+
for (const id of written) {
|
|
53070
|
+
this.retryTracker.delete(id);
|
|
53071
|
+
}
|
|
53038
53072
|
}
|
|
53039
53073
|
// if any records could not be written to the store because there were conflicts, handle the conflicts
|
|
53040
53074
|
if (conflicted.length > 0) {
|
|
@@ -53045,14 +53079,39 @@ class PrimingSession extends EventEmitter {
|
|
|
53045
53079
|
async handleWriteConflicts(records, conflicted, abortController) {
|
|
53046
53080
|
const result = await this.conflictPool.enqueueConflictedRecords(records.filter((x) => conflicted.includes(x.id)), abortController);
|
|
53047
53081
|
if (abortController.aborted) {
|
|
53082
|
+
for (const id of conflicted) {
|
|
53083
|
+
this.retryTracker.delete(id);
|
|
53084
|
+
}
|
|
53048
53085
|
return;
|
|
53049
53086
|
}
|
|
53050
|
-
if (
|
|
53087
|
+
if (keys$3(result.additionalWork.records).length > 0) {
|
|
53051
53088
|
this.emit('conflict', {
|
|
53052
53089
|
ids: Object.values(result.additionalWork.records).flatMap((record) => record.ids),
|
|
53053
53090
|
resolution: 'priming-refresh',
|
|
53054
53091
|
});
|
|
53055
|
-
|
|
53092
|
+
// we're re-enqueuing here, so apply retry limits which may change the batches
|
|
53093
|
+
let limitedResult = this.applyRetryLimits(result.additionalWork);
|
|
53094
|
+
this.enqueue(limitedResult.additionalWork);
|
|
53095
|
+
if (limitedResult.recordsNeedingRefetch.size > 0) {
|
|
53096
|
+
for (const key in keys$3(limitedResult.recordsNeedingRefetch)) {
|
|
53097
|
+
const value = limitedResult.recordsNeedingRefetch.get(key);
|
|
53098
|
+
if (result.recordsNeedingRefetch.has(key)) {
|
|
53099
|
+
let existing = result.recordsNeedingRefetch.get(key);
|
|
53100
|
+
existing = {
|
|
53101
|
+
// merge the ids
|
|
53102
|
+
ids: [...existing.ids, ...value.ids],
|
|
53103
|
+
// This is safe because they derive from the same
|
|
53104
|
+
// input, no chance of getting a new field in the
|
|
53105
|
+
// limited result
|
|
53106
|
+
fields: existing.fields,
|
|
53107
|
+
};
|
|
53108
|
+
result.recordsNeedingRefetch.set(key, existing);
|
|
53109
|
+
}
|
|
53110
|
+
else {
|
|
53111
|
+
result.recordsNeedingRefetch.set(key, value);
|
|
53112
|
+
}
|
|
53113
|
+
}
|
|
53114
|
+
}
|
|
53056
53115
|
}
|
|
53057
53116
|
if (result.resolvedRecords.length > 0) {
|
|
53058
53117
|
this.emit('conflict', {
|
|
@@ -53060,8 +53119,14 @@ class PrimingSession extends EventEmitter {
|
|
|
53060
53119
|
resolution: 'priming-merge',
|
|
53061
53120
|
});
|
|
53062
53121
|
this.emit('primed', result.resolvedRecords);
|
|
53122
|
+
for (const id of result.resolvedRecords) {
|
|
53123
|
+
this.retryTracker.delete(id);
|
|
53124
|
+
}
|
|
53063
53125
|
}
|
|
53064
53126
|
if (result.recordsToWrite.length > 0) {
|
|
53127
|
+
for (const record of result.recordsToWrite) {
|
|
53128
|
+
this.retryTracker.delete(record.id);
|
|
53129
|
+
}
|
|
53065
53130
|
const { written, errors, conflicted } = await this.recordIngestor.insertRecords(result.recordsToWrite, true);
|
|
53066
53131
|
if (written.length > 0) {
|
|
53067
53132
|
const ids = Array.from(written);
|
|
@@ -53088,10 +53153,16 @@ class PrimingSession extends EventEmitter {
|
|
|
53088
53153
|
if (result.recordsNeedingRefetch.size > 0) {
|
|
53089
53154
|
const { loaded, errored } = await this.ldsRecordRefresher.loadRecords(result.recordsNeedingRefetch);
|
|
53090
53155
|
if (loaded.length > 0) {
|
|
53156
|
+
for (const id of loaded) {
|
|
53157
|
+
this.retryTracker.delete(id);
|
|
53158
|
+
}
|
|
53091
53159
|
this.emit('conflict', { resolution: 'lds-refresh', ids: loaded });
|
|
53092
53160
|
this.emit('primed', loaded);
|
|
53093
53161
|
}
|
|
53094
53162
|
if (errored.length > 0) {
|
|
53163
|
+
for (const id of errored) {
|
|
53164
|
+
this.retryTracker.delete(id);
|
|
53165
|
+
}
|
|
53095
53166
|
this.emit('error', {
|
|
53096
53167
|
ids: errored,
|
|
53097
53168
|
code: 'unknown',
|
|
@@ -53100,6 +53171,50 @@ class PrimingSession extends EventEmitter {
|
|
|
53100
53171
|
}
|
|
53101
53172
|
}
|
|
53102
53173
|
}
|
|
53174
|
+
applyRetryLimits(primingWork) {
|
|
53175
|
+
// retryable work goes back into priming session
|
|
53176
|
+
let retryableWork = {
|
|
53177
|
+
type: 'record-fields',
|
|
53178
|
+
records: {},
|
|
53179
|
+
};
|
|
53180
|
+
// refetchable work gets delegated to getRecords
|
|
53181
|
+
let refetchableWork = new Map();
|
|
53182
|
+
for (const key of keys$3(primingWork.records)) {
|
|
53183
|
+
let work = primingWork.records[key];
|
|
53184
|
+
let limitedIds = [];
|
|
53185
|
+
for (const id of work.ids) {
|
|
53186
|
+
let retryCount = this.retryTracker.get(id) || 0;
|
|
53187
|
+
retryCount += 1;
|
|
53188
|
+
if (retryCount > MAX_RETRY_COUNT) {
|
|
53189
|
+
limitedIds.push(id);
|
|
53190
|
+
this.retryTracker.delete(id);
|
|
53191
|
+
}
|
|
53192
|
+
else {
|
|
53193
|
+
this.retryTracker.set(id, retryCount);
|
|
53194
|
+
}
|
|
53195
|
+
}
|
|
53196
|
+
if (limitedIds.length < work.ids.length) {
|
|
53197
|
+
retryableWork.records[key] = {
|
|
53198
|
+
ids: work.ids.filter((id) => limitedIds.indexOf(id) === -1),
|
|
53199
|
+
fields: work.fields,
|
|
53200
|
+
};
|
|
53201
|
+
}
|
|
53202
|
+
if (limitedIds.length > 0) {
|
|
53203
|
+
this.emit('retry-limit-reached', { ids: limitedIds });
|
|
53204
|
+
refetchableWork.set(key, {
|
|
53205
|
+
ids: limitedIds,
|
|
53206
|
+
fields: work.fields,
|
|
53207
|
+
});
|
|
53208
|
+
}
|
|
53209
|
+
}
|
|
53210
|
+
return {
|
|
53211
|
+
additionalWork: retryableWork,
|
|
53212
|
+
recordsNeedingRefetch: refetchableWork,
|
|
53213
|
+
resolvedRecords: [],
|
|
53214
|
+
recordsToWrite: [],
|
|
53215
|
+
errors: [],
|
|
53216
|
+
};
|
|
53217
|
+
}
|
|
53103
53218
|
async fetchMetadata(batches) {
|
|
53104
53219
|
const apiNames = Array.from(batches.reduce((acc, x) => {
|
|
53105
53220
|
return acc.add(x.type);
|
|
@@ -53338,7 +53453,9 @@ class RecordLoaderGraphQL extends NetworkRecordLoader {
|
|
|
53338
53453
|
return acc;
|
|
53339
53454
|
}, {});
|
|
53340
53455
|
fields['Id'] = { value: id, displayValue: null };
|
|
53341
|
-
fields['RecordTypeId']
|
|
53456
|
+
if (objectInfo.fields['RecordTypeId'] !== undefined) {
|
|
53457
|
+
fields['RecordTypeId'] = { value: recordTypeId, displayValue: null };
|
|
53458
|
+
}
|
|
53342
53459
|
let recordTypeInfo = null;
|
|
53343
53460
|
if (recordTypeId !== null &&
|
|
53344
53461
|
objectInfo.recordTypeInfos &&
|
|
@@ -55535,4 +55652,4 @@ register({
|
|
|
55535
55652
|
});
|
|
55536
55653
|
|
|
55537
55654
|
export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
55538
|
-
// version: 1.332.0-
|
|
55655
|
+
// version: 1.332.0-dev21-0ddc3ca21c
|
|
@@ -4,7 +4,7 @@ import type { PrimingStore } from './PrimingStore';
|
|
|
4
4
|
import type { PrimingWork } from './types';
|
|
5
5
|
import type { ObjectInfoLoader } from './ObjectInfoLoader';
|
|
6
6
|
type ConflictResolutionError = 'object-info-missing';
|
|
7
|
-
interface ConflictResolutionResult {
|
|
7
|
+
export interface ConflictResolutionResult {
|
|
8
8
|
additionalWork: PrimingWork;
|
|
9
9
|
recordsToWrite: DurableRecordRepresentation[];
|
|
10
10
|
resolvedRecords: string[];
|
|
@@ -36,6 +36,9 @@ export interface PrimingEvents {
|
|
|
36
36
|
errors: string[];
|
|
37
37
|
duration: number;
|
|
38
38
|
};
|
|
39
|
+
'retry-limit-reached': {
|
|
40
|
+
ids: string[];
|
|
41
|
+
};
|
|
39
42
|
}
|
|
40
43
|
interface EventErrorPayload {
|
|
41
44
|
ids: string[];
|
|
@@ -56,12 +59,14 @@ export declare class PrimingSession extends EventEmitter<PrimingEvents> {
|
|
|
56
59
|
private networkWorkerPool;
|
|
57
60
|
private conflictPool;
|
|
58
61
|
private ldsRecordRefresher;
|
|
62
|
+
private retryTracker;
|
|
59
63
|
constructor(config: PrimingSessionConfig);
|
|
60
64
|
enqueue(work: PrimingWork): Promise<void>;
|
|
61
65
|
cancel(): void;
|
|
62
66
|
private enqueueBatches;
|
|
63
67
|
private processFetchedRecords;
|
|
64
68
|
private handleWriteConflicts;
|
|
69
|
+
private applyRetryLimits;
|
|
65
70
|
private fetchMetadata;
|
|
66
71
|
}
|
|
67
72
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-runtime-mobile",
|
|
3
|
-
"version": "1.332.0-
|
|
3
|
+
"version": "1.332.0-dev21",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "LDS runtime for mobile/hybrid environments.",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -32,23 +32,23 @@
|
|
|
32
32
|
"release:corejar": "yarn build && ../core-build/scripts/core.js --name=lds-runtime-mobile"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@salesforce/lds-adapters-uiapi": "^1.332.0-
|
|
36
|
-
"@salesforce/lds-bindings": "^1.332.0-
|
|
37
|
-
"@salesforce/lds-instrumentation": "^1.332.0-
|
|
35
|
+
"@salesforce/lds-adapters-uiapi": "^1.332.0-dev21",
|
|
36
|
+
"@salesforce/lds-bindings": "^1.332.0-dev21",
|
|
37
|
+
"@salesforce/lds-instrumentation": "^1.332.0-dev21",
|
|
38
38
|
"@salesforce/user": "0.0.21",
|
|
39
39
|
"o11y": "250.7.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@salesforce/lds-adapters-graphql": "^1.332.0-
|
|
43
|
-
"@salesforce/lds-drafts": "^1.332.0-
|
|
44
|
-
"@salesforce/lds-durable-records": "^1.332.0-
|
|
45
|
-
"@salesforce/lds-network-adapter": "^1.332.0-
|
|
46
|
-
"@salesforce/lds-network-nimbus": "^1.332.0-
|
|
47
|
-
"@salesforce/lds-store-binary": "^1.332.0-
|
|
48
|
-
"@salesforce/lds-store-nimbus": "^1.332.0-
|
|
49
|
-
"@salesforce/lds-store-sql": "^1.332.0-
|
|
50
|
-
"@salesforce/lds-utils-adapters": "^1.332.0-
|
|
51
|
-
"@salesforce/nimbus-plugin-lds": "^1.332.0-
|
|
42
|
+
"@salesforce/lds-adapters-graphql": "^1.332.0-dev21",
|
|
43
|
+
"@salesforce/lds-drafts": "^1.332.0-dev21",
|
|
44
|
+
"@salesforce/lds-durable-records": "^1.332.0-dev21",
|
|
45
|
+
"@salesforce/lds-network-adapter": "^1.332.0-dev21",
|
|
46
|
+
"@salesforce/lds-network-nimbus": "^1.332.0-dev21",
|
|
47
|
+
"@salesforce/lds-store-binary": "^1.332.0-dev21",
|
|
48
|
+
"@salesforce/lds-store-nimbus": "^1.332.0-dev21",
|
|
49
|
+
"@salesforce/lds-store-sql": "^1.332.0-dev21",
|
|
50
|
+
"@salesforce/lds-utils-adapters": "^1.332.0-dev21",
|
|
51
|
+
"@salesforce/nimbus-plugin-lds": "^1.332.0-dev21",
|
|
52
52
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
53
53
|
"wait-for-expect": "^3.0.2"
|
|
54
54
|
},
|
package/sfdc/main.js
CHANGED
|
@@ -52682,6 +52682,12 @@ function buildFieldUnionArray(existingRecord, incomingRecord, objectInfo) {
|
|
|
52682
52682
|
fieldUnion.push(`${fieldName}.Id`);
|
|
52683
52683
|
includesSpanningFields = true;
|
|
52684
52684
|
}
|
|
52685
|
+
else {
|
|
52686
|
+
// Field exists on record but not in object info.
|
|
52687
|
+
// Fall back to getRecords resolver in this case.
|
|
52688
|
+
fieldUnion.push(fieldName);
|
|
52689
|
+
includesSpanningFields = true;
|
|
52690
|
+
}
|
|
52685
52691
|
}
|
|
52686
52692
|
else {
|
|
52687
52693
|
fieldUnion.push(fieldName);
|
|
@@ -52909,6 +52915,7 @@ class ConflictPool {
|
|
|
52909
52915
|
|
|
52910
52916
|
const DEFAULT_BATCH_SIZE = 500;
|
|
52911
52917
|
const DEFAULT_CONCURRENCY = 6;
|
|
52918
|
+
const MAX_RETRY_COUNT = 2;
|
|
52912
52919
|
class PrimingSession extends EventEmitter {
|
|
52913
52920
|
constructor(config) {
|
|
52914
52921
|
super();
|
|
@@ -52920,6 +52927,7 @@ class PrimingSession extends EventEmitter {
|
|
|
52920
52927
|
this.ldsRecordRefresher = config.ldsRecordRefresher;
|
|
52921
52928
|
this.networkWorkerPool = new AsyncWorkerPool(this.concurrency);
|
|
52922
52929
|
this.conflictPool = new ConflictPool(config.store, this.objectInfoLoader);
|
|
52930
|
+
this.retryTracker = new Map();
|
|
52923
52931
|
}
|
|
52924
52932
|
// function that enqueues priming work
|
|
52925
52933
|
async enqueue(work) {
|
|
@@ -52938,6 +52946,9 @@ class PrimingSession extends EventEmitter {
|
|
|
52938
52946
|
unavailableTypes,
|
|
52939
52947
|
});
|
|
52940
52948
|
if (unavailableIds.length > 0) {
|
|
52949
|
+
for (const id of unavailableIds) {
|
|
52950
|
+
this.retryTracker.delete(id);
|
|
52951
|
+
}
|
|
52941
52952
|
this.emit('error', {
|
|
52942
52953
|
ids: unavailableIds,
|
|
52943
52954
|
code: 'precondition-error',
|
|
@@ -52962,6 +52973,9 @@ class PrimingSession extends EventEmitter {
|
|
|
52962
52973
|
.fetchRecordData(batch, abortController)
|
|
52963
52974
|
.then(async (results) => {
|
|
52964
52975
|
if (abortController.aborted) {
|
|
52976
|
+
for (const id of batch.ids) {
|
|
52977
|
+
this.retryTracker.delete(id);
|
|
52978
|
+
}
|
|
52965
52979
|
return;
|
|
52966
52980
|
}
|
|
52967
52981
|
this.emit('batch-fetched', {
|
|
@@ -52998,6 +53012,9 @@ class PrimingSession extends EventEmitter {
|
|
|
52998
53012
|
code: primingError,
|
|
52999
53013
|
message: `${result.messages.join(',')}`,
|
|
53000
53014
|
});
|
|
53015
|
+
for (const id of result.missingIds) {
|
|
53016
|
+
this.retryTracker.delete(id);
|
|
53017
|
+
}
|
|
53001
53018
|
return;
|
|
53002
53019
|
}
|
|
53003
53020
|
const { missingIds } = result;
|
|
@@ -53021,6 +53038,17 @@ class PrimingSession extends EventEmitter {
|
|
|
53021
53038
|
duration: Date.now() - beforeWrite,
|
|
53022
53039
|
});
|
|
53023
53040
|
if (abortController.aborted) {
|
|
53041
|
+
for (const id of written) {
|
|
53042
|
+
this.retryTracker.delete(id);
|
|
53043
|
+
}
|
|
53044
|
+
for (const id of conflicted) {
|
|
53045
|
+
this.retryTracker.delete(id);
|
|
53046
|
+
}
|
|
53047
|
+
for (const error of errors) {
|
|
53048
|
+
for (const id of error.ids) {
|
|
53049
|
+
this.retryTracker.delete(id);
|
|
53050
|
+
}
|
|
53051
|
+
}
|
|
53024
53052
|
return;
|
|
53025
53053
|
}
|
|
53026
53054
|
if (errors.length > 0) {
|
|
@@ -53030,11 +53058,17 @@ class PrimingSession extends EventEmitter {
|
|
|
53030
53058
|
code: 'unknown',
|
|
53031
53059
|
message: message,
|
|
53032
53060
|
});
|
|
53061
|
+
for (const id of ids) {
|
|
53062
|
+
this.retryTracker.delete(id);
|
|
53063
|
+
}
|
|
53033
53064
|
});
|
|
53034
53065
|
}
|
|
53035
53066
|
// now that the records are persisted, emit the primed event
|
|
53036
53067
|
if (written.length > 0) {
|
|
53037
53068
|
this.emit('primed', Array.from(written));
|
|
53069
|
+
for (const id of written) {
|
|
53070
|
+
this.retryTracker.delete(id);
|
|
53071
|
+
}
|
|
53038
53072
|
}
|
|
53039
53073
|
// if any records could not be written to the store because there were conflicts, handle the conflicts
|
|
53040
53074
|
if (conflicted.length > 0) {
|
|
@@ -53045,14 +53079,39 @@ class PrimingSession extends EventEmitter {
|
|
|
53045
53079
|
async handleWriteConflicts(records, conflicted, abortController) {
|
|
53046
53080
|
const result = await this.conflictPool.enqueueConflictedRecords(records.filter((x) => conflicted.includes(x.id)), abortController);
|
|
53047
53081
|
if (abortController.aborted) {
|
|
53082
|
+
for (const id of conflicted) {
|
|
53083
|
+
this.retryTracker.delete(id);
|
|
53084
|
+
}
|
|
53048
53085
|
return;
|
|
53049
53086
|
}
|
|
53050
|
-
if (
|
|
53087
|
+
if (keys$3(result.additionalWork.records).length > 0) {
|
|
53051
53088
|
this.emit('conflict', {
|
|
53052
53089
|
ids: Object.values(result.additionalWork.records).flatMap((record) => record.ids),
|
|
53053
53090
|
resolution: 'priming-refresh',
|
|
53054
53091
|
});
|
|
53055
|
-
|
|
53092
|
+
// we're re-enqueuing here, so apply retry limits which may change the batches
|
|
53093
|
+
let limitedResult = this.applyRetryLimits(result.additionalWork);
|
|
53094
|
+
this.enqueue(limitedResult.additionalWork);
|
|
53095
|
+
if (limitedResult.recordsNeedingRefetch.size > 0) {
|
|
53096
|
+
for (const key in keys$3(limitedResult.recordsNeedingRefetch)) {
|
|
53097
|
+
const value = limitedResult.recordsNeedingRefetch.get(key);
|
|
53098
|
+
if (result.recordsNeedingRefetch.has(key)) {
|
|
53099
|
+
let existing = result.recordsNeedingRefetch.get(key);
|
|
53100
|
+
existing = {
|
|
53101
|
+
// merge the ids
|
|
53102
|
+
ids: [...existing.ids, ...value.ids],
|
|
53103
|
+
// This is safe because they derive from the same
|
|
53104
|
+
// input, no chance of getting a new field in the
|
|
53105
|
+
// limited result
|
|
53106
|
+
fields: existing.fields,
|
|
53107
|
+
};
|
|
53108
|
+
result.recordsNeedingRefetch.set(key, existing);
|
|
53109
|
+
}
|
|
53110
|
+
else {
|
|
53111
|
+
result.recordsNeedingRefetch.set(key, value);
|
|
53112
|
+
}
|
|
53113
|
+
}
|
|
53114
|
+
}
|
|
53056
53115
|
}
|
|
53057
53116
|
if (result.resolvedRecords.length > 0) {
|
|
53058
53117
|
this.emit('conflict', {
|
|
@@ -53060,8 +53119,14 @@ class PrimingSession extends EventEmitter {
|
|
|
53060
53119
|
resolution: 'priming-merge',
|
|
53061
53120
|
});
|
|
53062
53121
|
this.emit('primed', result.resolvedRecords);
|
|
53122
|
+
for (const id of result.resolvedRecords) {
|
|
53123
|
+
this.retryTracker.delete(id);
|
|
53124
|
+
}
|
|
53063
53125
|
}
|
|
53064
53126
|
if (result.recordsToWrite.length > 0) {
|
|
53127
|
+
for (const record of result.recordsToWrite) {
|
|
53128
|
+
this.retryTracker.delete(record.id);
|
|
53129
|
+
}
|
|
53065
53130
|
const { written, errors, conflicted } = await this.recordIngestor.insertRecords(result.recordsToWrite, true);
|
|
53066
53131
|
if (written.length > 0) {
|
|
53067
53132
|
const ids = Array.from(written);
|
|
@@ -53088,10 +53153,16 @@ class PrimingSession extends EventEmitter {
|
|
|
53088
53153
|
if (result.recordsNeedingRefetch.size > 0) {
|
|
53089
53154
|
const { loaded, errored } = await this.ldsRecordRefresher.loadRecords(result.recordsNeedingRefetch);
|
|
53090
53155
|
if (loaded.length > 0) {
|
|
53156
|
+
for (const id of loaded) {
|
|
53157
|
+
this.retryTracker.delete(id);
|
|
53158
|
+
}
|
|
53091
53159
|
this.emit('conflict', { resolution: 'lds-refresh', ids: loaded });
|
|
53092
53160
|
this.emit('primed', loaded);
|
|
53093
53161
|
}
|
|
53094
53162
|
if (errored.length > 0) {
|
|
53163
|
+
for (const id of errored) {
|
|
53164
|
+
this.retryTracker.delete(id);
|
|
53165
|
+
}
|
|
53095
53166
|
this.emit('error', {
|
|
53096
53167
|
ids: errored,
|
|
53097
53168
|
code: 'unknown',
|
|
@@ -53100,6 +53171,50 @@ class PrimingSession extends EventEmitter {
|
|
|
53100
53171
|
}
|
|
53101
53172
|
}
|
|
53102
53173
|
}
|
|
53174
|
+
applyRetryLimits(primingWork) {
|
|
53175
|
+
// retryable work goes back into priming session
|
|
53176
|
+
let retryableWork = {
|
|
53177
|
+
type: 'record-fields',
|
|
53178
|
+
records: {},
|
|
53179
|
+
};
|
|
53180
|
+
// refetchable work gets delegated to getRecords
|
|
53181
|
+
let refetchableWork = new Map();
|
|
53182
|
+
for (const key of keys$3(primingWork.records)) {
|
|
53183
|
+
let work = primingWork.records[key];
|
|
53184
|
+
let limitedIds = [];
|
|
53185
|
+
for (const id of work.ids) {
|
|
53186
|
+
let retryCount = this.retryTracker.get(id) || 0;
|
|
53187
|
+
retryCount += 1;
|
|
53188
|
+
if (retryCount > MAX_RETRY_COUNT) {
|
|
53189
|
+
limitedIds.push(id);
|
|
53190
|
+
this.retryTracker.delete(id);
|
|
53191
|
+
}
|
|
53192
|
+
else {
|
|
53193
|
+
this.retryTracker.set(id, retryCount);
|
|
53194
|
+
}
|
|
53195
|
+
}
|
|
53196
|
+
if (limitedIds.length < work.ids.length) {
|
|
53197
|
+
retryableWork.records[key] = {
|
|
53198
|
+
ids: work.ids.filter((id) => limitedIds.indexOf(id) === -1),
|
|
53199
|
+
fields: work.fields,
|
|
53200
|
+
};
|
|
53201
|
+
}
|
|
53202
|
+
if (limitedIds.length > 0) {
|
|
53203
|
+
this.emit('retry-limit-reached', { ids: limitedIds });
|
|
53204
|
+
refetchableWork.set(key, {
|
|
53205
|
+
ids: limitedIds,
|
|
53206
|
+
fields: work.fields,
|
|
53207
|
+
});
|
|
53208
|
+
}
|
|
53209
|
+
}
|
|
53210
|
+
return {
|
|
53211
|
+
additionalWork: retryableWork,
|
|
53212
|
+
recordsNeedingRefetch: refetchableWork,
|
|
53213
|
+
resolvedRecords: [],
|
|
53214
|
+
recordsToWrite: [],
|
|
53215
|
+
errors: [],
|
|
53216
|
+
};
|
|
53217
|
+
}
|
|
53103
53218
|
async fetchMetadata(batches) {
|
|
53104
53219
|
const apiNames = Array.from(batches.reduce((acc, x) => {
|
|
53105
53220
|
return acc.add(x.type);
|
|
@@ -53338,7 +53453,9 @@ class RecordLoaderGraphQL extends NetworkRecordLoader {
|
|
|
53338
53453
|
return acc;
|
|
53339
53454
|
}, {});
|
|
53340
53455
|
fields['Id'] = { value: id, displayValue: null };
|
|
53341
|
-
fields['RecordTypeId']
|
|
53456
|
+
if (objectInfo.fields['RecordTypeId'] !== undefined) {
|
|
53457
|
+
fields['RecordTypeId'] = { value: recordTypeId, displayValue: null };
|
|
53458
|
+
}
|
|
53342
53459
|
let recordTypeInfo = null;
|
|
53343
53460
|
if (recordTypeId !== null &&
|
|
53344
53461
|
objectInfo.recordTypeInfos &&
|
|
@@ -55535,4 +55652,4 @@ register({
|
|
|
55535
55652
|
});
|
|
55536
55653
|
|
|
55537
55654
|
export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
55538
|
-
// version: 1.332.0-
|
|
55655
|
+
// version: 1.332.0-dev21-0ddc3ca21c
|
|
@@ -4,7 +4,7 @@ import type { PrimingStore } from './PrimingStore';
|
|
|
4
4
|
import type { PrimingWork } from './types';
|
|
5
5
|
import type { ObjectInfoLoader } from './ObjectInfoLoader';
|
|
6
6
|
type ConflictResolutionError = 'object-info-missing';
|
|
7
|
-
interface ConflictResolutionResult {
|
|
7
|
+
export interface ConflictResolutionResult {
|
|
8
8
|
additionalWork: PrimingWork;
|
|
9
9
|
recordsToWrite: DurableRecordRepresentation[];
|
|
10
10
|
resolvedRecords: string[];
|
|
@@ -36,6 +36,9 @@ export interface PrimingEvents {
|
|
|
36
36
|
errors: string[];
|
|
37
37
|
duration: number;
|
|
38
38
|
};
|
|
39
|
+
'retry-limit-reached': {
|
|
40
|
+
ids: string[];
|
|
41
|
+
};
|
|
39
42
|
}
|
|
40
43
|
interface EventErrorPayload {
|
|
41
44
|
ids: string[];
|
|
@@ -56,12 +59,14 @@ export declare class PrimingSession extends EventEmitter<PrimingEvents> {
|
|
|
56
59
|
private networkWorkerPool;
|
|
57
60
|
private conflictPool;
|
|
58
61
|
private ldsRecordRefresher;
|
|
62
|
+
private retryTracker;
|
|
59
63
|
constructor(config: PrimingSessionConfig);
|
|
60
64
|
enqueue(work: PrimingWork): Promise<void>;
|
|
61
65
|
cancel(): void;
|
|
62
66
|
private enqueueBatches;
|
|
63
67
|
private processFetchedRecords;
|
|
64
68
|
private handleWriteConflicts;
|
|
69
|
+
private applyRetryLimits;
|
|
65
70
|
private fetchMetadata;
|
|
66
71
|
}
|
|
67
72
|
export {};
|