Skip to content

Commit

Permalink
Merge pull request #164 from Akord-com/simultaneous-akord-calls
Browse files Browse the repository at this point in the history
fix: use fresh service instance for akord calls
  • Loading branch information
wkolod authored Aug 22, 2023
2 parents c0ca043 + 454cd8f commit 0c32091
Show file tree
Hide file tree
Showing 12 changed files with 589 additions and 543 deletions.
9 changes: 6 additions & 3 deletions src/core/batch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Node, NodeLike, NodeType, Stack } from "../types/node";
import { FileLike } from "../types/file";
import { BatchMembershipInviteResponse, BatchStackCreateResponse } from "../types/batch-response";
import { Membership, RoleType } from "../types/membership";
import { Hooks } from "./file";
import { FileService, Hooks } from "./file";
import { actionRefs, functions, objectType, protocolTags } from "../constants";
import { ContractInput, Tag, Tags } from "../types/contract";
import { ObjectType } from "../types/object";
Expand Down Expand Up @@ -152,7 +152,6 @@ class BatchService extends Service {
// upload file data & metadata
Promise.all(chunk.map(async (item) => {
const service = new StackService(this.wallet, this.api, this);
service.setVaultContextForFile();

const nodeId = uuidv4();
service.setObjectId(nodeId);
Expand All @@ -165,9 +164,13 @@ class BatchService extends Service {
service.setParentId(createOptions.parentId);
service.arweaveTags = await service.getTxTags();

const fileService = new FileService(this.wallet, this.api, service);
const fileUploadResult = await fileService.create(item.file, createOptions);
const version = await fileService.newVersion(item.file, fileUploadResult);

const state = {
name: await service.processWriteString(item.name ? item.name : item.file.name),
versions: [await service.uploadNewFileVersion(item.file, createOptions)],
versions: [version],
tags: service.tags
};
const id = await service.uploadState(state);
Expand Down
59 changes: 59 additions & 0 deletions src/core/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { ListOptions } from "../types/query-options";
import lodash from "lodash";
import { EncryptionMetadata } from "./service";
import { EncryptedPayload } from "@akord/crypto/lib/types";
import { base64ToArray } from "@akord/crypto";

export const handleListErrors = async <T>(originalItems: Array<T>, promises: Array<Promise<T>>)
: Promise<{ items: Array<T>, errors: Array<{ id: string, error: Error }> }> => {
const results = await Promise.all(promises.map(p => p.catch(e => e)));
const items = results.filter(result => !(result instanceof Error));
const errors = results
.map((result, index) => ({ result, index }))
.filter((mapped) => mapped.result instanceof Error)
.map((filtered) => ({ id: (<any>originalItems[filtered.index]).id, error: filtered.result }));
return { items, errors };
}

export const paginate = async <T>(apiCall: any, listOptions: ListOptions & { vaultId?: string }): Promise<Array<T>> => {
let token = undefined;
let results = [] as T[];
do {
const { items, nextToken } = await apiCall(listOptions);
results = results.concat(items);
token = nextToken;
listOptions.nextToken = nextToken;
if (nextToken === "null") {
token = undefined;
}
} while (token);
return results;
}

export const mergeState = (currentState: any, stateUpdates: any): any => {
let newState = lodash.cloneDeepWith(currentState);
lodash.mergeWith(
newState,
stateUpdates,
function concatArrays(objValue, srcValue) {
if (lodash.isArray(objValue)) {
return objValue.concat(srcValue);
}
});
return newState;
}

export const getEncryptedPayload = (data: ArrayBuffer | string, metadata: EncryptionMetadata)
: EncryptedPayload => {
const { encryptedKey, iv } = metadata;
if (encryptedKey && iv) {
return {
encryptedKey,
encryptedData: {
iv: base64ToArray(iv),
ciphertext: data as ArrayBuffer
}
}
}
return null;
}
1 change: 0 additions & 1 deletion src/core/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ class ContractService extends Service {
*/
public async getState(id: string): Promise<ContractState> {
const contract = await this.api.getContractState(id);
this.setIsPublic(contract.public);
if (contract.public) {
return contract;
} else {
Expand Down
44 changes: 32 additions & 12 deletions src/core/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { BinaryLike } from "crypto";
import { getTxData, getTxMetadata } from "../arweave";
import * as mime from "mime-types";
import { CONTENT_TYPE as MANIFEST_CONTENT_TYPE, FILE_TYPE as MANIFEST_FILE_TYPE } from "./manifest";
import { FileVersion } from "../types/node";

const DEFAULT_FILE_TYPE = "text/plain";

Expand All @@ -28,27 +29,27 @@ class FileService extends Service {
* @returns Promise with file buffer
*/
public async get(id: string, vaultId: string, options: DownloadOptions = {}): Promise<ArrayBuffer> {
await this.setVaultContext(vaultId);
const service = new FileService(this.wallet, this.api);
await service.setVaultContext(vaultId);
const downloadOptions = options as FileDownloadOptions;
downloadOptions.public = this.isPublic;
downloadOptions.public = service.isPublic;
let fileBinary: ArrayBuffer;
if (options.isChunked) {
let currentChunk = 0;
while (currentChunk < options.numberOfChunks) {
const url = `${id}_${currentChunk}`;
downloadOptions.loadedSize = currentChunk * this.chunkSize;
const chunkBinary = await this.getBinary(url, downloadOptions);
fileBinary = this.appendBuffer(fileBinary, chunkBinary);
const chunkBinary = await service.getBinary(url, downloadOptions);
fileBinary = service.appendBuffer(fileBinary, chunkBinary);
currentChunk++;
}
} else {
const { fileData, metadata } = await this.api.downloadFile(id, downloadOptions);
fileBinary = await this.processReadRaw(fileData, metadata)
fileBinary = await service.processReadRaw(fileData, metadata)
}
return fileBinary;
}


/**
* Downloads the file keeping memory consumed (RAM) under defiend level: this#chunkSize.
* In browser, streaming of the binary requires self hosting of mitm.html and sw.js
Expand All @@ -59,17 +60,18 @@ class FileService extends Service {
* @returns Promise with file buffer
*/
public async download(id: string, vaultId: string, options: DownloadOptions = {}): Promise<void> {
await this.setVaultContext(vaultId);
const service = new FileService(this.wallet, this.api);
await service.setVaultContext(vaultId);
const downloadOptions = options as FileDownloadOptions;
downloadOptions.public = this.isPublic;
const writer = await this.stream(options.name, options.resourceSize);
downloadOptions.public = service.isPublic;
const writer = await service.stream(options.name, options.resourceSize);
if (options.isChunked) {
let currentChunk = 0;
try {
while (currentChunk < options.numberOfChunks) {
const url = `${id}_${currentChunk}`;
downloadOptions.loadedSize = currentChunk * this.chunkSize;
const fileBinary = await this.getBinary(url, downloadOptions);
downloadOptions.loadedSize = currentChunk * service.chunkSize;
const fileBinary = await service.getBinary(url, downloadOptions);
if (writer instanceof WritableStreamDefaultWriter) {
await writer.ready
}
Expand All @@ -85,7 +87,7 @@ class FileService extends Service {
await writer.close();
}
} else {
const fileBinary = await this.getBinary(id, downloadOptions);
const fileBinary = await service.getBinary(id, downloadOptions);
await writer.write(new Uint8Array(fileBinary));
await writer.close();
}
Expand Down Expand Up @@ -157,6 +159,24 @@ class FileService extends Service {
}
}

public async newVersion(file: FileLike, uploadResult: FileUploadResult): Promise<FileVersion> {
const version = new FileVersion({
owner: await this.wallet.getAddress(),
createdAt: JSON.stringify(Date.now()),
name: await this.processWriteString(file.name),
type: file.type,
size: file.size,
resourceUri: [
`arweave:${uploadResult.resourceTx}`,
`hash:${uploadResult.resourceHash}`,
`s3:${uploadResult.resourceUrl}`
],
numberOfChunks: uploadResult.numberOfChunks,
chunkSize: uploadResult.chunkSize,
});
return version;
}

private retrieveFileMetadata(fileTxId: string, tags: Tags = [])
: { name: string, type: string } {
const type = this.retrieveFileType(tags);
Expand Down
13 changes: 7 additions & 6 deletions src/core/folder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ class FolderService extends NodeService<Folder> {
* @returns Promise with new folder id & corresponding transaction id
*/
public async create(vaultId: string, name: string, options: NodeCreateOptions = this.defaultCreateOptions): Promise<FolderCreateResult> {
await this.setVaultContext(vaultId);
this.setActionRef(actionRefs.FOLDER_CREATE);
this.setFunction(functions.NODE_CREATE);
this.setAkordTags((this.isPublic ? [name] : []).concat(options.tags));
const service = new FolderService(this.wallet, this.api);
await service.setVaultContext(vaultId);
service.setActionRef(actionRefs.FOLDER_CREATE);
service.setFunction(functions.NODE_CREATE);
service.setAkordTags((service.isPublic ? [name] : []).concat(options.tags));
const state = {
name: await this.processWriteString(name),
name: await service.processWriteString(name),
tags: options.tags || []
}
const { nodeId, transactionId, object } = await this.nodeCreate<Folder>(state, { parentId: options.parentId }, options.arweaveTags);
const { nodeId, transactionId, object } = await service.nodeCreate<Folder>(state, { parentId: options.parentId }, options.arweaveTags);
return { folderId: nodeId, transactionId, object };
}
};
Expand Down
Loading

0 comments on commit 0c32091

Please sign in to comment.