mirror of
https://github.com/FlipsideCrypto/near-bos-vm.git
synced 2026-02-06 11:18:24 +00:00
Merge pull request #114 from NearSocial/no-stale
- Add `cacheOptions` optional argument to the following methods:
- `Social.get(keys, blockId|finality, options, cacheOptions)`
- `Social.getr(keys, blockId|finality, options, cacheOptions)`
- `Social.keys(keys, blockId|finality, options, cacheOptions)`
- `Social.index(action, key, options, cacheOptions)`
- `Near.view(contractName, methodName, args, blockId|finality, subscribe, cacheOptions)`
- `Near.block(blockId|finality, subscribe, cacheOptions)`
The `cacheOptions` object is optional and may contain the following property:
- `ignoreCache` - boolean, if true, the method will ignore the cached value in the local DB and fetch the data from the API server. This will only happen once per session. Default is false.
This is useful to avoid loading stale objects that are likely to change often. For example, the index of posts for the main feed, or notifications.
```jsx
const index = Social.index(
"post",
"main",
{
limit: 10,
order: "desc",
},
{
ignoreCache: true,
}
);
```
This commit is contained in:
commit
27ec908e57
24
CHANGELOG.md
24
CHANGELOG.md
@ -2,6 +2,30 @@
|
||||
|
||||
## Pending
|
||||
|
||||
- Add `cacheOptions` optional argument to the following methods:
|
||||
- `Social.get(keys, blockId|finality, options, cacheOptions)`
|
||||
- `Social.getr(keys, blockId|finality, options, cacheOptions)`
|
||||
- `Social.keys(keys, blockId|finality, options, cacheOptions)`
|
||||
- `Social.index(action, key, options, cacheOptions)`
|
||||
- `Near.view(contractName, methodName, args, blockId|finality, subscribe, cacheOptions)`
|
||||
- `Near.block(blockId|finality, subscribe, cacheOptions)`
|
||||
The `cacheOptions` object is optional and may contain the following property:
|
||||
- `ignoreCache` - boolean, if true, the method will ignore the cached value in the local DB and fetch the data from the API server. This will only happen once per session. Default is false.
|
||||
|
||||
This is useful to avoid loading stale objects that are likely to change often. For example, the index of posts for the main feed, or notifications.
|
||||
```jsx
|
||||
const index = Social.index(
|
||||
"post",
|
||||
"main",
|
||||
{
|
||||
limit: 10,
|
||||
order: "desc",
|
||||
},
|
||||
{
|
||||
ignoreCache: true,
|
||||
}
|
||||
);
|
||||
```
|
||||
- Replace `lodash` dependency with `lodash.clonedeep` to reduce bundle size.
|
||||
|
||||
## 2.3.2
|
||||
|
||||
2
dist/index.js
vendored
2
dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -65,7 +65,7 @@ class Cache {
|
||||
return (await this.dbPromise).put(CacheDbObject, val, key);
|
||||
}
|
||||
|
||||
cachedPromise(key, promise, invalidate, forceCachedValue) {
|
||||
cachedPromise(key, promise, invalidate, cacheOptions) {
|
||||
key = JSON.stringify(key);
|
||||
const cached = this.cache[key] || {
|
||||
status: CacheStatus.NotStarted,
|
||||
@ -106,10 +106,13 @@ class Cache {
|
||||
) {
|
||||
return cached.result;
|
||||
}
|
||||
if (cached.status === CacheStatus.NotStarted) {
|
||||
if (
|
||||
cached.status === CacheStatus.NotStarted &&
|
||||
!cacheOptions?.ignoreCache
|
||||
) {
|
||||
this.innerGet(key).then((cachedResult) => {
|
||||
if (
|
||||
(cachedResult || forceCachedValue) &&
|
||||
(cachedResult || cacheOptions?.forceCachedValue) &&
|
||||
cached.status === CacheStatus.InProgress
|
||||
) {
|
||||
CacheDebug && console.log("Cached value", key, cachedResult);
|
||||
@ -200,18 +203,27 @@ class Cache {
|
||||
});
|
||||
}
|
||||
|
||||
cachedBlock(near, blockId, invalidate) {
|
||||
cachedBlock(near, blockId, invalidate, cacheOptions) {
|
||||
return this.cachedPromise(
|
||||
{
|
||||
action: Action.Block,
|
||||
blockId,
|
||||
},
|
||||
() => near.block(blockId),
|
||||
invalidate
|
||||
invalidate,
|
||||
cacheOptions
|
||||
);
|
||||
}
|
||||
|
||||
cachedViewCall(near, contractId, methodName, args, blockId, invalidate) {
|
||||
cachedViewCall(
|
||||
near,
|
||||
contractId,
|
||||
methodName,
|
||||
args,
|
||||
blockId,
|
||||
invalidate,
|
||||
cacheOptions
|
||||
) {
|
||||
return this.cachedPromise(
|
||||
{
|
||||
action: Action.ViewCall,
|
||||
@ -221,7 +233,8 @@ class Cache {
|
||||
blockId,
|
||||
},
|
||||
() => near.viewCall(contractId, methodName, args, blockId),
|
||||
invalidate
|
||||
invalidate,
|
||||
cacheOptions
|
||||
);
|
||||
}
|
||||
|
||||
@ -266,7 +279,7 @@ class Cache {
|
||||
}
|
||||
}
|
||||
|
||||
cachedFetch(url, options, invalidate) {
|
||||
cachedFetch(url, options, invalidate, cacheOptions) {
|
||||
return this.cachedPromise(
|
||||
{
|
||||
action: Action.Fetch,
|
||||
@ -274,22 +287,24 @@ class Cache {
|
||||
options,
|
||||
},
|
||||
() => this.asyncFetch(url, options),
|
||||
invalidate
|
||||
invalidate,
|
||||
cacheOptions
|
||||
);
|
||||
}
|
||||
|
||||
cachedCustomPromise(key, promise, invalidate) {
|
||||
cachedCustomPromise(key, promise, invalidate, cacheOptions) {
|
||||
return this.cachedPromise(
|
||||
{
|
||||
action: Action.CustomPromise,
|
||||
key,
|
||||
},
|
||||
() => promise(),
|
||||
invalidate
|
||||
invalidate,
|
||||
cacheOptions
|
||||
);
|
||||
}
|
||||
|
||||
socialGet(near, keys, recursive, blockId, options, invalidate) {
|
||||
socialGet(near, keys, recursive, blockId, options, invalidate, cacheOptions) {
|
||||
if (!near) {
|
||||
return null;
|
||||
}
|
||||
@ -305,7 +320,8 @@ class Cache {
|
||||
"get",
|
||||
args,
|
||||
blockId,
|
||||
invalidate
|
||||
invalidate,
|
||||
cacheOptions
|
||||
);
|
||||
if (data === null) {
|
||||
return null;
|
||||
@ -325,7 +341,7 @@ class Cache {
|
||||
return data;
|
||||
}
|
||||
|
||||
socialIndex(near, action, key, options, invalidate) {
|
||||
socialIndex(near, action, key, options, invalidate, cacheOptions) {
|
||||
const res = this.cachedFetch(
|
||||
`${near.config.apiUrl}/index`,
|
||||
{
|
||||
@ -339,7 +355,8 @@ class Cache {
|
||||
options,
|
||||
}),
|
||||
},
|
||||
invalidate
|
||||
invalidate,
|
||||
cacheOptions
|
||||
);
|
||||
|
||||
return res?.ok ? res.body : null;
|
||||
@ -354,7 +371,9 @@ class Cache {
|
||||
},
|
||||
undefined,
|
||||
invalidate,
|
||||
true
|
||||
{
|
||||
forceCachedValue: true,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ -390,7 +409,7 @@ class Cache {
|
||||
}
|
||||
}
|
||||
|
||||
cachedEthersCall(ethersProvider, callee, args, invalidate) {
|
||||
cachedEthersCall(ethersProvider, callee, args, invalidate, cacheOptions) {
|
||||
if (!ethersProvider) {
|
||||
return null;
|
||||
}
|
||||
@ -401,7 +420,8 @@ class Cache {
|
||||
args,
|
||||
},
|
||||
() => ethersProvider[callee](...args),
|
||||
invalidate
|
||||
invalidate,
|
||||
cacheOptions
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -417,14 +437,14 @@ const useSecondaryCache = singletonHook(secondaryCache, () => {
|
||||
return secondaryCache;
|
||||
});
|
||||
|
||||
export const useCache = networkId => {
|
||||
export const useCache = (networkId) => {
|
||||
const near = useNear();
|
||||
const defaultCache = useDefaultCache();
|
||||
const secondaryCache = useSecondaryCache();
|
||||
|
||||
if(!networkId || networkId === near.config.networkId) {
|
||||
if (!networkId || networkId === near.config.networkId) {
|
||||
return defaultCache;
|
||||
}
|
||||
|
||||
return secondaryCache;
|
||||
}
|
||||
};
|
||||
|
||||
102
src/lib/vm/vm.js
102
src/lib/vm/vm.js
@ -738,7 +738,13 @@ class VmStack {
|
||||
if (args.length < 1) {
|
||||
throw new Error("Missing argument 'keys' for Social.getr");
|
||||
}
|
||||
return this.vm.cachedSocialGet(args[0], true, args[1], args[2]);
|
||||
return this.vm.cachedSocialGet(
|
||||
args[0],
|
||||
true,
|
||||
args[1],
|
||||
args[2],
|
||||
args[3]
|
||||
);
|
||||
} else if (
|
||||
(keyword === "Social" && callee === "get") ||
|
||||
callee === "socialGet"
|
||||
@ -746,19 +752,25 @@ class VmStack {
|
||||
if (args.length < 1) {
|
||||
throw new Error("Missing argument 'keys' for Social.get");
|
||||
}
|
||||
return this.vm.cachedSocialGet(args[0], false, args[1], args[2]);
|
||||
return this.vm.cachedSocialGet(
|
||||
args[0],
|
||||
false,
|
||||
args[1],
|
||||
args[2],
|
||||
args[3]
|
||||
);
|
||||
} else if (keyword === "Social" && callee === "keys") {
|
||||
if (args.length < 1) {
|
||||
throw new Error("Missing argument 'keys' for Social.keys");
|
||||
}
|
||||
return this.vm.cachedSocialKeys(args[0], args[1], args[2]);
|
||||
return this.vm.cachedSocialKeys(...args);
|
||||
} else if (keyword === "Social" && callee === "index") {
|
||||
if (args.length < 2) {
|
||||
throw new Error(
|
||||
"Missing argument 'action' and 'key` for Social.index"
|
||||
);
|
||||
}
|
||||
return this.vm.cachedIndex(args[0], args[1], args[2]);
|
||||
return this.vm.cachedIndex(...args);
|
||||
} else if (keyword === "Social" && callee === "set") {
|
||||
if (args.length < 1) {
|
||||
throw new Error("Missing argument 'data' for Social.set");
|
||||
@ -767,17 +779,25 @@ class VmStack {
|
||||
} else if (keyword === "Near" && callee === "view") {
|
||||
if (args.length < 2) {
|
||||
throw new Error(
|
||||
"Method: Near.view. Required arguments: 'contractName', 'methodName'. Optional: 'args', 'blockId/finality', 'subscribe'"
|
||||
"Method: Near.view. Required arguments: 'contractName', 'methodName'. Optional: 'args', 'blockId/finality', 'subscribe', 'cacheOptions'"
|
||||
);
|
||||
}
|
||||
const [contractName, methodName, viewArg, blockId, subscribe] = args;
|
||||
const [
|
||||
contractName,
|
||||
methodName,
|
||||
viewArg,
|
||||
blockId,
|
||||
subscribe,
|
||||
cacheOptions,
|
||||
] = args;
|
||||
|
||||
return this.vm.cachedNearView(
|
||||
contractName,
|
||||
methodName,
|
||||
viewArg,
|
||||
blockId,
|
||||
maybeSubscribe(subscribe, blockId)
|
||||
maybeSubscribe(subscribe, blockId),
|
||||
cacheOptions
|
||||
);
|
||||
} else if (keyword === "Near" && callee === "asyncView") {
|
||||
if (args.length < 2) {
|
||||
@ -787,10 +807,11 @@ class VmStack {
|
||||
}
|
||||
return this.vm.asyncNearView(...args);
|
||||
} else if (keyword === "Near" && callee === "block") {
|
||||
const [blockId, subscribe] = args;
|
||||
const [blockId, subscribe, cacheOptions] = args;
|
||||
return this.vm.cachedNearBlock(
|
||||
blockId,
|
||||
maybeSubscribe(subscribe, blockId)
|
||||
maybeSubscribe(subscribe, blockId),
|
||||
cacheOptions
|
||||
);
|
||||
} else if (keyword === "Near" && callee === "call") {
|
||||
if (args.length === 1) {
|
||||
@ -1807,7 +1828,7 @@ export default class VM {
|
||||
return deepCopy(promise(invalidate));
|
||||
}
|
||||
|
||||
cachedSocialGet(keys, recursive, blockId, options) {
|
||||
cachedSocialGet(keys, recursive, blockId, options, cacheOptions) {
|
||||
keys = Array.isArray(keys) ? keys : [keys];
|
||||
return this.cachedPromise(
|
||||
(invalidate) =>
|
||||
@ -1817,7 +1838,8 @@ export default class VM {
|
||||
recursive,
|
||||
blockId,
|
||||
options,
|
||||
invalidate
|
||||
invalidate,
|
||||
cacheOptions
|
||||
),
|
||||
options?.subscribe
|
||||
);
|
||||
@ -1833,7 +1855,7 @@ export default class VM {
|
||||
return this.cache.localStorageSet(domain, key, value);
|
||||
}
|
||||
|
||||
cachedSocialKeys(keys, blockId, options) {
|
||||
cachedSocialKeys(keys, blockId, options, cacheOptions) {
|
||||
keys = Array.isArray(keys) ? keys : [keys];
|
||||
return this.cachedPromise(
|
||||
(invalidate) =>
|
||||
@ -1846,7 +1868,8 @@ export default class VM {
|
||||
options,
|
||||
},
|
||||
blockId,
|
||||
invalidate
|
||||
invalidate,
|
||||
cacheOptions
|
||||
),
|
||||
options?.subscribe
|
||||
);
|
||||
@ -1856,20 +1879,28 @@ export default class VM {
|
||||
return this.near.viewCall(contractName, methodName, args, blockId);
|
||||
}
|
||||
|
||||
cachedEthersCall(callee, args, subscribe) {
|
||||
cachedEthersCall(callee, args, subscribe, cacheOptions) {
|
||||
return this.cachedPromise(
|
||||
(invalidate) =>
|
||||
this.cache.cachedEthersCall(
|
||||
this.ethersProvider,
|
||||
callee,
|
||||
args,
|
||||
invalidate
|
||||
invalidate,
|
||||
cacheOptions
|
||||
),
|
||||
subscribe
|
||||
);
|
||||
}
|
||||
|
||||
cachedNearView(contractName, methodName, args, blockId, subscribe) {
|
||||
cachedNearView(
|
||||
contractName,
|
||||
methodName,
|
||||
args,
|
||||
blockId,
|
||||
subscribe,
|
||||
cacheOptions
|
||||
) {
|
||||
return this.cachedPromise(
|
||||
(invalidate) =>
|
||||
this.cache.cachedViewCall(
|
||||
@ -1878,15 +1909,17 @@ export default class VM {
|
||||
methodName,
|
||||
args,
|
||||
blockId,
|
||||
invalidate
|
||||
invalidate,
|
||||
cacheOptions
|
||||
),
|
||||
subscribe
|
||||
);
|
||||
}
|
||||
|
||||
cachedNearBlock(blockId, subscribe) {
|
||||
cachedNearBlock(blockId, subscribe, cacheOptions) {
|
||||
return this.cachedPromise(
|
||||
(invalidate) => this.cache.cachedBlock(this.near, blockId, invalidate),
|
||||
(invalidate) =>
|
||||
this.cache.cachedBlock(this.near, blockId, invalidate, cacheOptions),
|
||||
subscribe
|
||||
);
|
||||
}
|
||||
@ -1895,22 +1928,30 @@ export default class VM {
|
||||
return this.cache.asyncFetch(url, options);
|
||||
}
|
||||
|
||||
cachedFetch(url, options) {
|
||||
return this.cachedPromise(
|
||||
(invalidate) => this.cache.cachedFetch(url, options, invalidate),
|
||||
options?.subscribe
|
||||
);
|
||||
}
|
||||
|
||||
cachedIndex(action, key, options) {
|
||||
cachedFetch(url, options, cacheOptions) {
|
||||
return this.cachedPromise(
|
||||
(invalidate) =>
|
||||
this.cache.socialIndex(this.near, action, key, options, invalidate),
|
||||
this.cache.cachedFetch(url, options, invalidate, cacheOptions),
|
||||
options?.subscribe
|
||||
);
|
||||
}
|
||||
|
||||
useCache(promiseGenerator, dataKey, options) {
|
||||
cachedIndex(action, key, options, cacheOptions) {
|
||||
return this.cachedPromise(
|
||||
(invalidate) =>
|
||||
this.cache.socialIndex(
|
||||
this.near,
|
||||
action,
|
||||
key,
|
||||
options,
|
||||
invalidate,
|
||||
cacheOptions
|
||||
),
|
||||
options?.subscribe
|
||||
);
|
||||
}
|
||||
|
||||
useCache(promiseGenerator, dataKey, options, cacheOptions) {
|
||||
return this.cachedPromise(
|
||||
(invalidate) =>
|
||||
this.cache.cachedCustomPromise(
|
||||
@ -1919,7 +1960,8 @@ export default class VM {
|
||||
dataKey,
|
||||
},
|
||||
promiseGenerator,
|
||||
invalidate
|
||||
invalidate,
|
||||
cacheOptions
|
||||
),
|
||||
options?.subscribe
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user