@overmap-ai/core 1.0.58-asset-description.5 → 1.0.58-asset-description.7

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.
@@ -5378,6 +5378,16 @@ class CategoryService extends BaseApiService {
5378
5378
  store.dispatch(setCategories(result));
5379
5379
  }
5380
5380
  }
5381
+ function chunkArray(arr, chunkSize) {
5382
+ const chunks = [];
5383
+ let index2 = 0;
5384
+ const arrLength = arr.length;
5385
+ while (index2 < arrLength) {
5386
+ chunks.push(arr.slice(index2, index2 += chunkSize));
5387
+ }
5388
+ return chunks;
5389
+ }
5390
+ const BULK_ADD_ASSET_BATCH_SIZE = 1e3;
5381
5391
  class AssetService extends BaseApiService {
5382
5392
  // Basic CRUD functions
5383
5393
  add(asset, workspaceId) {
@@ -5454,36 +5464,49 @@ class AssetService extends BaseApiService {
5454
5464
  throw err;
5455
5465
  });
5456
5466
  }
5457
- async addBatch(assetsToCreate, workspaceId, assetTypeId) {
5467
+ addBulk(assetsToCreate, workspaceId, assetTypeId) {
5468
+ const { store } = this.client;
5458
5469
  const fullAssets = assetsToCreate.map((asset) => {
5459
5470
  return { ...offline(asset), submitted_at: (/* @__PURE__ */ new Date()).toISOString() };
5460
5471
  });
5461
- const { store } = this.client;
5462
- store.dispatch(addAssetsInBatches(fullAssets));
5463
- const promise = this.client.enqueueRequest({
5464
- description: "Batch create assets",
5465
- method: HttpMethod.POST,
5466
- url: `/assets/types/${assetTypeId}/add-assets/`,
5467
- queryParams: {
5468
- workspace_id: workspaceId.toString()
5469
- },
5470
- payload: {
5471
- assets: fullAssets
5472
- },
5473
- blockers: [assetTypeId],
5474
- blocks: fullAssets.map((c) => c.offline_id)
5475
- });
5476
- void promise.then((result) => {
5477
- for (const assets of Object.values(result)) {
5478
- store.dispatch(updateAsset(assets));
5479
- }
5480
- }).catch((e) => {
5481
- for (const asset of fullAssets) {
5482
- store.dispatch(removeAsset(asset.offline_id));
5483
- }
5484
- throw e;
5472
+ const assetBatches = chunkArray(fullAssets, BULK_ADD_ASSET_BATCH_SIZE).map((assetBatch) => {
5473
+ return {
5474
+ batchId: v4(),
5475
+ payload: {
5476
+ assets: assetBatch
5477
+ }
5478
+ };
5485
5479
  });
5486
- return promise;
5480
+ store.dispatch(addAssetsInBatches(fullAssets));
5481
+ let prevBatchId = null;
5482
+ const batchPromises = Promise.all(
5483
+ assetBatches.map((assetBatch) => {
5484
+ const { batchId, payload } = assetBatch;
5485
+ const promise = this.client.enqueueRequest({
5486
+ description: "Batch create assets",
5487
+ method: HttpMethod.POST,
5488
+ url: `/assets/types/${assetTypeId}/add-assets/`,
5489
+ queryParams: {
5490
+ workspace_id: workspaceId.toString()
5491
+ },
5492
+ payload,
5493
+ blockers: prevBatchId ? [assetTypeId, prevBatchId] : [assetTypeId],
5494
+ blocks: assetBatch.payload.assets.map((c) => c.offline_id).concat([batchId])
5495
+ });
5496
+ promise.then((result) => {
5497
+ for (const assets of Object.values(result)) {
5498
+ store.dispatch(updateAsset(assets));
5499
+ }
5500
+ }).catch(() => {
5501
+ for (const asset of assetBatch.payload.assets) {
5502
+ store.dispatch(removeAsset(asset.offline_id));
5503
+ }
5504
+ });
5505
+ prevBatchId = assetBatch.batchId;
5506
+ return promise;
5507
+ })
5508
+ );
5509
+ return [fullAssets, batchPromises.then((result) => result)];
5487
5510
  }
5488
5511
  async refreshStore() {
5489
5512
  const { store } = this.client;
@@ -7269,6 +7292,7 @@ const separateFilesFromValues = (values) => {
7269
7292
  }
7270
7293
  return { values: newValues, files };
7271
7294
  };
7295
+ const MAX_BULK_ADD_SUBMISSIONS = 1e3;
7272
7296
  class UserFormSubmissionService extends BaseApiService {
7273
7297
  constructor() {
7274
7298
  super(...arguments);
@@ -7355,103 +7379,129 @@ class UserFormSubmissionService extends BaseApiService {
7355
7379
  const offlineSubmissions = [];
7356
7380
  const offlineAttachments = [];
7357
7381
  const submissionOfflineIds = [];
7358
- const submissionsPayload = [];
7359
- const attachmentsPayload = [];
7360
- let files = {};
7382
+ const allFilesRecord = {};
7361
7383
  const { values: fileSeperatedCommonFieldValues, files: commonFiles } = separateFilesFromValues(commonFieldValues);
7362
- files = commonFiles;
7363
7384
  const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
7364
7385
  const createdBy = store.getState().userReducer.currentUser.id;
7365
- for (const assetId in fieldValuesByAsset) {
7366
- const { values: fileSeperatedSubmissionSpecificValues, files: submissionSpecificFiles } = separateFilesFromValues(fieldValuesByAsset[assetId] ?? {});
7367
- files = Object.assign(files, submissionSpecificFiles);
7368
- const submissionValues = { ...fileSeperatedCommonFieldValues, ...fileSeperatedSubmissionSpecificValues };
7369
- const submission = offline({
7370
- form_revision: formRevision,
7371
- values: submissionValues,
7372
- created_by: createdBy,
7373
- submitted_at: submittedAt,
7374
- asset: assetId
7375
- });
7376
- submissionOfflineIds.push(submission.offline_id);
7377
- submissionsPayload.push({
7378
- offline_id: submission.offline_id,
7379
- asset_id: assetId,
7380
- form_data: fileSeperatedSubmissionSpecificValues
7381
- });
7382
- offlineSubmissions.push(submission);
7383
- for (const [fieldIdentifier, fileArray] of Object.entries(files)) {
7384
- for (const file of fileArray) {
7385
- const sha1 = await hashFile(file);
7386
- await this.client.files.addCache(file, sha1);
7387
- const offlineAttachment = offline({
7388
- file_name: file.name,
7389
- file_sha1: sha1,
7390
- file: URL.createObjectURL(file),
7391
- submission: submission.offline_id,
7392
- field_identifier: fieldIdentifier
7386
+ const assetIdBatches = chunkArray(Object.keys(fieldValuesByAsset), MAX_BULK_ADD_SUBMISSIONS);
7387
+ const bulkAddBatches = await Promise.all(
7388
+ assetIdBatches.map(async (assetIdBatch) => {
7389
+ const batchId = v4();
7390
+ const submissionsPayload = [];
7391
+ const attachmentsPayload = [];
7392
+ let files = { ...commonFiles };
7393
+ for (const assetId of assetIdBatch) {
7394
+ const { values: fileSeperatedSubmissionSpecificValues, files: submissionSpecificFiles } = separateFilesFromValues(fieldValuesByAsset[assetId] ?? {});
7395
+ files = Object.assign(files, submissionSpecificFiles);
7396
+ const submissionValues = {
7397
+ ...fileSeperatedCommonFieldValues,
7398
+ ...fileSeperatedSubmissionSpecificValues
7399
+ };
7400
+ const submission = offline({
7401
+ form_revision: formRevision,
7402
+ values: submissionValues,
7403
+ created_by: createdBy,
7404
+ submitted_at: submittedAt,
7405
+ asset: assetId
7393
7406
  });
7394
- offlineAttachments.push(offlineAttachment);
7395
- attachmentsPayload.push({
7396
- offline_id: offlineAttachment.offline_id,
7397
- submission_id: submission.offline_id,
7398
- sha1,
7399
- name: file.name,
7400
- field_identifier: fieldIdentifier
7407
+ submissionOfflineIds.push(submission.offline_id);
7408
+ submissionsPayload.push({
7409
+ offline_id: submission.offline_id,
7410
+ asset_id: assetId,
7411
+ form_data: fileSeperatedSubmissionSpecificValues
7401
7412
  });
7413
+ offlineSubmissions.push(submission);
7414
+ for (const [fieldIdentifier, fileArray] of Object.entries(files)) {
7415
+ for (const file of fileArray) {
7416
+ const sha1 = await hashFile(file);
7417
+ await this.client.files.addCache(file, sha1);
7418
+ const offlineAttachment = offline({
7419
+ file_name: file.name,
7420
+ file_sha1: sha1,
7421
+ file: URL.createObjectURL(file),
7422
+ submission: submission.offline_id,
7423
+ field_identifier: fieldIdentifier
7424
+ });
7425
+ offlineAttachments.push(offlineAttachment);
7426
+ attachmentsPayload.push({
7427
+ offline_id: offlineAttachment.offline_id,
7428
+ submission_id: submission.offline_id,
7429
+ sha1,
7430
+ name: file.name,
7431
+ field_identifier: fieldIdentifier
7432
+ });
7433
+ }
7434
+ }
7402
7435
  }
7403
- }
7404
- }
7405
- const filesRecord = {};
7406
- for (const file of Object.values(files).flat()) {
7407
- const sha1 = await hashFile(file);
7408
- filesRecord[sha1] = {
7409
- sha1,
7410
- extension: file.name.split(".").pop() || "",
7411
- file_type: file.type,
7412
- size: file.size
7413
- };
7414
- }
7436
+ const filePaylods = [];
7437
+ for (const file of Object.values(files).flat()) {
7438
+ const sha1 = await hashFile(file);
7439
+ const filePayload = {
7440
+ sha1,
7441
+ extension: file.name.split(".").pop() || "",
7442
+ file_type: file.type,
7443
+ size: file.size
7444
+ };
7445
+ allFilesRecord[sha1] = filePayload;
7446
+ filePaylods.push(filePayload);
7447
+ }
7448
+ return {
7449
+ batchId,
7450
+ payload: {
7451
+ form_data: fileSeperatedCommonFieldValues,
7452
+ submitted_at: submittedAt,
7453
+ submissions: submissionsPayload,
7454
+ attachments: attachmentsPayload,
7455
+ files: filePaylods
7456
+ }
7457
+ };
7458
+ })
7459
+ );
7415
7460
  store.dispatch(addFormSubmissions(offlineSubmissions));
7416
7461
  store.dispatch(addFormSubmissionAttachments(offlineAttachments));
7417
- const promise = this.client.enqueueRequest({
7418
- description: "Bulk add form submissions",
7419
- method: HttpMethod.POST,
7420
- url: `/forms/revisions/${formRevision}/bulk-respond/`,
7421
- payload: {
7422
- form_data: fileSeperatedCommonFieldValues,
7423
- submitted_at: submittedAt,
7424
- submissions: submissionsPayload,
7425
- attachments: attachmentsPayload,
7426
- files: Object.values(filesRecord)
7427
- },
7428
- blockers: Object.keys(fieldValuesByAsset),
7429
- blocks: submissionOfflineIds
7430
- });
7431
- promise.then(({ submissions, attachments, presigned_urls }) => {
7432
- store.dispatch(updateFormSubmissions(submissions));
7433
- store.dispatch(updateFormSubmissionAttachments(attachments));
7434
- for (const [sha1, presigned_url] of Object.entries(presigned_urls)) {
7435
- const file = filesRecord[sha1];
7436
- if (!file)
7437
- continue;
7438
- void this.client.enqueueRequest({
7439
- url: presigned_url.url,
7440
- description: "Upload file",
7462
+ let prevBatchId = null;
7463
+ const batchPromises = Promise.all(
7464
+ bulkAddBatches.map((batch) => {
7465
+ const { payload, batchId } = batch;
7466
+ const batchAssetIds = payload.submissions.map((x) => x.asset_id);
7467
+ const batchSubmissionOfflineIds = payload.submissions.map((x) => x.offline_id);
7468
+ const batchAttachmentsOfflineIds = payload.attachments.map((x) => x.offline_id);
7469
+ const promise = this.client.enqueueRequest({
7470
+ description: "Bulk add form submissions",
7441
7471
  method: HttpMethod.POST,
7442
- isExternalUrl: true,
7443
- isAuthNeeded: false,
7444
- attachmentHash: sha1,
7445
- blockers: [`s3-${file.sha1}.${file.extension}`],
7446
- blocks: [sha1],
7447
- s3url: presigned_url
7472
+ url: `/forms/revisions/${formRevision}/bulk-respond/`,
7473
+ payload,
7474
+ blockers: prevBatchId ? batchAssetIds.concat([prevBatchId]) : batchAssetIds,
7475
+ blocks: batchSubmissionOfflineIds.concat([batchId])
7448
7476
  });
7449
- }
7450
- }).catch(() => {
7451
- store.dispatch(deleteFormSubmissions(submissionOfflineIds));
7452
- store.dispatch(deleteFormSubmissionAttachments(offlineAttachments.map((x) => x.offline_id)));
7453
- });
7454
- return [offlineSubmissions, promise.then(({ submissions }) => submissions)];
7477
+ promise.then(({ submissions, attachments, presigned_urls }) => {
7478
+ store.dispatch(updateFormSubmissions(submissions));
7479
+ store.dispatch(updateFormSubmissionAttachments(attachments));
7480
+ for (const [sha1, presigned_url] of Object.entries(presigned_urls)) {
7481
+ const file = allFilesRecord[sha1];
7482
+ if (!file)
7483
+ continue;
7484
+ void this.client.enqueueRequest({
7485
+ url: presigned_url.url,
7486
+ description: "Upload file",
7487
+ method: HttpMethod.POST,
7488
+ isExternalUrl: true,
7489
+ isAuthNeeded: false,
7490
+ attachmentHash: sha1,
7491
+ blockers: [`s3-${file.sha1}.${file.extension}`],
7492
+ blocks: [sha1],
7493
+ s3url: presigned_url
7494
+ });
7495
+ }
7496
+ }).catch(() => {
7497
+ store.dispatch(deleteFormSubmissions(batchSubmissionOfflineIds));
7498
+ store.dispatch(deleteFormSubmissionAttachments(batchAttachmentsOfflineIds));
7499
+ });
7500
+ prevBatchId = batchId;
7501
+ return promise;
7502
+ })
7503
+ );
7504
+ return [offlineSubmissions, batchPromises.then((results) => results.map(({ submissions }) => submissions))];
7455
7505
  }
7456
7506
  update(submission) {
7457
7507
  const { store } = this.client;