@oap75/api
Version:
JavaScript API for Subsocial blockchain.
198 lines (197 loc) • 9.57 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadAndSetPostRelatedStructs = void 0;
const common_1 = require("./common");
const utils_1 = require("@subsocial/utils");
const filters_1 = require("../filters");
function loadRelatedStructs(posts, finders, opts) {
return __awaiter(this, void 0, void 0, function* () {
const { withSpace, withOwner } = opts || {};
const { findSpaces, findPosts, findProfiles } = finders;
const ownerByIdMap = new Map();
const spaceByIdMap = new Map();
const postByIdMap = new Map();
posts.forEach(x => postByIdMap.set(x.struct.id.toString(), x));
const postStructs = [];
const extPostStructs = [];
const rootPosts = [];
const extPosts = [];
const rootIds = [];
const extIds = [];
const ownerIds = [];
const spaceIds = [];
// Key - serialized id of root post of comment.
// Value - indices of the posts that have this root post in `extPostStructs` array.
const postIndicesByRootIdMap = new Map();
// Key - serialized id of a shared original post or root post of a comment.
// Value - indices of the posts that share this original post or comments that are replies to root post in postStructs array.
const postIndicesByExtIdMap = new Map();
// Key - serialized id of a post owner.
// Value - indices of the posts that have the same owner (as key) in `posts` array.
const postIndicesByOwnerIdMap = new Map();
// Key - serialized id of a space.
// Value - indices of the posts that have the same space (as key) in `posts` array.
const postIndicesBySpaceIdMap = new Map();
// Post id can be either extension or root post
const rememberPostIdAndMapToPostIndices = (post, postIndex, resultIndicesByPostIdMap, posts, postIds) => {
const extId = (0, common_1.getPostIdFromExtension)(post);
const extIdStr = extId === null || extId === void 0 ? void 0 : extId.toString();
if (extId && (0, utils_1.nonEmptyStr)(extIdStr)) {
let postIdxs = resultIndicesByPostIdMap.get(extIdStr);
if ((0, utils_1.notDefined)(postIdxs)) {
postIdxs = [];
resultIndicesByPostIdMap.set(extIdStr, postIdxs);
const currentPost = postByIdMap.get(extIdStr);
if (currentPost) {
posts.push(currentPost);
}
else {
postIds.push(extId);
}
}
postIdxs.push(postIndex);
}
};
// Related id can be either space id or owner id
function rememberRelatedIdAndMapToPostIndices(relatedId, postIndex, postIndicesByRelatedIdMap, relatedIds) {
if ((0, utils_1.isDefined)(relatedId)) {
const idStr = relatedId.toString();
let postIdxs = postIndicesByRelatedIdMap.get(idStr);
if ((0, utils_1.notDefined)(postIdxs)) {
postIdxs = [];
postIndicesByOwnerIdMap.set(idStr, postIdxs);
relatedIds.push(relatedId);
}
postIdxs.push(postIndex);
}
}
function setExtOnPost(ext, resultIndicesByPostIdMap, postStructs) {
const extId = ext.post.struct.id.toString();
postByIdMap.set(extId, ext.post);
const idxs = resultIndicesByPostIdMap.get(extId) || [];
idxs.forEach(idx => {
postStructs[idx].ext = ext;
});
}
posts.forEach((post, i) => {
postStructs.push({ post });
rememberPostIdAndMapToPostIndices(post, i, postIndicesByExtIdMap, extPosts, extIds);
if (withOwner) {
const ownerId = post.struct.created.account;
rememberRelatedIdAndMapToPostIndices(ownerId, i, postIndicesByOwnerIdMap, ownerIds);
}
if (withSpace) {
const spaceId = post.struct.spaceId.unwrapOr(undefined);
spaceId && rememberRelatedIdAndMapToPostIndices(spaceId, i, postIndicesBySpaceIdMap, spaceIds);
}
});
const loadedExtPosts = yield findPosts(extIds);
extPosts.push(...loadedExtPosts);
extPosts.forEach((post, i) => {
extPostStructs.push({ post });
setExtOnPost(extPostStructs[i], postIndicesByExtIdMap, postStructs);
if (withOwner) {
const ownerId = post.struct.created.account;
ownerIds.push(ownerId);
}
if (withSpace) {
const spaceId = post.struct.spaceId.unwrapOr(undefined);
if ((0, utils_1.isDefined)(spaceId)) {
spaceIds.push(spaceId);
}
else {
rememberPostIdAndMapToPostIndices(post, i, postIndicesByRootIdMap, rootPosts, rootIds);
}
}
});
const loadedRootPosts = yield findPosts(rootIds);
rootPosts.push(...loadedRootPosts);
rootPosts.forEach((post, i) => {
setExtOnPost({ post }, postIndicesByRootIdMap, extPostStructs);
if (withSpace) {
const spaceId = post.struct.spaceId.unwrapOr(undefined);
spaceId && rememberRelatedIdAndMapToPostIndices(spaceId, i, postIndicesBySpaceIdMap, spaceIds);
}
});
// Load related owners
if (withOwner) {
const owners = yield findProfiles(ownerIds);
owners.forEach(owner => {
var _a;
const ownerId = (_a = owner.profile) === null || _a === void 0 ? void 0 : _a.created.account.toString();
ownerId && ownerByIdMap.set(ownerId, owner);
});
}
// Load related spaces
if (withSpace) {
const spaces = yield findSpaces(spaceIds);
spaces.forEach(space => {
const spaceId = space.struct.id.toString();
spaceId && spaceByIdMap.set(spaceId, space);
});
}
return {
postStructs,
spaceByIdMap,
ownerByIdMap
};
});
}
/** Load post structs and related structs like owner profile, space, root post if required. */
function loadAndSetPostRelatedStructs(posts, finders, opts) {
return __awaiter(this, void 0, void 0, function* () {
const { withSpace, withOwner, visibility } = opts || {};
const { spaceByIdMap, ownerByIdMap, postStructs } = yield loadRelatedStructs(posts, finders, opts);
const setOwnerOnPost = (postStruct) => {
if (!withOwner)
return;
const { post, ext } = postStruct;
const ownerId = post.struct.created.account.toHuman();
const owner = ownerByIdMap.get(ownerId);
postStruct.owner = owner;
if (!ext)
return;
const extOwnerId = ext.post.struct.created.account.toHuman();
ext.owner = extOwnerId === ownerId
? owner
: ownerByIdMap.get(extOwnerId);
};
const setSpaceOnPost = (post, spaceId, ext) => {
if (!withSpace || !spaceId)
return;
const space = spaceByIdMap.get(spaceId.toString());
if (!post.space) {
post.space = space;
}
if (ext) {
ext.space = space;
}
};
postStructs.forEach(post => {
var _a;
const { post: { struct: { spaceId: spaceIdOpt } }, ext } = post;
setOwnerOnPost(post);
// Set a space if the post has space id:
setSpaceOnPost(post, spaceIdOpt.unwrapOr(undefined));
// Set a space (from extension) on post and its extension if extension has space id:
const spaceId = ext === null || ext === void 0 ? void 0 : ext.post.struct.spaceId.unwrapOr(undefined);
setSpaceOnPost(post, spaceId, ext);
if (!spaceId) {
// Set a space (from root post) on post and its extension if extension does NOT have space id:
const spaceId = (_a = ext === null || ext === void 0 ? void 0 : ext.ext) === null || _a === void 0 ? void 0 : _a.post.struct.spaceId.unwrapOr(undefined);
setSpaceOnPost(post, spaceId, ext);
}
});
return withSpace && visibility === 'onlyVisible' ? postStructs.filter(({ space }) => (0, filters_1.isVisible)(space === null || space === void 0 ? void 0 : space.struct)) : postStructs;
});
}
exports.loadAndSetPostRelatedStructs = loadAndSetPostRelatedStructs;