From 087f5bf774897b89509bd456f00742d9d9e2290c Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 4 Oct 2021 11:55:44 +1100 Subject: [PATCH 01/12] guide/example: Demonstrate how to use the store callback option This option is better than using the returned value. This is because the returned value is returned only once **all** pages are received, which can be very long if the `timeFilter` option is not used. --- examples/store-reactjs-chat/src/App.js | 16 +++++--- guides/reactjs-store.md | 52 ++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/examples/store-reactjs-chat/src/App.js b/examples/store-reactjs-chat/src/App.js index 8e7566e05e..47191432e8 100644 --- a/examples/store-reactjs-chat/src/App.js +++ b/examples/store-reactjs-chat/src/App.js @@ -44,15 +44,18 @@ function App() { React.useEffect(() => { if (wakuStatus !== 'Connected') return; + const processMessages = (retrievedMessages) => { + const messages = retrievedMessages.map(decodeMessage).filter(Boolean); + + setMessages((currentMessages) => { + return currentMessages.concat(messages.reverse()); + }); + }; + waku.store - .queryHistory([ContentTopic]) + .queryHistory([ContentTopic], { callback: processMessages }) .catch((e) => { console.log('Failed to retrieve messages', e); - }) - .then((retrievedMessages) => { - const messages = retrievedMessages.map(decodeMessage).filter(Boolean); - - setMessages(messages); }); }, [waku, wakuStatus]); @@ -104,6 +107,7 @@ function formatDate(timestamp) { day: 'numeric', hour: 'numeric', minute: '2-digit', + second: '2-digit', hour12: false, }); } diff --git a/guides/reactjs-store.md b/guides/reactjs-store.md index edccb59ec4..c0c0e38c9f 100644 --- a/guides/reactjs-store.md +++ b/guides/reactjs-store.md @@ -185,7 +185,42 @@ function decodeMessage(wakuMessage) { You now have all the building blocks to retrieve and decode messages for a store node. -Finally, retrieve messages from a store node: +Note that Waku Store queries are paginated. +The API provided by `js-waku` automatically traverses all pages of the Waku Store response. +By default, the most recent page is retrieved first but this can be changed with the `direction` option. + +First, define a React state to save the messages: + +```js +function App() { + const [messages, setMessages] = React.useState([]); + /// [..] +} +``` + +Then, define `processMessages` to decode and then store messages in a React state. +You will pass `processMessages` as a `callback` option to `WakuStore.queryHistory`. +`processMessages` will be called each time a page is received from the Waku Store. + + +```js +const processMessages = (retrievedMessages) => { + const messages = retrievedMessages.map(decodeMessage).filter(Boolean); + + setMessages((currentMessages) => { + return currentMessages.concat(messages.reverse()); + }); +}; +``` + +Finally, pass `processMessage` in `WakuStore.queryHistory` as the `callback` value: + +```js +waku.store + .queryHistory([ContentTopic], { callback: processMessages }); +``` + +All together, you should now have: ```js const ContentTopic = '/toy-chat/2/huilong/proto'; @@ -198,15 +233,18 @@ function App() { React.useEffect(() => { if (wakuStatus !== 'Connected') return; + const processMessages = (retrievedMessages) => { + const messages = retrievedMessages.map(decodeMessage).filter(Boolean); + + setMessages((currentMessages) => { + return currentMessages.concat(messages.reverse()); + }); + }; + waku.store - .queryHistory([ContentTopic]) + .queryHistory([ContentTopic], { callback: processMessages }) .catch((e) => { console.log('Failed to retrieve messages', e); - }) - .then((retrievedMessages) => { - const messages = retrievedMessages.map(decodeMessage).filter(Boolean); - - setMessages(messages); }); }, [waku, wakuStatus]); From f5a0416efd2939362c6cfb303339057b39e60f85 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 4 Oct 2021 12:21:13 +1100 Subject: [PATCH 02/12] Rename to page direction As the direction only affects the page ordering, not the message ordering in the pages. --- CHANGELOG.md | 4 ++++ examples/web-chat/src/App.tsx | 4 ++-- src/index.ts | 2 +- src/lib/waku_store/history_rpc.ts | 16 +++++++++------- src/lib/waku_store/index.node.spec.ts | 4 ++-- src/lib/waku_store/index.ts | 8 ++++---- 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67e107ce43..c4e7a98877 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- **Breaking**: Renamed `WakuStore.QueryOptions`'s `direction` to `pageDirection` (and its type) as it only affects the page ordering, + not the ordering of messages with the page. + ## [0.13.1] - 2021-09-21 ### Fixed diff --git a/examples/web-chat/src/App.tsx b/examples/web-chat/src/App.tsx index bebbe23cc5..bc4eaa9e8d 100644 --- a/examples/web-chat/src/App.tsx +++ b/examples/web-chat/src/App.tsx @@ -1,6 +1,6 @@ import { useEffect, useReducer, useState } from 'react'; import './App.css'; -import { Direction, getBootstrapNodes, Waku, WakuMessage } from 'js-waku'; +import { PageDirection, getBootstrapNodes, Waku, WakuMessage } from 'js-waku'; import handleCommand from './command'; import Room from './Room'; import { WakuContext } from './WakuContext'; @@ -64,7 +64,7 @@ async function retrieveStoreMessages( try { const res = await waku.store.queryHistory([ChatContentTopic], { pageSize: 5, - direction: Direction.FORWARD, + pageDirection: PageDirection.FORWARD, timeFilter: { startTime, endTime, diff --git a/src/index.ts b/src/index.ts index 69c667b160..324459c865 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,6 +20,6 @@ export { export { WakuRelay, RelayCodecs } from './lib/waku_relay'; -export { Direction, WakuStore, StoreCodec } from './lib/waku_store'; +export { PageDirection, WakuStore, StoreCodec } from './lib/waku_store'; export * as proto from './proto'; diff --git a/src/lib/waku_store/history_rpc.ts b/src/lib/waku_store/history_rpc.ts index cdf328fb57..2e2194c981 100644 --- a/src/lib/waku_store/history_rpc.ts +++ b/src/lib/waku_store/history_rpc.ts @@ -3,7 +3,7 @@ import { v4 as uuid } from 'uuid'; import * as proto from '../../proto/waku/v2/store'; -export enum Direction { +export enum PageDirection { BACKWARD = 'backward', FORWARD = 'forward', } @@ -11,7 +11,7 @@ export enum Direction { export interface Params { contentTopics: string[]; pubSubTopic: string; - direction: Direction; + pageDirection: PageDirection; pageSize: number; startTime?: number; endTime?: number; @@ -25,7 +25,7 @@ export class HistoryRPC { * Create History Query. */ static createQuery(params: Params): HistoryRPC { - const direction = directionToProto(params.direction); + const direction = directionToProto(params.pageDirection); const pagingInfo = { pageSize: params.pageSize, cursor: params.cursor, @@ -67,11 +67,13 @@ export class HistoryRPC { } } -function directionToProto(direction: Direction): proto.PagingInfo_Direction { - switch (direction) { - case Direction.BACKWARD: +function directionToProto( + pageDirection: PageDirection +): proto.PagingInfo_Direction { + switch (pageDirection) { + case PageDirection.BACKWARD: return proto.PagingInfo_Direction.DIRECTION_BACKWARD_UNSPECIFIED; - case Direction.FORWARD: + case PageDirection.FORWARD: return proto.PagingInfo_Direction.DIRECTION_FORWARD; default: return proto.PagingInfo_Direction.DIRECTION_BACKWARD_UNSPECIFIED; diff --git a/src/lib/waku_store/index.node.spec.ts b/src/lib/waku_store/index.node.spec.ts index b11daf570f..6fb739a0ac 100644 --- a/src/lib/waku_store/index.node.spec.ts +++ b/src/lib/waku_store/index.node.spec.ts @@ -19,7 +19,7 @@ import { getPublicKey, } from '../waku_message/version_1'; -import { Direction } from './history_rpc'; +import { PageDirection } from './history_rpc'; const dbg = debug('waku:test:store'); @@ -94,7 +94,7 @@ describe('Waku Store', () => { }); const messages = await waku.store.queryHistory([], { - direction: Direction.FORWARD, + pageDirection: PageDirection.FORWARD, }); expect(messages?.length).eq(15); diff --git a/src/lib/waku_store/index.ts b/src/lib/waku_store/index.ts index 1b2286186f..ffc197b166 100644 --- a/src/lib/waku_store/index.ts +++ b/src/lib/waku_store/index.ts @@ -12,13 +12,13 @@ import { hexToBuf } from '../utils'; import { DefaultPubSubTopic } from '../waku'; import { WakuMessage } from '../waku_message'; -import { Direction, HistoryRPC } from './history_rpc'; +import { HistoryRPC, PageDirection } from './history_rpc'; const dbg = debug('waku:store'); export const StoreCodec = '/vac/waku/store/2.0.0-beta3'; -export { Direction }; +export { PageDirection }; export interface CreateOptions { /** @@ -40,7 +40,7 @@ export interface TimeFilter { export interface QueryOptions { peerId?: PeerId; pubSubTopic?: string; - direction?: Direction; + pageDirection?: PageDirection; pageSize?: number; timeFilter?: TimeFilter; callback?: (messages: WakuMessage[]) => void; @@ -93,7 +93,7 @@ export class WakuStore { const opts = Object.assign( { pubSubTopic: this.pubSubTopic, - direction: Direction.BACKWARD, + pageDirection: PageDirection.BACKWARD, pageSize: 10, }, options, From 92ee5b060c514490fe5ea1d6a7885f9ae7b969ad Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 4 Oct 2021 12:18:40 +1100 Subject: [PATCH 03/12] doc: Move comments to ensure they appear in generated documentation --- src/lib/waku_store/index.ts | 57 +++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/src/lib/waku_store/index.ts b/src/lib/waku_store/index.ts index ffc197b166..75c4601d50 100644 --- a/src/lib/waku_store/index.ts +++ b/src/lib/waku_store/index.ts @@ -18,6 +18,8 @@ const dbg = debug('waku:store'); export const StoreCodec = '/vac/waku/store/2.0.0-beta3'; +export const DefaultPageSize = 10; + export { PageDirection }; export interface CreateOptions { @@ -38,12 +40,50 @@ export interface TimeFilter { } export interface QueryOptions { + /** + * The peer to query. If undefined, a pseudo-random peer is selected from the connected Waku Store peers. + */ peerId?: PeerId; + /** + * The pubsub topic to pass to the query. + * See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/). + */ pubSubTopic?: string; + /** + * The direction in which pages are retrieved: + * - [[Direction.BACKWARD]]: Most recent page first. + * - [[Direction.FORWARD]]: Oldest page first. + * + * Note: This does not affect the ordering of messages with the page + * (oldest message is always first). + * + * @default [[Direction.BACKWARD]] + */ pageDirection?: PageDirection; + /** + * The number of message per page. + * + * @default [[DefaultPageSize]] + */ pageSize?: number; + /** + * Retrieve messages with a timestamp within the provided values. + */ timeFilter?: TimeFilter; + /** + * Callback called on pages of stored messages as they are retrieved. + * Allows for a faster access to the results as it is called as soon as a page + * is received. + * Traversal of the pages is done automatically so this function will invoked + * for each retrieved page. + */ callback?: (messages: WakuMessage[]) => void; + /** + * Keys that will be used to decrypt messages. + * + * It can be Asymmetric Private Keys and Symmetric Keys in the same array, + * all keys will be tried with both methods. + */ decryptionKeys?: Array; } @@ -65,20 +105,13 @@ export class WakuStore { } /** - * Query given peer using Waku Store. + * Do a History Query to a Waku Store. * * @param contentTopics The content topics to pass to the query, leave empty to * retrieve all messages. - * @param options - * @param options.peerId The peer to query.Options - * @param options.timeFilter Query messages with a timestamp within the provided values. - * @param options.pubSubTopic The pubsub topic to pass to the query. Defaults - * to the value set at creation. See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/). - * @param options.callback Callback called on page of stored messages as they are retrieved - * @param options.decryptionKeys Keys that will be used to decrypt messages. - * It can be Asymmetric Private Keys and Symmetric Keys in the same array, all keys will be tried with both - * methods. - * @throws If not able to reach the peer to query or error when processing the reply. + * + * @throws If not able to reach a Waku Store peer to query + * or if an error is encountered when processing the reply. */ async queryHistory( contentTopics: string[], @@ -94,7 +127,7 @@ export class WakuStore { { pubSubTopic: this.pubSubTopic, pageDirection: PageDirection.BACKWARD, - pageSize: 10, + pageSize: DefaultPageSize, }, options, { From 4ae819357f294956bfacd72dbe385d664692ef35 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 5 Oct 2021 11:05:37 +1100 Subject: [PATCH 04/12] Correct doc for page direction --- guides/reactjs-store.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/reactjs-store.md b/guides/reactjs-store.md index c0c0e38c9f..0d91dcbc60 100644 --- a/guides/reactjs-store.md +++ b/guides/reactjs-store.md @@ -187,7 +187,7 @@ You now have all the building blocks to retrieve and decode messages for a store Note that Waku Store queries are paginated. The API provided by `js-waku` automatically traverses all pages of the Waku Store response. -By default, the most recent page is retrieved first but this can be changed with the `direction` option. +By default, the most recent page is retrieved first but this can be changed with the `pageDirection` option. First, define a React state to save the messages: From 92762deda23da7dc4003bc7bd44a5038c90ec628 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 5 Oct 2021 11:14:56 +1100 Subject: [PATCH 05/12] Remove extra line --- guides/reactjs-store.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/guides/reactjs-store.md b/guides/reactjs-store.md index 0d91dcbc60..144630f4d0 100644 --- a/guides/reactjs-store.md +++ b/guides/reactjs-store.md @@ -198,10 +198,9 @@ function App() { } ``` -Then, define `processMessages` to decode and then store messages in a React state. +Then, define `processMessages` to decode and then store messages in the React state. You will pass `processMessages` as a `callback` option to `WakuStore.queryHistory`. -`processMessages` will be called each time a page is received from the Waku Store. - +`processMessages` will be called each time a page is received from the Waku Store. ```js const processMessages = (retrievedMessages) => { From b216cd3b222d80df75085719c49cc9c5a7aee8bb Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 5 Oct 2021 11:17:03 +1100 Subject: [PATCH 06/12] Update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4e7a98877..ea8e2166df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **Breaking**: Renamed `WakuStore.QueryOptions`'s `direction` to `pageDirection` (and its type) as it only affects the page ordering, not the ordering of messages with the page. +### Fixed +- Docs: Ensure that `WakuStore`'s `QueryOptions` documentation is available [online](https://status-im.github.io/js-waku/docs/). + ## [0.13.1] - 2021-09-21 ### Fixed From 899e0c89e75c3cec9a8363ef074dbb4fde738c0c Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 5 Oct 2021 12:58:18 +1100 Subject: [PATCH 07/12] Add time filter to the guide --- examples/store-reactjs-chat/src/App.js | 9 ++++++++- guides/reactjs-store.md | 27 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/examples/store-reactjs-chat/src/App.js b/examples/store-reactjs-chat/src/App.js index 47191432e8..2ad02e624f 100644 --- a/examples/store-reactjs-chat/src/App.js +++ b/examples/store-reactjs-chat/src/App.js @@ -52,8 +52,15 @@ function App() { }); }; + const startTime = new Date(); + // 7 days/week, 24 hours/day, 60min/hour, 60secs/min, 100ms/sec + startTime.setTime(startTime.getTime() - 7 * 24 * 60 * 60 * 1000); + waku.store - .queryHistory([ContentTopic], { callback: processMessages }) + .queryHistory([ContentTopic], { + callback: processMessages, + timeFilter: { startTime, endTime: new Date() }, + }) .catch((e) => { console.log('Failed to retrieve messages', e); }); diff --git a/guides/reactjs-store.md b/guides/reactjs-store.md index 144630f4d0..a051a0df70 100644 --- a/guides/reactjs-store.md +++ b/guides/reactjs-store.md @@ -266,4 +266,31 @@ Note that `WakuStore.queryHistory` select an available store node for you. However, it can only select a connected node, which is why the bootstrapping is necessary. It will throw an error if no store node is available. +## Filter messages + +By default, Waku Store nodes store messages for 30 days. +Depending on your use case, you may not need to retrieve 30 days worth of messages. + +Messages have an optional unencrypted `timestamp` field. +The timestamp is set by the sender and may be present. +By default, js-waku [sets the timestamp of outgoing message to the current time](https://github.com/status-im/js-waku/blob/a056227538f9409aa9134c7ef0df25f602dbea58/src/lib/waku_message/index.ts#L76). + +You can filter messages that include a timestamp with the `timeFilter` option. + +Let's only retrieve messages up to a week old: + +```js +const startTime = new Date(); +// 7 days/week, 24 hours/day, 60min/hour, 60secs/min, 100ms/sec +startTime.setTime(startTime.getTime() - 7 * 24 * 60 * 60 * 1000); + +waku.store + .queryHistory([ContentTopic], { + callback: processMessages, + timeFilter: { startTime, endTime: new Date() } + }); +``` + +## End result + You can see the complete code in the [Minimal ReactJS Waku Store App](/examples/store-reactjs-chat). From 62b30b3f33c36516cb3ecbdbfbd3a70259e7ac7f Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 5 Oct 2021 13:29:37 +1100 Subject: [PATCH 08/12] Log queried store peer info --- src/lib/waku_store/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/waku_store/index.ts b/src/lib/waku_store/index.ts index 75c4601d50..613be4d4c1 100644 --- a/src/lib/waku_store/index.ts +++ b/src/lib/waku_store/index.ts @@ -166,6 +166,8 @@ export class WakuStore { const { stream } = await connection.newStream(StoreCodec); const queryOpts = Object.assign(opts, { cursor }); const historyRpcQuery = HistoryRPC.createQuery(queryOpts); + dbg('Querying store peer', connection.remoteAddr.toString()); + const res = await pipe( [historyRpcQuery.encode()], lp.encode(), From 6f4d765e30308e103c6f8c0ea6f2530453d12d44 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 5 Oct 2021 13:30:04 +1100 Subject: [PATCH 09/12] Remove useless log --- src/lib/waku.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/waku.ts b/src/lib/waku.ts index 286cd3487e..6900ab6e07 100644 --- a/src/lib/waku.ts +++ b/src/lib/waku.ts @@ -328,7 +328,6 @@ export class Waku { peers.push(peer) ); }); - dbg('peers for ', desiredProtocolVersions, peers); if (peers.length > 0) { return Promise.resolve(); From d6f180cf361a95d4d4fbf1f4ddd3bb663970aeff Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 5 Oct 2021 13:35:29 +1100 Subject: [PATCH 10/12] Use callback option in store guide --- guides/store-retrieve-messages.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/guides/store-retrieve-messages.md b/guides/store-retrieve-messages.md index dbab771cbd..ffefff452b 100644 --- a/guides/store-retrieve-messages.md +++ b/guides/store-retrieve-messages.md @@ -140,23 +140,26 @@ const decodeWakuMessage = (wakuMessage) => { You now have all the building blocks to retrieve and decode messages for a store node. -Retrieve messages from a store node: +Store node responses are paginated. +The `WakuStore.queryHistory` API automatically query all the pages in a sequential manner. +To process messages as soon as they received (page by page), use the `callback` option: ```js const ContentTopic = '/store-guide/1/news/proto'; waku.store - .queryHistory([ContentTopic]) + .queryHistory([ContentTopic], { + callback: (retrievedMessages) => { + const articles = retrievedMessages + .map(decodeWakuMessage) // Decode messages + .filter(Boolean); // Filter out undefined values + + console.log(`${articles.length} articles have been retrieved`); + } + }) .catch((e) => { // Be sure to catch any potential error console.log('Failed to retrieve messages', e); - }) - .then((retrievedMessages) => { - const articles = retrievedMessages - .map(decodeWakuMessage) // Decode messages - .filter(Boolean); // Filter out undefined values - - console.log(`${articles.length} articles have been retrieved`); }); ``` From 0d82b748542fa68b61bd568765b3f7d906e99f29 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 5 Oct 2021 13:41:21 +1100 Subject: [PATCH 11/12] Add and update time filter guides --- guides/reactjs-store.md | 8 ++--- guides/store-retrieve-messages.md | 55 ++++++++++++++++++++++++------- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/guides/reactjs-store.md b/guides/reactjs-store.md index a051a0df70..4c9c3cbfb9 100644 --- a/guides/reactjs-store.md +++ b/guides/reactjs-store.md @@ -266,16 +266,16 @@ Note that `WakuStore.queryHistory` select an available store node for you. However, it can only select a connected node, which is why the bootstrapping is necessary. It will throw an error if no store node is available. -## Filter messages +## Filter messages by send time By default, Waku Store nodes store messages for 30 days. Depending on your use case, you may not need to retrieve 30 days worth of messages. -Messages have an optional unencrypted `timestamp` field. -The timestamp is set by the sender and may be present. +[Waku Message](https://rfc.vac.dev/spec/14/) defines an optional unencrypted `timestamp` field. +The timestamp is set by the sender. By default, js-waku [sets the timestamp of outgoing message to the current time](https://github.com/status-im/js-waku/blob/a056227538f9409aa9134c7ef0df25f602dbea58/src/lib/waku_message/index.ts#L76). -You can filter messages that include a timestamp with the `timeFilter` option. +You can filter messages that include a timestamp within given bound with the `timeFilter` option. Let's only retrieve messages up to a week old: diff --git a/guides/store-retrieve-messages.md b/guides/store-retrieve-messages.md index ffefff452b..16437574a6 100644 --- a/guides/store-retrieve-messages.md +++ b/guides/store-retrieve-messages.md @@ -147,19 +147,19 @@ To process messages as soon as they received (page by page), use the `callback` ```js const ContentTopic = '/store-guide/1/news/proto'; -waku.store - .queryHistory([ContentTopic], { - callback: (retrievedMessages) => { - const articles = retrievedMessages - .map(decodeWakuMessage) // Decode messages - .filter(Boolean); // Filter out undefined values +const callback = (retrievedMessages) => { + const articles = retrievedMessages + .map(decodeWakuMessage) // Decode messages + .filter(Boolean); // Filter out undefined values - console.log(`${articles.length} articles have been retrieved`); - } - }) + console.log(`${articles.length} articles have been retrieved`); +}; + +waku.store + .queryHistory([ContentTopic], { callback }) .catch((e) => { - // Be sure to catch any potential error - console.log('Failed to retrieve messages', e); + // Catch any potential error + console.log('Failed to retrieve messages from store', e); }); ``` @@ -167,3 +167,36 @@ Note that `WakuStore.queryHistory` select an available store node for you. However, it can only select a connected node, which is why the bootstrapping is necessary. It will throw an error if no store node is available. +## Filter messages by send time + +By default, Waku Store nodes store messages for 30 days. +Depending on your use case, you may not need to retrieve 30 days worth of messages. + +[Waku Message](https://rfc.vac.dev/spec/14/) defiles an optional unencrypted `timestamp` field. +The timestamp is set by the sender. +By default, js-waku [sets the timestamp of outgoing message to the current time](https://github.com/status-im/js-waku/blob/a056227538f9409aa9134c7ef0df25f602dbea58/src/lib/waku_message/index.ts#L76). + +You can filter messages that include a timestamp within given bound with the `timeFilter` option. + +Let's only retrieve messages up to a week old: + +```js +// `ContentTopic` and `callback` definitions + +const startTime = new Date(); +// 7 days/week, 24 hours/day, 60min/hour, 60secs/min, 100ms/sec +startTime.setTime(startTime.getTime() - 7 * 24 * 60 * 60 * 1000); + +waku.store + .queryHistory([ContentTopic], { + callback, + timeFilter: { startTime, endTime: new Date() } + }) + .catch((e) => { + console.log('Failed to retrieve messages from store', e); + }); +``` + +## End result + +You can see a similar example implemented in ReactJS in the [Minimal ReactJS Waku Store App](/examples/store-reactjs-chat). From 2fbe926df2762f1182c10209a194dedb5c81806a Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 5 Oct 2021 13:44:37 +1100 Subject: [PATCH 12/12] Fix typos --- guides/reactjs-store.md | 4 ++-- guides/store-retrieve-messages.md | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/guides/reactjs-store.md b/guides/reactjs-store.md index 4c9c3cbfb9..7bd2d462e1 100644 --- a/guides/reactjs-store.md +++ b/guides/reactjs-store.md @@ -275,9 +275,9 @@ Depending on your use case, you may not need to retrieve 30 days worth of messag The timestamp is set by the sender. By default, js-waku [sets the timestamp of outgoing message to the current time](https://github.com/status-im/js-waku/blob/a056227538f9409aa9134c7ef0df25f602dbea58/src/lib/waku_message/index.ts#L76). -You can filter messages that include a timestamp within given bound with the `timeFilter` option. +You can filter messages that include a timestamp within given bounds with the `timeFilter` option. -Let's only retrieve messages up to a week old: +Retrieve messages up to a week old: ```js const startTime = new Date(); diff --git a/guides/store-retrieve-messages.md b/guides/store-retrieve-messages.md index 16437574a6..e37c4b856e 100644 --- a/guides/store-retrieve-messages.md +++ b/guides/store-retrieve-messages.md @@ -176,12 +176,12 @@ Depending on your use case, you may not need to retrieve 30 days worth of messag The timestamp is set by the sender. By default, js-waku [sets the timestamp of outgoing message to the current time](https://github.com/status-im/js-waku/blob/a056227538f9409aa9134c7ef0df25f602dbea58/src/lib/waku_message/index.ts#L76). -You can filter messages that include a timestamp within given bound with the `timeFilter` option. +You can filter messages that include a timestamp within given bounds with the `timeFilter` option. -Let's only retrieve messages up to a week old: +Retrieve messages up to a week old: ```js -// `ContentTopic` and `callback` definitions +// [..] `ContentTopic` and `callback` definitions const startTime = new Date(); // 7 days/week, 24 hours/day, 60min/hour, 60secs/min, 100ms/sec