diff --git a/services/gunDB/Mediator/index.js b/services/gunDB/Mediator/index.js index 98bafe55..f8fc73ec 100644 --- a/services/gunDB/Mediator/index.js +++ b/services/gunDB/Mediator/index.js @@ -1303,6 +1303,7 @@ const register = async (alias, pass) => { await API.Actions.setDisplayName('anon' + pub.slice(0, 8), user) await API.Actions.generateHandshakeAddress() await API.Actions.generateOrderAddress(user) + await API.Actions.initWall() await API.Actions.setBio('A little bit about myself.', user) return pub }) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 1998d24a..a0ae6171 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1269,7 +1269,15 @@ const createPost = async (tags, title, content) => { v => typeof v !== 'number' ) - return typeof maybeNumOfPages === 'number' ? maybeNumOfPages : 0 + if (typeof maybeNumOfPages !== 'number') { + throw new TypeError( + `Could not fetch number of pages from wall, instead got: ${JSON.stringify( + maybeNumOfPages + )}` + ) + } + + return maybeNumOfPages })() let pageIdx = Math.max(0, numOfPages - 1).toString() @@ -1502,6 +1510,62 @@ const unfollow = publicKey => }) }) +/** + * @throws {Error} + * @returns {Promise} + */ +const initWall = async () => { + const user = require('../Mediator').getUser() + + await new Promise((res, rej) => { + user + .get(Key.WALL) + .get(Key.NUM_OF_PAGES) + .put(0, ack => { + if (ack.err) { + rej(new Error(ack.err)) + } else { + res() + } + }) + }) + + await new Promise((res, rej) => { + user + .get(Key.WALL) + .get(Key.PAGES) + .get('0') + .get(Key.POSTS) + .put( + { + unused: null + }, + ack => { + if (ack.err) { + rej(new Error(ack.err)) + } else { + res() + } + } + ) + }) + + await new Promise((res, rej) => { + user + .get(Key.WALL) + .get(Key.PAGES) + .get('0') + .get(Key.COUNT) + .put(0, ack => { + if (ack.err) { + rej(new Error(ack.err)) + } else { + res() + } + }) + }) +} + module.exports = { __createOutgoingFeed, acceptRequest, @@ -1524,5 +1588,6 @@ module.exports = { createPost, deletePost, follow, - unfollow + unfollow, + initWall } diff --git a/services/gunDB/contact-api/getters/user.js b/services/gunDB/contact-api/getters/user.js index fdcd7dfb..8f1d9cf2 100644 --- a/services/gunDB/contact-api/getters/user.js +++ b/services/gunDB/contact-api/getters/user.js @@ -12,8 +12,8 @@ const Utils = require('../utils') */ const getAnUser = async publicKey => { const oldProfile = await Utils.tryAndWait( - g => { - const user = g.get(`~${publicKey}`) + (g, u) => { + const user = u._.sea.pub === publicKey ? u : g.user(publicKey) return new Promise(res => user.get(Key.PROFILE).load(res)) }, @@ -21,25 +21,29 @@ const getAnUser = async publicKey => { ) const bio = await Utils.tryAndWait( - g => - g - .get(`~${publicKey}`) - .get(Key.BIO) - .then(), + (g, u) => { + const user = u._.sea.pub === publicKey ? u : g.user(publicKey) + + return user.get(Key.BIO).then() + }, v => typeof v !== 'string' ) const lastSeenApp = await Utils.tryAndWait( - g => - g - .get(`~${publicKey}`) - .get(Key.LAST_SEEN_APP) - .then(), + (g, u) => { + const user = u._.sea.pub === publicKey ? u : g.user(publicKey) + + return user.get(Key.LAST_SEEN_APP).then() + }, v => typeof v !== 'number' ) const lastSeenNode = await Utils.tryAndWait( - (_, user) => user.get(Key.LAST_SEEN_NODE).then(), + (g, u) => { + const user = u._.sea.pub === publicKey ? u : g.user(publicKey) + + return user.get(Key.LAST_SEEN_NODE).then() + }, v => typeof v !== 'number' ) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 73eb210f..9ac3c6fb 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -15,7 +15,14 @@ const Wall = require('./user') const getWallTotalPages = async publicKey => { const totalPages = await Utils.tryAndWait( (gun, u) => { - const user = publicKey ? gun.get(`~${publicKey}`) : u + /** + * @type {import('../SimpleGUN').GUNNode} + */ + let user = u + + if (publicKey && u._.sea.pub !== publicKey) { + user = gun.user(publicKey) + } return user .get(Key.WALL) @@ -44,18 +51,63 @@ const getWallPage = async (page, publicKey) => { ) } + const empty = { + count: 0, + posts: {} + } + + if (totalPages === 0) { + return empty + } + const actualPageIdx = page < 0 ? totalPages + page : page - 1 if (actualPageIdx > totalPages - 1) { throw new RangeError(`Requested a page out of bounds`) } + /** + * @type {number} + */ + // @ts-ignore + const count = await Utils.tryAndWait( + (g, u) => { + /** + * @type {import('../SimpleGUN').GUNNode} + */ + let user = u + + if (publicKey && u._.sea.pub !== publicKey) { + user = g.user(publicKey) + } + + return user + .get(Key.WALL) + .get(Key.PAGES) + .get(actualPageIdx.toString()) + .get(Key.COUNT) + .then() + }, + v => typeof v !== 'number' + ) + + if (count === 0) { + return empty + } + /** * @type {Common.SchemaTypes.WallPage} */ const thePage = await Utils.tryAndWait( (g, u) => { - const user = publicKey ? g.get(`~${publicKey}`) : u + /** + * @type {import('../SimpleGUN').GUNNode} + */ + let user = u + + if (publicKey && u._.sea.pub !== publicKey) { + user = g.user(publicKey) + } return new Promise(res => { user diff --git a/services/gunDB/contact-api/utils/index.js b/services/gunDB/contact-api/utils/index.js index 28dc0ebb..f35964ce 100644 --- a/services/gunDB/contact-api/utils/index.js +++ b/services/gunDB/contact-api/utils/index.js @@ -98,13 +98,14 @@ const tryAndWait = async (promGen, shouldRetry = () => false) => { if (shouldRetry(resolvedValue)) { logger.info( 'force retrying' + - ` args: ${promGen.toString()} -- ${shouldRetry.toString()}` + ` args: ${promGen.toString()} -- ${shouldRetry.toString()} \n resolvedValue: ${resolvedValue}, type: ${typeof resolvedValue}` ) } else { return resolvedValue } } catch (e) { logger.error(e) + logger.info(JSON.stringify(e)) if (e.message === 'NOT_AUTH') { throw e } @@ -128,7 +129,7 @@ const tryAndWait = async (promGen, shouldRetry = () => false) => { if (shouldRetry(resolvedValue)) { logger.info( 'force retrying' + - ` args: ${promGen.toString()} -- ${shouldRetry.toString()}` + ` args: ${promGen.toString()} -- ${shouldRetry.toString()} \n resolvedValue: ${resolvedValue}, type: ${typeof resolvedValue}` ) } else { return resolvedValue