@salesforce/lds-runtime-mobile 1.247.0 → 1.249.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.
- package/dist/main.js +437 -217
- package/dist/types/priming/SqlitePrimingStore.d.ts +0 -5
- package/dist/types/utils/ObjectInfoService.d.ts +5 -0
- package/package.json +1 -1
- package/sfdc/main.js +437 -217
- package/sfdc/types/priming/SqlitePrimingStore.d.ts +0 -5
- package/sfdc/types/utils/ObjectInfoService.d.ts +5 -0
package/dist/main.js
CHANGED
|
@@ -15,8 +15,9 @@ import { withRegistration, register } from '@salesforce/lds-default-luvio';
|
|
|
15
15
|
import { setupInstrumentation, instrumentAdapter as instrumentAdapter$1, instrumentLuvio, setLdsAdaptersUiapiInstrumentation, setLdsNetworkAdapterInstrumentation } from '@salesforce/lds-instrumentation';
|
|
16
16
|
import { HttpStatusCode, StoreKeySet, serializeStructuredKey, StringKeyInMemoryStore, Reader, deepFreeze, emitAdapterEvent, createCustomAdapterEventEmitter, StoreKeyMap, isFileReference, Environment, Luvio, InMemoryStore } from '@luvio/engine';
|
|
17
17
|
import excludeStaleRecordsGate from '@salesforce/gate/lds.graphqlEvalExcludeStaleRecords';
|
|
18
|
-
import { parseAndVisit, Kind, visit, execute,
|
|
19
|
-
import { RECORD_ID_PREFIX, RECORD_FIELDS_KEY_JUNCTION, isStoreKeyRecordViewEntity, getRecordId18, RECORD_REPRESENTATION_NAME, extractRecordIdFromStoreKey, keyBuilderQuickActionExecutionRepresentation, ingestQuickActionExecutionRepresentation, keyBuilderContentDocumentCompositeRepresentation, getResponseCacheKeysContentDocumentCompositeRepresentation, keyBuilderFromTypeContentDocumentCompositeRepresentation, ingestContentDocumentCompositeRepresentation, keyBuilderRecord, RECORD_VIEW_ENTITY_ID_PREFIX, getTypeCacheKeysRecord, keyBuilderFromTypeRecordRepresentation, ingestRecord, RecordRepresentationRepresentationType, ObjectInfoRepresentationType, getRecordAdapterFactory, getObjectInfoAdapterFactory, getObjectInfosAdapterFactory, getObjectInfoDirectoryAdapterFactory, UiApiNamespace, RecordRepresentationType, RecordRepresentationTTL, RecordRepresentationVersion,
|
|
18
|
+
import { parseAndVisit, Kind, buildSchema, isObjectType, defaultFieldResolver, visit, execute, parse as parse$7, extendSchema, isScalarType } from '@luvio/graphql-parser';
|
|
19
|
+
import { RECORD_ID_PREFIX, RECORD_FIELDS_KEY_JUNCTION, isStoreKeyRecordViewEntity, getRecordId18, RECORD_REPRESENTATION_NAME, extractRecordIdFromStoreKey, keyBuilderQuickActionExecutionRepresentation, ingestQuickActionExecutionRepresentation, keyBuilderContentDocumentCompositeRepresentation, getResponseCacheKeysContentDocumentCompositeRepresentation, keyBuilderFromTypeContentDocumentCompositeRepresentation, ingestContentDocumentCompositeRepresentation, keyBuilderRecord, RECORD_VIEW_ENTITY_ID_PREFIX, getTypeCacheKeysRecord, keyBuilderFromTypeRecordRepresentation, ingestRecord, RecordRepresentationRepresentationType, ObjectInfoRepresentationType, getRecordAdapterFactory, getObjectInfoAdapterFactory, getObjectInfosAdapterFactory, getObjectInfoDirectoryAdapterFactory, UiApiNamespace, RecordRepresentationType, RecordRepresentationTTL, RecordRepresentationVersion, getRecordsAdapterFactory } from '@salesforce/lds-adapters-uiapi';
|
|
20
|
+
import ldsIdempotencyWriteDisabled from '@salesforce/gate/lds.idempotencyWriteDisabled';
|
|
20
21
|
import caseSensitiveUserId from '@salesforce/user/Id';
|
|
21
22
|
import { idleDetector, getInstrumentation } from 'o11y/client';
|
|
22
23
|
import ldsUseShortUrlGate from '@salesforce/gate/lds.useShortUrl';
|
|
@@ -1237,12 +1238,12 @@ function makeDurable(environment, { durableStore, instrumentation, useRevivingSt
|
|
|
1237
1238
|
}
|
|
1238
1239
|
return environment.getNode(key, stagingStore);
|
|
1239
1240
|
};
|
|
1240
|
-
const wrapNormalizedGraphNode = function (normalized) {
|
|
1241
|
+
const wrapNormalizedGraphNode = function (normalized, key) {
|
|
1241
1242
|
validateNotDisposed();
|
|
1242
1243
|
if (stagingStore === null) {
|
|
1243
1244
|
stagingStore = buildIngestStagingStore(environment);
|
|
1244
1245
|
}
|
|
1245
|
-
return environment.wrapNormalizedGraphNode(normalized, stagingStore);
|
|
1246
|
+
return environment.wrapNormalizedGraphNode(normalized, key, stagingStore);
|
|
1246
1247
|
};
|
|
1247
1248
|
const rebuildSnapshot = function (snapshot, onRebuild) {
|
|
1248
1249
|
validateNotDisposed();
|
|
@@ -4950,6 +4951,21 @@ class AsyncWorkerPool {
|
|
|
4950
4951
|
}
|
|
4951
4952
|
}
|
|
4952
4953
|
|
|
4954
|
+
/**
|
|
4955
|
+
Use Math.random to generate v4 RFC4122 compliant uuid
|
|
4956
|
+
*/
|
|
4957
|
+
function uuidv4() {
|
|
4958
|
+
const uuid = [];
|
|
4959
|
+
for (let i = 0; i < 32; i++) {
|
|
4960
|
+
const random = (Math.random() * 16) | 0;
|
|
4961
|
+
if (i === 8 || i === 12 || i === 16 || i === 20) {
|
|
4962
|
+
uuid.push('-');
|
|
4963
|
+
}
|
|
4964
|
+
uuid.push((i === 12 ? 4 : i === 16 ? (random & 3) | 8 : random).toString(16));
|
|
4965
|
+
}
|
|
4966
|
+
return uuid.join('');
|
|
4967
|
+
}
|
|
4968
|
+
|
|
4953
4969
|
/**
|
|
4954
4970
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
4955
4971
|
* All rights reserved.
|
|
@@ -5163,20 +5179,6 @@ function generateUniqueDraftActionId(existingIds) {
|
|
|
5163
5179
|
}
|
|
5164
5180
|
return newId.toString();
|
|
5165
5181
|
}
|
|
5166
|
-
/**
|
|
5167
|
-
Use Math.random to generate v4 RFC4122 compliant uuid
|
|
5168
|
-
*/
|
|
5169
|
-
function uuidv4() {
|
|
5170
|
-
const uuid = [];
|
|
5171
|
-
for (let i = 0; i < 32; i++) {
|
|
5172
|
-
const random = (Math.random() * 16) | 0;
|
|
5173
|
-
if (i === 8 || i === 12 || i === 16 || i === 20) {
|
|
5174
|
-
uuid.push('-');
|
|
5175
|
-
}
|
|
5176
|
-
uuid.push((i === 12 ? 4 : i === 16 ? (random & 3) | 8 : random).toString(16));
|
|
5177
|
-
}
|
|
5178
|
-
return uuid.join('');
|
|
5179
|
-
}
|
|
5180
5182
|
|
|
5181
5183
|
const HTTP_HEADER_RETRY_AFTER = 'Retry-After';
|
|
5182
5184
|
const HTTP_HEADER_IDEMPOTENCY_KEY = 'Idempotency-Key';
|
|
@@ -6053,7 +6055,12 @@ class AbstractResourceRequestActionHandler {
|
|
|
6053
6055
|
// the luvio store redirect table, during which a new draft might be enqueued
|
|
6054
6056
|
// which would not see a necessary mapping.
|
|
6055
6057
|
this.ephemeralRedirects = {};
|
|
6058
|
+
// determined by Server setup.
|
|
6056
6059
|
this.isIdempotencySupported = true;
|
|
6060
|
+
// idempotency write flag set by lds
|
|
6061
|
+
this.isLdsIdempotencyWriteDisabled = ldsIdempotencyWriteDisabled.isOpen({
|
|
6062
|
+
fallback: false,
|
|
6063
|
+
});
|
|
6057
6064
|
}
|
|
6058
6065
|
enqueue(data) {
|
|
6059
6066
|
return this.draftQueue.enqueue(this.handlerId, data);
|
|
@@ -6410,7 +6417,7 @@ class AbstractResourceRequestActionHandler {
|
|
|
6410
6417
|
return [action.targetId];
|
|
6411
6418
|
}
|
|
6412
6419
|
hasIdempotencySupport() {
|
|
6413
|
-
return this.isIdempotencySupported;
|
|
6420
|
+
return this.isIdempotencySupported && !this.isLdsIdempotencyWriteDisabled;
|
|
6414
6421
|
}
|
|
6415
6422
|
async ingestResponses(responses, action) {
|
|
6416
6423
|
const luvio = this.getLuvio();
|
|
@@ -6948,14 +6955,20 @@ function buildQueryTypeStringKey(args) {
|
|
|
6948
6955
|
*/
|
|
6949
6956
|
|
|
6950
6957
|
|
|
6958
|
+
const MAX_BATCH_SIZE = 2000;
|
|
6951
6959
|
class DataLoader {
|
|
6952
|
-
constructor(batchLoadFn) {
|
|
6960
|
+
constructor(batchLoadFn, options) {
|
|
6953
6961
|
this._batchLoadFn = batchLoadFn;
|
|
6954
6962
|
this._batch = null;
|
|
6955
6963
|
this._batchScheduleFn = function (fn) {
|
|
6956
6964
|
setTimeout(fn, 0);
|
|
6957
6965
|
};
|
|
6958
6966
|
this._cacheMap = new Map();
|
|
6967
|
+
this._maxBatchSize = MAX_BATCH_SIZE;
|
|
6968
|
+
if (options !== undefined) {
|
|
6969
|
+
const { maxBatchSize } = options;
|
|
6970
|
+
this._maxBatchSize = maxBatchSize || MAX_BATCH_SIZE;
|
|
6971
|
+
}
|
|
6959
6972
|
}
|
|
6960
6973
|
load(key) {
|
|
6961
6974
|
if (key === null || key === undefined) {
|
|
@@ -6985,7 +6998,9 @@ class DataLoader {
|
|
|
6985
6998
|
// If there is an existing batch which has not yet dispatched and is within
|
|
6986
6999
|
// the limit of the batch size, then return it.
|
|
6987
7000
|
const existingBatch = this._batch;
|
|
6988
|
-
if (existingBatch !== null &&
|
|
7001
|
+
if (existingBatch !== null &&
|
|
7002
|
+
!existingBatch.hasDispatched &&
|
|
7003
|
+
existingBatch.keys.length < this._maxBatchSize) {
|
|
6989
7004
|
return existingBatch;
|
|
6990
7005
|
}
|
|
6991
7006
|
// Otherwise, create a new batch for this loader.
|
|
@@ -7077,7 +7092,7 @@ function isArrayLike(x) {
|
|
|
7077
7092
|
|
|
7078
7093
|
const { create: create$4, keys: keys$4, values: values$2, entries: entries$3, assign: assign$4 } = Object;
|
|
7079
7094
|
const { stringify: stringify$4, parse: parse$4 } = JSON;
|
|
7080
|
-
const { isArray: isArray$2 } = Array;
|
|
7095
|
+
const { isArray: isArray$2, from: from$1 } = Array;
|
|
7081
7096
|
|
|
7082
7097
|
function recordLoaderFactory(query) {
|
|
7083
7098
|
async function batchRecordQuery(ids) {
|
|
@@ -9308,25 +9323,6 @@ const additionalSchemaDefinitions = /* GraphQL */ `
|
|
|
9308
9323
|
}
|
|
9309
9324
|
`;
|
|
9310
9325
|
const baseTypeDefinitions = uiapiSchemaString + additionalSchemaDefinitions;
|
|
9311
|
-
/**
|
|
9312
|
-
*
|
|
9313
|
-
* @param objectInfos
|
|
9314
|
-
* @returns Type definition string and entity type names which support polymorphism.
|
|
9315
|
-
*/
|
|
9316
|
-
function generateTypeDefinitions(objectInfos) {
|
|
9317
|
-
if (keys$4(objectInfos).length === 0)
|
|
9318
|
-
return { typeDefs: baseTypeDefinitions, polyFieldTypeNames: [] };
|
|
9319
|
-
const { recordQueries, recordConnections, polyFieldTypeNameArr } = generateRecordQueries(objectInfos);
|
|
9320
|
-
const typeDefs = `
|
|
9321
|
-
${baseTypeDefinitions}
|
|
9322
|
-
|
|
9323
|
-
extend type RecordQuery {
|
|
9324
|
-
${recordQueries}
|
|
9325
|
-
}
|
|
9326
|
-
${recordConnections}
|
|
9327
|
-
`;
|
|
9328
|
-
return { typeDefs, polyFieldTypeNames: polyFieldTypeNameArr };
|
|
9329
|
-
}
|
|
9330
9326
|
const fieldsStaticallyAdded = [
|
|
9331
9327
|
'ApiName',
|
|
9332
9328
|
'DisplayValue',
|
|
@@ -9336,99 +9332,347 @@ const fieldsStaticallyAdded = [
|
|
|
9336
9332
|
'SystemModstamp',
|
|
9337
9333
|
'WeakEtag',
|
|
9338
9334
|
];
|
|
9339
|
-
|
|
9335
|
+
class CachedGraphQLSchema {
|
|
9336
|
+
constructor() {
|
|
9337
|
+
this._schema = buildBaseSchema();
|
|
9338
|
+
this._polymorphicFieldTypeNames = [];
|
|
9339
|
+
}
|
|
9340
|
+
getSchema() {
|
|
9341
|
+
return this._schema;
|
|
9342
|
+
}
|
|
9343
|
+
setSchema(value) {
|
|
9344
|
+
this._schema = value;
|
|
9345
|
+
}
|
|
9346
|
+
getPolymorphicFieldTypeNames() {
|
|
9347
|
+
return this._polymorphicFieldTypeNames;
|
|
9348
|
+
}
|
|
9349
|
+
setPolymorphicFieldTypeNames(value) {
|
|
9350
|
+
this._polymorphicFieldTypeNames = value;
|
|
9351
|
+
}
|
|
9352
|
+
set(schema, polymorphicFieldTypeNames) {
|
|
9353
|
+
this._schema = schema;
|
|
9354
|
+
this._polymorphicFieldTypeNames = polymorphicFieldTypeNames;
|
|
9355
|
+
}
|
|
9356
|
+
}
|
|
9357
|
+
/**
|
|
9358
|
+
* Looks at the injected object info map and checks to see if the existing objects
|
|
9359
|
+
* are within the current schema. It will extend the cached schema if it is not included.
|
|
9360
|
+
* @param objectInfos
|
|
9361
|
+
* @param cache
|
|
9362
|
+
* @returns GraphQLSchema
|
|
9363
|
+
*/
|
|
9364
|
+
function createSchemaWithCache(objectInfos, cache) {
|
|
9365
|
+
const updatedCache = extendSchemaWithObjectInfos(cache, objectInfos);
|
|
9366
|
+
// set the new values to the passed cached schema & polymorphic field names
|
|
9367
|
+
cache.set(updatedCache.getSchema(), updatedCache.getPolymorphicFieldTypeNames());
|
|
9368
|
+
return cache.getSchema();
|
|
9369
|
+
}
|
|
9370
|
+
/**
|
|
9371
|
+
* Extends the current GraphQL Schema with new types based on the given object info map
|
|
9372
|
+
*
|
|
9373
|
+
* @param cache the existing cached schema object
|
|
9374
|
+
* @param objectInfoMap map of object info and apiname for key
|
|
9375
|
+
* @returns CachedGraphQLSchema
|
|
9376
|
+
*/
|
|
9377
|
+
function extendSchemaWithObjectInfos(cache, objectInfoMap) {
|
|
9378
|
+
const { recordQueries, recordConnections, recordExtensions, polyFieldTypeNameArr } = generateRecordQueries(cache.getSchema(), objectInfoMap);
|
|
9379
|
+
const typeDefs = `
|
|
9380
|
+
${recordQueries}
|
|
9381
|
+
${recordConnections}
|
|
9382
|
+
${recordExtensions}
|
|
9383
|
+
`;
|
|
9384
|
+
// if nothing new is added then return the current cache
|
|
9385
|
+
if (typeDefs.trim().length === 0) {
|
|
9386
|
+
return cache;
|
|
9387
|
+
}
|
|
9388
|
+
// parse extensions into DocumentNode to extend the schema
|
|
9389
|
+
const extensions = parse$7(typeDefs);
|
|
9390
|
+
const polymorphicFieldTypeNames = [
|
|
9391
|
+
...polyFieldTypeNameArr,
|
|
9392
|
+
...cache.getPolymorphicFieldTypeNames(),
|
|
9393
|
+
];
|
|
9394
|
+
// extend the schema and add resolvers
|
|
9395
|
+
const schema = addResolversToSchema(extendSchema(cache.getSchema(), extensions), polymorphicFieldTypeNames);
|
|
9396
|
+
const polymorphicFieldTypeNamesSet = new Set(polymorphicFieldTypeNames);
|
|
9397
|
+
cache.setSchema(schema);
|
|
9398
|
+
cache.setPolymorphicFieldTypeNames([...polymorphicFieldTypeNamesSet]);
|
|
9399
|
+
return cache;
|
|
9400
|
+
}
|
|
9401
|
+
/**
|
|
9402
|
+
* Builds the base schema from uiapi graphql adapter with resolvers attached
|
|
9403
|
+
* @returns GraphQLSchema
|
|
9404
|
+
*/
|
|
9405
|
+
function buildBaseSchema() {
|
|
9406
|
+
return addResolversToSchema(buildSchema(baseTypeDefinitions), []);
|
|
9407
|
+
}
|
|
9408
|
+
/**
|
|
9409
|
+
* Given the existing schema and the object infos it will create a new type for the schema
|
|
9410
|
+
* or extend an existing type to add new fields to it.
|
|
9411
|
+
*
|
|
9412
|
+
* Extends RecordQuery to add new top level queries
|
|
9413
|
+
* extend type RecordQuery {
|
|
9414
|
+
* Account(predicates): AccountConnection
|
|
9415
|
+
* }
|
|
9416
|
+
* @param schema
|
|
9417
|
+
* @param objectInfoMap
|
|
9418
|
+
* @returns
|
|
9419
|
+
*/
|
|
9420
|
+
function generateRecordQueries(schema, objectInfoMap) {
|
|
9340
9421
|
let recordQueries = ``;
|
|
9341
9422
|
let recordConnections = ``;
|
|
9342
|
-
|
|
9423
|
+
let recordExtensions = ``;
|
|
9424
|
+
// use a set to not allow duplicate scalars causing error(s)
|
|
9425
|
+
let addedTypedScalars = new Set();
|
|
9426
|
+
let allPolymorphicFieldTypeNames = new Set();
|
|
9427
|
+
for (const name of keys$4(objectInfoMap)) {
|
|
9428
|
+
const objectInfo = objectInfoMap[name];
|
|
9429
|
+
const { apiName } = objectInfo;
|
|
9430
|
+
const type = schema.getType(apiName);
|
|
9431
|
+
// if type is an ObjectType it exists in the schema
|
|
9432
|
+
if (isObjectType(type)) {
|
|
9433
|
+
const { recordExtension, typedScalars, polymorphicFieldTypeNames } = extendExistingRecordType(schema, type, objectInfo, objectInfoMap);
|
|
9434
|
+
recordExtensions += recordExtension;
|
|
9435
|
+
addedTypedScalars = new Set([...addedTypedScalars, ...typedScalars]);
|
|
9436
|
+
allPolymorphicFieldTypeNames = new Set([
|
|
9437
|
+
...allPolymorphicFieldTypeNames,
|
|
9438
|
+
...polymorphicFieldTypeNames,
|
|
9439
|
+
]);
|
|
9440
|
+
}
|
|
9441
|
+
else {
|
|
9442
|
+
const { recordQueries: newRecordQueries, recordConnections: newRecordConnections, typedScalars, polymorphicFieldTypeNames, } = createNewRecordQuery(schema, objectInfo, objectInfoMap);
|
|
9443
|
+
recordQueries += newRecordQueries;
|
|
9444
|
+
recordConnections += newRecordConnections;
|
|
9445
|
+
addedTypedScalars = new Set([...addedTypedScalars, ...typedScalars]);
|
|
9446
|
+
allPolymorphicFieldTypeNames = new Set([
|
|
9447
|
+
...allPolymorphicFieldTypeNames,
|
|
9448
|
+
...polymorphicFieldTypeNames,
|
|
9449
|
+
]);
|
|
9450
|
+
}
|
|
9451
|
+
}
|
|
9452
|
+
// transform added scalar types into a list of scalars in string
|
|
9453
|
+
const scalars = [...addedTypedScalars].map((scalar) => `scalar ${scalar}`).join('\n');
|
|
9454
|
+
recordConnections += scalars;
|
|
9455
|
+
// return empty string if no recordQueries were extended
|
|
9456
|
+
const extensionWrapper = recordQueries.length > 0
|
|
9457
|
+
? `
|
|
9458
|
+
extend type RecordQuery {
|
|
9459
|
+
${recordQueries}
|
|
9460
|
+
}`
|
|
9461
|
+
: '';
|
|
9462
|
+
return {
|
|
9463
|
+
recordQueries: extensionWrapper,
|
|
9464
|
+
recordConnections,
|
|
9465
|
+
recordExtensions,
|
|
9466
|
+
polyFieldTypeNameArr: from$1(allPolymorphicFieldTypeNames),
|
|
9467
|
+
};
|
|
9468
|
+
}
|
|
9469
|
+
/**
|
|
9470
|
+
* Will create a new record query extension for something that does not already exist in the schema
|
|
9471
|
+
*
|
|
9472
|
+
* generates:
|
|
9473
|
+
*
|
|
9474
|
+
* type {typename} implements Record {
|
|
9475
|
+
* ...scalar fields
|
|
9476
|
+
* Id: IDValue
|
|
9477
|
+
* ...spanning parent records
|
|
9478
|
+
* User: Parent
|
|
9479
|
+
* ...spanning children queries
|
|
9480
|
+
* Accounts(predicates): AccountConnection
|
|
9481
|
+
* }
|
|
9482
|
+
*
|
|
9483
|
+
* scalars SomeAddedScalar
|
|
9484
|
+
*
|
|
9485
|
+
* @param schema
|
|
9486
|
+
* @param objectInfo
|
|
9487
|
+
* @param objectInfoMap
|
|
9488
|
+
* @returns
|
|
9489
|
+
*/
|
|
9490
|
+
function createNewRecordQuery(schema, objectInfo, objectInfoMap) {
|
|
9343
9491
|
let typedScalars = new Set();
|
|
9344
9492
|
let parentRelationshipFields = new Set();
|
|
9345
|
-
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
|
|
9355
|
-
|
|
9356
|
-
|
|
9493
|
+
const { apiName, childRelationships, fields: fieldsRepresentation } = objectInfo;
|
|
9494
|
+
typedScalars.add(`${apiName}_Filter`);
|
|
9495
|
+
typedScalars.add(`${apiName}_OrderBy`);
|
|
9496
|
+
const { fields, polymorphicFieldTypeNames } = makeRecordField(values$2(fieldsRepresentation), objectInfoMap, parentRelationshipFields, 'Missing');
|
|
9497
|
+
// handles child relationship
|
|
9498
|
+
const { spanningRecordConnections, typedScalars: spanningConnectionTypedScalars } = makeSpanningRecordConnections(schema, childRelationships, objectInfoMap, parentRelationshipFields);
|
|
9499
|
+
typedScalars = new Set([...typedScalars, ...spanningConnectionTypedScalars]);
|
|
9500
|
+
const recordQueries = `${apiName}(first: Int, where: ${apiName}_Filter, orderBy: ${apiName}_OrderBy, scope: SupportedScopes): ${apiName}Connection\n`;
|
|
9501
|
+
const isServiceAppointment = apiName === 'ServiceAppointment';
|
|
9502
|
+
const recordConnections = /* GraphQL */ `
|
|
9503
|
+
${isServiceAppointment ? `scalar ${apiName.toUpperCase()}_SCOPE` : ''}
|
|
9504
|
+
|
|
9505
|
+
type ${apiName} implements Record {
|
|
9506
|
+
ApiName: String!
|
|
9507
|
+
DisplayValue: String
|
|
9508
|
+
LastModifiedById: IDValue
|
|
9509
|
+
LastModifiedDate: DateTimeValue
|
|
9510
|
+
RecordTypeId(fallback: Boolean): IDValue
|
|
9511
|
+
SystemModstamp: DateTimeValue
|
|
9512
|
+
WeakEtag: Long!
|
|
9513
|
+
_drafts: JSON
|
|
9514
|
+
${fields}
|
|
9515
|
+
${spanningRecordConnections}
|
|
9357
9516
|
}
|
|
9358
|
-
|
|
9359
|
-
|
|
9360
|
-
|
|
9361
|
-
|
|
9362
|
-
|
|
9363
|
-
// the query.
|
|
9364
|
-
if (objectInfos[relation.apiName] !== undefined) {
|
|
9365
|
-
parentRelationshipFields.add(field.relationshipName);
|
|
9366
|
-
fields += `${field.relationshipName}: ${relation.apiName}\n`;
|
|
9367
|
-
}
|
|
9368
|
-
// For polymorphic field, its type is 'Record' inteface. The concrete entity type name is saved for field resolving of next phase
|
|
9517
|
+
|
|
9518
|
+
type ${apiName}Connection {
|
|
9519
|
+
edges: [${apiName}Edge]
|
|
9520
|
+
pageInfo: PageInfo!
|
|
9521
|
+
totalCount: Int!
|
|
9369
9522
|
}
|
|
9370
|
-
|
|
9371
|
-
|
|
9372
|
-
|
|
9373
|
-
|
|
9374
|
-
if (objectInfos[relation.apiName] !== undefined) {
|
|
9375
|
-
polymorphicFieldTypeNames.add(relation.apiName);
|
|
9376
|
-
}
|
|
9377
|
-
}
|
|
9523
|
+
|
|
9524
|
+
type ${apiName}Edge {
|
|
9525
|
+
node: ${apiName}
|
|
9526
|
+
cursor: String!
|
|
9378
9527
|
}
|
|
9528
|
+
|
|
9529
|
+
`;
|
|
9530
|
+
return { recordQueries, recordConnections, typedScalars, polymorphicFieldTypeNames };
|
|
9531
|
+
}
|
|
9532
|
+
/**
|
|
9533
|
+
* Takes the current schema and will extend missing fields to the record.
|
|
9534
|
+
* Assume all scalar fields have already been added, but will extend spanning fields
|
|
9535
|
+
*
|
|
9536
|
+
* extend type Account {
|
|
9537
|
+
* ...spanning parent records
|
|
9538
|
+
* User: User
|
|
9539
|
+
* ...spanning children queries
|
|
9540
|
+
* Users(predicates): UserConnection
|
|
9541
|
+
* }
|
|
9542
|
+
*
|
|
9543
|
+
* @param schema
|
|
9544
|
+
* @param type
|
|
9545
|
+
* @param objectInfo
|
|
9546
|
+
* @param objectInfoMap
|
|
9547
|
+
* @returns
|
|
9548
|
+
*/
|
|
9549
|
+
function extendExistingRecordType(schema, type, objectInfo, objectInfoMap) {
|
|
9550
|
+
// use a set to not allow duplicate scalars causing error(s)
|
|
9551
|
+
let typedScalars = new Set();
|
|
9552
|
+
let parentRelationshipFields = new Set();
|
|
9553
|
+
const existingFields = keys$4(type.getFields());
|
|
9554
|
+
const missingFields = values$2(objectInfo.fields).filter((field) => {
|
|
9555
|
+
return (existingFields.includes(field.apiName) === false ||
|
|
9556
|
+
(field.relationshipName !== null && field.referenceToInfos.length > 1));
|
|
9557
|
+
});
|
|
9558
|
+
const { fields, polymorphicFieldTypeNames } = makeRecordField(missingFields, objectInfoMap, parentRelationshipFields, 'Cached');
|
|
9559
|
+
const { apiName, childRelationships } = objectInfo;
|
|
9560
|
+
// handles child relationship
|
|
9561
|
+
const { spanningRecordConnections, typedScalars: spanningConnectionTypedScalars } = makeSpanningRecordConnections(schema, childRelationships, objectInfoMap, parentRelationshipFields, existingFields);
|
|
9562
|
+
typedScalars = new Set([...typedScalars, ...spanningConnectionTypedScalars]);
|
|
9563
|
+
const hasExtensions = fields.length > 0 || spanningRecordConnections.length > 0;
|
|
9564
|
+
const recordExtension = hasExtensions
|
|
9565
|
+
? `
|
|
9566
|
+
extend type ${apiName} {
|
|
9567
|
+
${fields}
|
|
9568
|
+
${spanningRecordConnections}
|
|
9569
|
+
}\n`
|
|
9570
|
+
: '';
|
|
9571
|
+
return { recordExtension, typedScalars, polymorphicFieldTypeNames };
|
|
9572
|
+
}
|
|
9573
|
+
/**
|
|
9574
|
+
* Converts child relationships into spanning record connections to be added to record types
|
|
9575
|
+
*
|
|
9576
|
+
* type Record {
|
|
9577
|
+
* Generates -> AccountConnection(first: Int, where: Account_Filter, etc...): AccountConnection
|
|
9578
|
+
* }
|
|
9579
|
+
*
|
|
9580
|
+
* will also generate typed scalars if they have not been added to the existing schema for the spanning connection
|
|
9581
|
+
* example: Account_Filter or Account_OrderBy scalars needed to be defined as predicate types
|
|
9582
|
+
* @param schema
|
|
9583
|
+
* @param childRelationships
|
|
9584
|
+
* @param objectInfoMap
|
|
9585
|
+
* @param existingParentRelationships
|
|
9586
|
+
* @param existingFields
|
|
9587
|
+
* @returns
|
|
9588
|
+
*/
|
|
9589
|
+
function makeSpanningRecordConnections(schema, childRelationships, objectInfoMap, existingParentRelationships, existingFields = []) {
|
|
9590
|
+
let spanningRecordConnections = ``;
|
|
9591
|
+
let typedScalars = new Set();
|
|
9592
|
+
for (const childRelationship of childRelationships) {
|
|
9593
|
+
const { childObjectApiName, relationshipName } = childRelationship;
|
|
9594
|
+
// Only add the relationship if there is relevant objectinfos for it,
|
|
9595
|
+
// otherwise we'd be defining types we cannot satisfy and aren't referenced in
|
|
9596
|
+
// the query.
|
|
9597
|
+
// If one field has both parent relationship and child relationship with the same name, the child relationship is ignored. This is how the server GQL has implemented as date of 08/07/2023
|
|
9598
|
+
if (existingFields.length > 0 && existingFields.includes(relationshipName)) {
|
|
9599
|
+
continue;
|
|
9379
9600
|
}
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9601
|
+
if (objectInfoMap[childObjectApiName] !== undefined &&
|
|
9602
|
+
!existingParentRelationships.has(relationshipName)) {
|
|
9603
|
+
spanningRecordConnections += `${relationshipName}(first: Int, where: ${childObjectApiName}_Filter, orderBy: ${childObjectApiName}_OrderBy, scope: SupportedScopes): ${childObjectApiName}Connection \n`;
|
|
9604
|
+
// if the record type has already been extended then these additional scalars have already been added
|
|
9605
|
+
// to add them again would throw an error
|
|
9606
|
+
const filterScalarType = schema.getType(`${childObjectApiName}_Filter`);
|
|
9607
|
+
if (isScalarType(filterScalarType) === false) {
|
|
9608
|
+
typedScalars.add(`${childObjectApiName}_Filter`);
|
|
9609
|
+
}
|
|
9610
|
+
const orderByScalarType = schema.getType(`${childObjectApiName}_OrderBy`);
|
|
9611
|
+
if (isScalarType(orderByScalarType) === false) {
|
|
9612
|
+
typedScalars.add(`${childObjectApiName}_OrderBy`);
|
|
9613
|
+
}
|
|
9614
|
+
}
|
|
9615
|
+
}
|
|
9616
|
+
return { spanningRecordConnections, typedScalars };
|
|
9617
|
+
}
|
|
9618
|
+
/**
|
|
9619
|
+
* Creates scalar and parent relationship fields for a record type
|
|
9620
|
+
*
|
|
9621
|
+
* type RecordName {
|
|
9622
|
+
* generates scalar -> Id: IDValue
|
|
9623
|
+
* generates relationship -> Account: Record
|
|
9624
|
+
* }
|
|
9625
|
+
*
|
|
9626
|
+
* can be used in a type definition or an extension
|
|
9627
|
+
* @param fieldRepresentations
|
|
9628
|
+
* @param objectInfoMap
|
|
9629
|
+
* @param existingParentRelationships
|
|
9630
|
+
* @param recordTypeInSchema
|
|
9631
|
+
* @returns
|
|
9632
|
+
*/
|
|
9633
|
+
function makeRecordField(fieldRepresentations, objectInfoMap, existingParentRelationships, recordTypeInSchema) {
|
|
9634
|
+
const polymorphicFieldTypeNames = new Set();
|
|
9635
|
+
let fields = ``;
|
|
9636
|
+
for (const field of values$2(fieldRepresentations)) {
|
|
9637
|
+
if (!fieldsStaticallyAdded.includes(field.apiName) && recordTypeInSchema === 'Missing') {
|
|
9638
|
+
fields += `${field.apiName}: ${dataTypeToType(field.dataType, field.apiName)}\n`;
|
|
9639
|
+
}
|
|
9640
|
+
//handles parent relationship
|
|
9641
|
+
if (field.relationshipName === null) {
|
|
9642
|
+
continue;
|
|
9643
|
+
}
|
|
9644
|
+
// For spanning parent relationships with no union types
|
|
9645
|
+
if (field.referenceToInfos.length === 1) {
|
|
9646
|
+
const [relation] = field.referenceToInfos;
|
|
9383
9647
|
// Only add the relationship if there is relevant objectinfos for it,
|
|
9384
9648
|
// otherwise we'd be defining types we cannot satisfy and aren't referenced in
|
|
9385
9649
|
// the query.
|
|
9386
|
-
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
fields += `${childRelationship.relationshipName}(first: Int, where: ${childObjectApiName}_Filter, orderBy: ${childObjectApiName}_OrderBy, scope: SupportedScopes): ${childObjectApiName}Connection \n`;
|
|
9390
|
-
typedScalars.add(`${childObjectApiName}_Filter`);
|
|
9391
|
-
typedScalars.add(`${childObjectApiName}_OrderBy`);
|
|
9650
|
+
if (objectInfoMap[relation.apiName] !== undefined) {
|
|
9651
|
+
existingParentRelationships.add(field.relationshipName);
|
|
9652
|
+
fields += `${field.relationshipName}: ${relation.apiName}\n`;
|
|
9392
9653
|
}
|
|
9654
|
+
// For polymorphic field, its type is 'Record' inteface. The concrete entity type name is saved for field resolving of next phase
|
|
9393
9655
|
}
|
|
9394
|
-
|
|
9395
|
-
|
|
9396
|
-
|
|
9397
|
-
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
|
|
9401
|
-
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
RecordTypeId(fallback: Boolean): IDValue
|
|
9405
|
-
SystemModstamp: DateTimeValue
|
|
9406
|
-
WeakEtag: Long!
|
|
9407
|
-
_drafts: JSON
|
|
9408
|
-
${fields}
|
|
9409
|
-
}
|
|
9410
|
-
|
|
9411
|
-
type ${apiName}Connection {
|
|
9412
|
-
edges: [${apiName}Edge]
|
|
9413
|
-
pageInfo: PageInfo!
|
|
9414
|
-
totalCount: Int!
|
|
9415
|
-
}
|
|
9416
|
-
|
|
9417
|
-
type ${apiName}Edge {
|
|
9418
|
-
node: ${apiName}
|
|
9419
|
-
cursor: String!
|
|
9656
|
+
else if (field.referenceToInfos.length > 1) {
|
|
9657
|
+
if (recordTypeInSchema === 'Missing') {
|
|
9658
|
+
existingParentRelationships.add(field.relationshipName);
|
|
9659
|
+
fields += `${field.relationshipName}: Record\n`;
|
|
9660
|
+
}
|
|
9661
|
+
for (const relation of field.referenceToInfos) {
|
|
9662
|
+
if (objectInfoMap[relation.apiName] !== undefined) {
|
|
9663
|
+
polymorphicFieldTypeNames.add(relation.apiName);
|
|
9664
|
+
}
|
|
9665
|
+
}
|
|
9420
9666
|
}
|
|
9421
|
-
|
|
9422
|
-
`;
|
|
9423
9667
|
}
|
|
9424
|
-
|
|
9425
|
-
return accu + `scalar ${typed}\n`;
|
|
9426
|
-
}, ``);
|
|
9427
|
-
recordConnections += scalars;
|
|
9428
|
-
const polyFieldTypeNameArr = [];
|
|
9429
|
-
polymorphicFieldTypeNames.forEach((fieldType) => polyFieldTypeNameArr.push(fieldType));
|
|
9430
|
-
return { recordQueries, recordConnections, polyFieldTypeNameArr };
|
|
9668
|
+
return { fields, polymorphicFieldTypeNames };
|
|
9431
9669
|
}
|
|
9670
|
+
/**
|
|
9671
|
+
* converts the ObjectInfoRepresentation data type into a defined schema scalar type
|
|
9672
|
+
* @param objectInfoDataType
|
|
9673
|
+
* @param apiName
|
|
9674
|
+
* @returns
|
|
9675
|
+
*/
|
|
9432
9676
|
function dataTypeToType(objectInfoDataType, apiName) {
|
|
9433
9677
|
if (apiName && apiName === 'Id') {
|
|
9434
9678
|
return `ID!`;
|
|
@@ -9470,13 +9714,8 @@ function dataTypeToType(objectInfoDataType, apiName) {
|
|
|
9470
9714
|
return 'String';
|
|
9471
9715
|
}
|
|
9472
9716
|
}
|
|
9473
|
-
function createSchema(objectInfos) {
|
|
9474
|
-
const { typeDefs: typeDefinitions, polyFieldTypeNames } = generateTypeDefinitions(objectInfos);
|
|
9475
|
-
const schema = buildSchema(typeDefinitions);
|
|
9476
|
-
return addResolversToSchema(schema, polyFieldTypeNames);
|
|
9477
|
-
}
|
|
9478
9717
|
|
|
9479
|
-
async function evaluate(config, observers, settings, objectInfos, store, snapshot, draftFunctions) {
|
|
9718
|
+
async function evaluate(config, observers, settings, objectInfos, store, snapshot, cache, draftFunctions) {
|
|
9480
9719
|
const eventEmitter = createCustomAdapterEventEmitter(GRAPHQL_EVAL_NAMESPACE, observers);
|
|
9481
9720
|
// this is only wrapped in a try to execute the event after the result was returned
|
|
9482
9721
|
try {
|
|
@@ -9517,7 +9756,7 @@ async function evaluate(config, observers, settings, objectInfos, store, snapsho
|
|
|
9517
9756
|
const contextValue = createContext(store, objectInfos, eventEmitter, settings, snapshot, draftFunctions);
|
|
9518
9757
|
// We're building this from scratch from each request. If this becomes a
|
|
9519
9758
|
// hotspot we can pull it up and memoize it later
|
|
9520
|
-
const schema =
|
|
9759
|
+
const schema = createSchemaWithCache(objectInfos, cache);
|
|
9521
9760
|
eventEmitter({ type: 'graphql-schema-created' });
|
|
9522
9761
|
// execute document against schema/context
|
|
9523
9762
|
let result = (await execute({
|
|
@@ -11867,34 +12106,42 @@ function applyReferenceLinksToDraft(record, draftMetadata) {
|
|
|
11867
12106
|
}
|
|
11868
12107
|
const { dataType, relationshipName, referenceToInfos } = fieldInfo;
|
|
11869
12108
|
const draftFieldValue = record.fields[draftField].value;
|
|
11870
|
-
if (dataType === 'Reference' && relationshipName !== null
|
|
11871
|
-
if (
|
|
11872
|
-
|
|
12109
|
+
if (dataType === 'Reference' && relationshipName !== null) {
|
|
12110
|
+
if (draftFieldValue === null) {
|
|
12111
|
+
recordFields[relationshipName] = {
|
|
12112
|
+
displayValue: null,
|
|
12113
|
+
value: null,
|
|
12114
|
+
};
|
|
11873
12115
|
}
|
|
11874
|
-
|
|
11875
|
-
|
|
11876
|
-
|
|
11877
|
-
displayValue: null,
|
|
11878
|
-
value: createLink(key),
|
|
11879
|
-
};
|
|
11880
|
-
// for custom objects, we select the 'Name' field
|
|
11881
|
-
// otherwise we check the object info for name fields.
|
|
11882
|
-
//if there are multiple we select 'Name' if it exists, otherwise the first one
|
|
11883
|
-
if (referencedRecord !== undefined && referenceToInfos.length > 0) {
|
|
11884
|
-
let nameField;
|
|
11885
|
-
const referenceToInfo = referenceToInfos[0];
|
|
11886
|
-
const nameFields = referenceToInfo.nameFields;
|
|
11887
|
-
if (nameFields.length !== 0) {
|
|
11888
|
-
nameField = nameFields.find((x) => x === 'Name');
|
|
11889
|
-
if (nameField === undefined) {
|
|
11890
|
-
nameField = nameFields[0];
|
|
11891
|
-
}
|
|
12116
|
+
else {
|
|
12117
|
+
if (typeof draftFieldValue !== 'string') {
|
|
12118
|
+
throw Error('reference field value is not a string');
|
|
11892
12119
|
}
|
|
11893
|
-
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
|
|
11897
|
-
|
|
12120
|
+
const key = getRecordKeyForId(luvio, draftFieldValue);
|
|
12121
|
+
const referencedRecord = referencedRecords.get(key);
|
|
12122
|
+
recordFields[relationshipName] = {
|
|
12123
|
+
displayValue: null,
|
|
12124
|
+
value: createLink(key),
|
|
12125
|
+
};
|
|
12126
|
+
// for custom objects, we select the 'Name' field
|
|
12127
|
+
// otherwise we check the object info for name fields.
|
|
12128
|
+
//if there are multiple we select 'Name' if it exists, otherwise the first one
|
|
12129
|
+
if (referencedRecord !== undefined && referenceToInfos.length > 0) {
|
|
12130
|
+
let nameField;
|
|
12131
|
+
const referenceToInfo = referenceToInfos[0];
|
|
12132
|
+
const nameFields = referenceToInfo.nameFields;
|
|
12133
|
+
if (nameFields.length !== 0) {
|
|
12134
|
+
nameField = nameFields.find((x) => x === 'Name');
|
|
12135
|
+
if (nameField === undefined) {
|
|
12136
|
+
nameField = nameFields[0];
|
|
12137
|
+
}
|
|
12138
|
+
}
|
|
12139
|
+
if (nameField !== undefined) {
|
|
12140
|
+
const nameFieldRef = referencedRecord.fields[nameField];
|
|
12141
|
+
if (nameFieldRef) {
|
|
12142
|
+
recordFields[relationshipName].displayValue =
|
|
12143
|
+
(_a = nameFieldRef.displayValue) !== null && _a !== void 0 ? _a : nameFieldRef.value;
|
|
12144
|
+
}
|
|
11898
12145
|
}
|
|
11899
12146
|
}
|
|
11900
12147
|
}
|
|
@@ -12187,17 +12434,8 @@ class UiApiActionHandler extends AbstractResourceRequestActionHandler {
|
|
|
12187
12434
|
};
|
|
12188
12435
|
for (const fieldName of keys$3(recordWithSpanningRefLinks.fields)) {
|
|
12189
12436
|
const fieldKey = buildRecordFieldStoreKey(key, fieldName);
|
|
12190
|
-
|
|
12191
|
-
|
|
12192
|
-
normalizedRecord.fields[fieldName] = { __ref: fieldKey };
|
|
12193
|
-
publishData(fieldKey, fieldData);
|
|
12194
|
-
}
|
|
12195
|
-
else if (recordWithSpanningRefLinks.fields[fieldName] &&
|
|
12196
|
-
recordWithSpanningRefLinks.fields[fieldName].value &&
|
|
12197
|
-
recordWithSpanningRefLinks.fields[fieldName].value.__ref !== undefined) {
|
|
12198
|
-
normalizedRecord.fields[fieldName] = { __ref: fieldKey };
|
|
12199
|
-
publishData(fieldKey, recordWithSpanningRefLinks.fields[fieldName]);
|
|
12200
|
-
}
|
|
12437
|
+
normalizedRecord.fields[fieldName] = { __ref: fieldKey };
|
|
12438
|
+
publishData(fieldKey, recordWithSpanningRefLinks.fields[fieldName]);
|
|
12201
12439
|
}
|
|
12202
12440
|
// publish the normalized record
|
|
12203
12441
|
publishData(key, normalizedRecord);
|
|
@@ -13012,6 +13250,8 @@ const replaceDraftIdsInVariables = (variables, draftFunctions, unmappedDraftIDs)
|
|
|
13012
13250
|
}, {});
|
|
13013
13251
|
return newVariables;
|
|
13014
13252
|
};
|
|
13253
|
+
// create the runtime cache for the graphql schema when the factory creates the adapter
|
|
13254
|
+
const graphqlSchemaCache = new CachedGraphQLSchema();
|
|
13015
13255
|
function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio, isDraftId) {
|
|
13016
13256
|
const getCanonicalId = (id) => {
|
|
13017
13257
|
var _a;
|
|
@@ -13085,7 +13325,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
13085
13325
|
...config,
|
|
13086
13326
|
//need to create another copy of the ast for future writes
|
|
13087
13327
|
query: parse$3(stringify$3(injectedAST)),
|
|
13088
|
-
}, observers, { userId }, objectInfoNeeded, store, nonEvaluatedSnapshot));
|
|
13328
|
+
}, observers, { userId }, objectInfoNeeded, store, nonEvaluatedSnapshot, graphqlSchemaCache));
|
|
13089
13329
|
}
|
|
13090
13330
|
catch (throwable) {
|
|
13091
13331
|
const error = throwable;
|
|
@@ -13114,7 +13354,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
13114
13354
|
let { result: rebuildResult, seenRecordIds } = await evaluate({
|
|
13115
13355
|
...config,
|
|
13116
13356
|
query: injectedAST,
|
|
13117
|
-
}, observers, { userId }, objectInfoNeeded, store, originalSnapshot, draftFunctions);
|
|
13357
|
+
}, observers, { userId }, objectInfoNeeded, store, originalSnapshot, graphqlSchemaCache, draftFunctions);
|
|
13118
13358
|
if (!rebuildResult.errors) {
|
|
13119
13359
|
rebuildResult = removeSyntheticFields(rebuildResult, config.query);
|
|
13120
13360
|
}
|
|
@@ -15156,6 +15396,14 @@ class ObjectInfoService {
|
|
|
15156
15396
|
return this.updateObjectInfoMapping(keyPrefix, apiName);
|
|
15157
15397
|
}
|
|
15158
15398
|
};
|
|
15399
|
+
this.getCachedObjectInfoStatus = async () => {
|
|
15400
|
+
const infos = await this.readObjectInfoDataFromDurableStore();
|
|
15401
|
+
const map = new Map();
|
|
15402
|
+
infos.forEach(({ apiName, expirationTimestamp }) => {
|
|
15403
|
+
map.set(apiName, { expiration: expirationTimestamp });
|
|
15404
|
+
});
|
|
15405
|
+
return map;
|
|
15406
|
+
};
|
|
15159
15407
|
this.isObjectInfoInDurableStore = async (apiName) => {
|
|
15160
15408
|
if (this.apiNameToKeyPrefixMemoryCache[apiName] !== undefined) {
|
|
15161
15409
|
return Promise.resolve(true);
|
|
@@ -15164,12 +15412,10 @@ class ObjectInfoService {
|
|
|
15164
15412
|
return this.apiNameToKeyPrefixMemoryCache[apiName] !== undefined;
|
|
15165
15413
|
};
|
|
15166
15414
|
this.loadObjectInfoMaps = async () => {
|
|
15167
|
-
const
|
|
15168
|
-
|
|
15169
|
-
const apiName = row[0];
|
|
15170
|
-
const keyPrefix = row[1];
|
|
15415
|
+
const infos = await this.readObjectInfoDataFromDurableStore();
|
|
15416
|
+
infos.forEach(({ keyPrefix, apiName }) => {
|
|
15171
15417
|
this.updateObjectInfoMapping(keyPrefix, apiName);
|
|
15172
|
-
}
|
|
15418
|
+
});
|
|
15173
15419
|
};
|
|
15174
15420
|
this.updateObjectInfoMapping = (keyPrefix, apiName) => {
|
|
15175
15421
|
this.apiNameToKeyPrefixMemoryCache[apiName] = keyPrefix;
|
|
@@ -15213,6 +15459,24 @@ class ObjectInfoService {
|
|
|
15213
15459
|
}
|
|
15214
15460
|
return snapshot.data;
|
|
15215
15461
|
}
|
|
15462
|
+
async readObjectInfoDataFromDurableStore() {
|
|
15463
|
+
const rows = (await this.durableStore.query(`
|
|
15464
|
+
SELECT
|
|
15465
|
+
json_extract(data, '$.apiName') as ApiName,
|
|
15466
|
+
json_extract(data, '$.keyPrefix') as keyPrefix,
|
|
15467
|
+
JSON_EXTRACT(metadata, '$.expirationTimestamp') AS expirationTimestamp
|
|
15468
|
+
from
|
|
15469
|
+
lds_data
|
|
15470
|
+
where
|
|
15471
|
+
key like '%ObjectInfoRepresentation%'`, [])).rows;
|
|
15472
|
+
return rows.map((row) => {
|
|
15473
|
+
return {
|
|
15474
|
+
apiName: row[0],
|
|
15475
|
+
keyPrefix: row[1],
|
|
15476
|
+
expirationTimestamp: row[2],
|
|
15477
|
+
};
|
|
15478
|
+
});
|
|
15479
|
+
}
|
|
15216
15480
|
}
|
|
15217
15481
|
|
|
15218
15482
|
function instrumentGraphQLEval(adapter) {
|
|
@@ -16311,7 +16575,7 @@ class ConflictPool {
|
|
|
16311
16575
|
}
|
|
16312
16576
|
}
|
|
16313
16577
|
|
|
16314
|
-
const DEFAULT_BATCH_SIZE = 500;
|
|
16578
|
+
const DEFAULT_BATCH_SIZE$1 = 500;
|
|
16315
16579
|
const DEFAULT_CONCURRENCY = 6;
|
|
16316
16580
|
const DEFAULT_GQL_QUERY_BATCH_SIZE = 5;
|
|
16317
16581
|
class PrimingSession extends EventEmitter {
|
|
@@ -16319,7 +16583,7 @@ class PrimingSession extends EventEmitter {
|
|
|
16319
16583
|
var _a, _b;
|
|
16320
16584
|
super();
|
|
16321
16585
|
this.useBatchGQL = false;
|
|
16322
|
-
this.batchSize = (_a = config.batchSize) !== null && _a !== void 0 ? _a : DEFAULT_BATCH_SIZE;
|
|
16586
|
+
this.batchSize = (_a = config.batchSize) !== null && _a !== void 0 ? _a : DEFAULT_BATCH_SIZE$1;
|
|
16323
16587
|
this.concurrency = (_b = config.concurrency) !== null && _b !== void 0 ? _b : DEFAULT_CONCURRENCY;
|
|
16324
16588
|
this.recordLoader = config.recordLoader;
|
|
16325
16589
|
this.recordIngestor = config.recordIngestor;
|
|
@@ -16940,10 +17204,6 @@ class NimbusPrimingNetworkAdapter {
|
|
|
16940
17204
|
// ref: https://gnome.pages.gitlab.gnome.org/tracker/docs/developer/limits.html?gi-language=c
|
|
16941
17205
|
const SQLITE_MAX_VARIABLE_NUMBER = 999;
|
|
16942
17206
|
const PARAMS_PER_RECORD = 3;
|
|
16943
|
-
/**
|
|
16944
|
-
* No key builder (or adapter) exists for the object info directory, we need to build the key manually
|
|
16945
|
-
*/
|
|
16946
|
-
const ObjectInfoDirectoryKey = `${UiApiNamespace}::${ObjectInfoDirectoryEntryRepresentationType}:`;
|
|
16947
17207
|
// We need to batch the records to avoid hitting the SQLITE_MAX_VARIABLE_NUMBER limit. Each record has 3 parameters
|
|
16948
17208
|
const BATCH_SIZE = Math.floor(SQLITE_MAX_VARIABLE_NUMBER / PARAMS_PER_RECORD);
|
|
16949
17209
|
class SqlitePrimingStore {
|
|
@@ -17008,44 +17268,6 @@ class SqlitePrimingStore {
|
|
|
17008
17268
|
};
|
|
17009
17269
|
}
|
|
17010
17270
|
}
|
|
17011
|
-
async readObjectInfoDirectory() {
|
|
17012
|
-
const sql = 'SELECT data FROM lds_data WHERE key = ?';
|
|
17013
|
-
const params = [ObjectInfoDirectoryKey];
|
|
17014
|
-
const result = await this.store.query(sql, params);
|
|
17015
|
-
if (result.rows.length === 1) {
|
|
17016
|
-
return JSON.parse(result.rows[0][0]);
|
|
17017
|
-
}
|
|
17018
|
-
return undefined;
|
|
17019
|
-
}
|
|
17020
|
-
async readObjectApiNames() {
|
|
17021
|
-
const sql = 'SELECT key FROM lds_data WHERE key like ?';
|
|
17022
|
-
const params = [`%${ObjectInfoRepresentationType}%`];
|
|
17023
|
-
const result = await this.store.query(sql, params);
|
|
17024
|
-
const apiNames = new Set();
|
|
17025
|
-
result.rows.forEach((row) => {
|
|
17026
|
-
const key = row[0];
|
|
17027
|
-
const parts = key.split(':');
|
|
17028
|
-
apiNames.add(parts[parts.length - 1]);
|
|
17029
|
-
});
|
|
17030
|
-
return apiNames;
|
|
17031
|
-
}
|
|
17032
|
-
writeObjectInfoDirectory(directory) {
|
|
17033
|
-
const sql = 'INSERT or IGNORE into lds_data (key, data) values (?, ?)';
|
|
17034
|
-
const params = [ObjectInfoDirectoryKey, JSON.stringify(directory)];
|
|
17035
|
-
return this.store.query(sql, params).then(() => { });
|
|
17036
|
-
}
|
|
17037
|
-
writeObjectInfos(objectInfos) {
|
|
17038
|
-
const sql = `INSERT or IGNORE into lds_data (key, data) values ${objectInfos
|
|
17039
|
-
.map(() => '(?, ?)')
|
|
17040
|
-
.join(',')};`;
|
|
17041
|
-
const params = [];
|
|
17042
|
-
objectInfos.forEach((objectInfo) => {
|
|
17043
|
-
const key = keyBuilderObjectInfo(this.getLuvio(), { apiName: objectInfo.apiName });
|
|
17044
|
-
params.push(key);
|
|
17045
|
-
params.push(JSON.stringify(objectInfo));
|
|
17046
|
-
});
|
|
17047
|
-
return this.store.query(sql, params).then(() => { });
|
|
17048
|
-
}
|
|
17049
17271
|
}
|
|
17050
17272
|
function batchArray(arr, batchSize = BATCH_SIZE) {
|
|
17051
17273
|
const batches = [];
|
|
@@ -17120,9 +17342,7 @@ function primingSessionFactory(config) {
|
|
|
17120
17342
|
recordLoader,
|
|
17121
17343
|
recordIngestor,
|
|
17122
17344
|
store: primingStore,
|
|
17123
|
-
objectInfoLoader:
|
|
17124
|
-
getObjectInfos: objectInfoService.getObjectInfos.bind(objectInfoService),
|
|
17125
|
-
},
|
|
17345
|
+
objectInfoLoader: objectInfoService,
|
|
17126
17346
|
concurrency: config.concurrency,
|
|
17127
17347
|
batchSize: config.batchSize,
|
|
17128
17348
|
ldsRecordRefresher: new LdsPrimingRecordRefresher(config.getRecords),
|
|
@@ -17288,4 +17508,4 @@ register({
|
|
|
17288
17508
|
});
|
|
17289
17509
|
|
|
17290
17510
|
export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
17291
|
-
// version: 1.
|
|
17511
|
+
// version: 1.249.0-11c3e1ed5
|