Comparing version 1.2.1-alpha.1 to 1.3.0
@@ -0,1 +1,7 @@ | ||
## 1.3.0 | ||
* Expanded on `getCached()`, `setCached()` and `updateCached()` on Async Actions - and made sure they can optionally notify any listeners on their cached values to re-render on changes. | ||
* Added `clearAllUnwatchedCache()` on Async Actions for quick and easy garbage collection. | ||
* Added `timeCached` as a passed argument to the `cacheBreakHook()`, allowing for easier cache invalidation against the time the value was last cached. | ||
## 1.2.0 | ||
@@ -2,0 +8,0 @@ |
import { IPullstateAllStores } from "./PullstateCore"; | ||
import { TUpdateFunction } from "./Store"; | ||
declare type TPullstateAsyncUpdateListener = () => void; | ||
export declare type TPullstateAsyncWatchResponse<R = any, T extends string = string> = [boolean, boolean, TAsyncActionResult<R, T>, boolean]; | ||
export declare type TPullstateAsyncResponseCacheFull<R, T extends string> = [boolean, boolean, TAsyncActionResult<R, T>, boolean, TAsyncActionResult<R, T> | true | null]; | ||
export declare type TPullstateAsyncWatchResponse<R = any, T extends string = string> = [boolean, boolean, TAsyncActionResult<R, T>, boolean, number]; | ||
export declare type TPullstateAsyncBeckonResponse<R = any, T extends string = string> = [boolean, TAsyncActionResult<R, T>, boolean]; | ||
@@ -40,2 +39,3 @@ export declare type TPullstateAsyncRunResponse<R = any, T extends string = string> = Promise<TAsyncActionResult<R, T>>; | ||
stores: S; | ||
timeCached: number; | ||
}) => boolean; | ||
@@ -81,3 +81,10 @@ export declare enum EPostActionContext { | ||
cacheBreakable: boolean; | ||
timeCached: number; | ||
} | ||
export interface IAsyncActionSetCachedOptions { | ||
notify?: boolean; | ||
} | ||
export interface IAsyncActionUpdateCachedOptions extends IAsyncActionSetCachedOptions { | ||
resetTimeCached?: boolean; | ||
} | ||
export declare type TAsyncActionBeckon<A, R, T extends string> = (args?: A, options?: IAsyncActionBeckonOptions) => TPullstateAsyncBeckonResponse<R, T>; | ||
@@ -88,5 +95,6 @@ export declare type TAsyncActionWatch<A, R, T extends string> = (args?: A, options?: IAsyncActionWatchOptions) => TPullstateAsyncWatchResponse<R, T>; | ||
export declare type TAsyncActionClearAllCache = () => void; | ||
export declare type TAsyncActionSetCached<A, R, T extends string> = (args: A, result: TAsyncActionResult<R, T>) => void; | ||
export declare type TAsyncActionUpdateCached<A, R, T extends string> = (args: A, updater: TUpdateFunction<R>) => void; | ||
export declare type TAsyncActionClearAllUnwatchedCache = () => void; | ||
export declare type TAsyncActionGetCached<A, R, T extends string> = (args?: A, options?: IAsyncActionGetCachedOptions) => IGetCachedResponse<R, T>; | ||
export declare type TAsyncActionSetCached<A, R, T extends string> = (args: A, result: TAsyncActionResult<R, T>, options?: IAsyncActionSetCachedOptions) => void; | ||
export declare type TAsyncActionUpdateCached<A, R, T extends string> = (args: A, updater: TUpdateFunction<R>, options?: IAsyncActionUpdateCachedOptions) => void; | ||
export declare type TAsyncActionDelayedRun<A> = (args?: A, options?: IAsyncActionRunOptions & { | ||
@@ -107,2 +115,3 @@ delay: number; | ||
clearAllCache: TAsyncActionClearAllCache; | ||
clearAllUnwatchedCache: TAsyncActionClearAllUnwatchedCache; | ||
} | ||
@@ -109,0 +118,0 @@ export interface IPullstateAsyncCache { |
@@ -301,2 +301,3 @@ import React,{useState,useRef,useEffect,useContext,useMemo}from'react';import produce$1 from'immer';const isEqual = require("fast-deep-equal"); | ||
for (const watchId of Object.keys(clientAsyncCache.listeners[key])) { | ||
console.log(`[${key}] Notifying listener with watch id: [${watchId}]`); | ||
clientAsyncCache.listeners[key][watchId](); | ||
@@ -306,4 +307,4 @@ } | ||
} | ||
function clearActionCache(key) { | ||
if (clientAsyncCache.actionOrd.hasOwnProperty(key)) { | ||
function clearActionCache(key, clearPending = true) { | ||
if (clearPending && clientAsyncCache.actionOrd.hasOwnProperty(key)) { | ||
clientAsyncCache.actionOrd[key] += 1; | ||
@@ -355,3 +356,8 @@ } | ||
cacheBreakHook !== undefined && | ||
cacheBreakHook({ args, result: cache.results[key][2], stores }) && | ||
cacheBreakHook({ | ||
args, | ||
result: cache.results[key][2], | ||
stores, | ||
timeCached: cache.results[key][4], | ||
}) && | ||
!cacheBreakLoop) { | ||
@@ -389,3 +395,3 @@ if (cacheBreakWatcher.hasOwnProperty(key)) { | ||
runPostActionHook(shortCircuitResponse, args, stores, EPostActionContext.SHORT_CIRCUIT); | ||
cache.results[key] = [true, true, shortCircuitResponse, false]; | ||
cache.results[key] = [true, true, shortCircuitResponse, false, Date.now()]; | ||
return cache.results[key]; | ||
@@ -395,6 +401,7 @@ } | ||
if (ssr || !onServer) { | ||
cache.actions[key] = () => action(args, stores).then(resp => { | ||
cache.actions[key] = () => action(args, stores) | ||
.then(resp => { | ||
if (currentActionOrd === cache.actionOrd[key]) { | ||
runPostActionHook(resp, args, stores, EPostActionContext.BECKON_RUN); | ||
cache.results[key] = [true, true, resp, false]; | ||
cache.results[key] = [true, true, resp, false, Date.now()]; | ||
} | ||
@@ -412,3 +419,9 @@ }) | ||
runPostActionHook(result, args, stores, EPostActionContext.BECKON_RUN); | ||
cache.results[key] = [true, true, result, false]; | ||
cache.results[key] = [ | ||
true, | ||
true, | ||
result, | ||
false, | ||
Date.now(), | ||
]; | ||
} | ||
@@ -438,2 +451,3 @@ }) | ||
false, | ||
-1, | ||
]; | ||
@@ -452,2 +466,3 @@ } | ||
false, | ||
-1, | ||
]; | ||
@@ -476,2 +491,6 @@ } | ||
const onAsyncStateChanged = () => { | ||
console.log(`[${key}][${watchId.current}] should update: ${shouldUpdate[key][watchId.current]}`); | ||
console.log(`[${key}][${watchId.current}] will update?: ${!isEqual$2(responseRef.current, cache.results[key])} - ${responseRef.current} !== ${cache.results[key]}`); | ||
console.log(responseRef.current); | ||
console.log(cache.results[key]); | ||
if (shouldUpdate[key][watchId.current] && !isEqual$2(responseRef.current, cache.results[key])) { | ||
@@ -491,4 +510,4 @@ responseRef.current = checkKeyAndReturnResponse(key, cache, initiate, ssr, args, stores, true, postActionEnabled, cacheBreakEnabled); | ||
useEffect(() => () => { | ||
delete cache.listeners[key][watchId.current]; | ||
shouldUpdate[key][watchId.current] = false; | ||
delete cache.listeners[key][watchId.current]; | ||
}, [key]); | ||
@@ -500,2 +519,3 @@ } | ||
if (prevKeyRef.current !== null && shouldUpdate.hasOwnProperty(prevKeyRef.current)) { | ||
delete cache.listeners[prevKeyRef.current][watchId.current]; | ||
shouldUpdate[prevKeyRef.current][watchId.current] = false; | ||
@@ -520,2 +540,3 @@ } | ||
stores: _stores, | ||
timeCached: _asyncCache.results[key][4], | ||
})) { | ||
@@ -537,3 +558,3 @@ delete _asyncCache.results[key]; | ||
if (shortCircuitResponse !== false) { | ||
_asyncCache.results[key] = [true, true, shortCircuitResponse, false]; | ||
_asyncCache.results[key] = [true, true, shortCircuitResponse, false, Date.now()]; | ||
runPostActionHook(shortCircuitResponse, args, _stores, EPostActionContext.SHORT_CIRCUIT); | ||
@@ -544,3 +565,3 @@ notifyListeners(key); | ||
} | ||
const [, prevFinished, prevResp] = _asyncCache.results[key] || [ | ||
const [, prevFinished, prevResp, prevUpdate, prevCacheTime] = _asyncCache.results[key] || [ | ||
false, | ||
@@ -554,5 +575,7 @@ false, | ||
}, | ||
false, | ||
-1, | ||
]; | ||
if (prevFinished && treatAsUpdate) { | ||
_asyncCache.results[key] = [true, true, prevResp, true]; | ||
_asyncCache.results[key] = [true, true, prevResp, true, prevCacheTime]; | ||
} | ||
@@ -570,2 +593,3 @@ else { | ||
false, | ||
-1, | ||
]; | ||
@@ -578,3 +602,3 @@ } | ||
if (currentActionOrd === _asyncCache.actionOrd[key]) { | ||
_asyncCache.results[key] = [true, true, result, false]; | ||
_asyncCache.results[key] = [true, true, result, false, Date.now()]; | ||
runPostActionHook(result, args, _stores, EPostActionContext.DIRECT_RUN); | ||
@@ -594,3 +618,3 @@ notifyListeners(key); | ||
if (currentActionOrd === _asyncCache.actionOrd[key]) { | ||
_asyncCache.results[key] = [true, true, result, false]; | ||
_asyncCache.results[key] = [true, true, result, false, Date.now()]; | ||
runPostActionHook(result, args, _stores, EPostActionContext.DIRECT_RUN); | ||
@@ -613,3 +637,11 @@ notifyListeners(key); | ||
}; | ||
const setCached = (args, result) => { | ||
const clearAllUnwatchedCache = () => { | ||
for (const key of Object.keys(shouldUpdate)) { | ||
if (!Object.values(shouldUpdate[key]).some(su => su)) { | ||
delete shouldUpdate[key]; | ||
clearActionCache(key, false); | ||
} | ||
} | ||
}; | ||
const setCached = (args, result, { notify = true }) => { | ||
const key = createKey(ordinal, args); | ||
@@ -619,5 +651,8 @@ const cache = onServer | ||
: clientAsyncCache; | ||
cache.results[key] = [true, true, result, false]; | ||
cache.results[key] = [true, true, result, false, Date.now()]; | ||
if (notify) { | ||
notifyListeners(key); | ||
} | ||
}; | ||
const updateCached = (args, updater) => { | ||
const updateCached = (args, updater, { notify = true, resetTimeCached = true } = {}) => { | ||
const key = createKey(ordinal, args); | ||
@@ -629,3 +664,17 @@ const cache = onServer | ||
const currentCached = cache.results[key][2].payload; | ||
cache.results[key][2].payload = produce$1(currentCached, s => updater(s, currentCached)); | ||
cache.results[key] = [ | ||
true, | ||
true, | ||
{ | ||
payload: produce$1(currentCached, s => updater(s, currentCached)), | ||
error: false, | ||
message: cache.results[key][2].message, | ||
tags: cache.results[key][2].tags, | ||
}, | ||
cache.results[key][3], | ||
cache.results[key][4], | ||
]; | ||
if (notify) { | ||
notifyListeners(key); | ||
} | ||
} | ||
@@ -646,2 +695,3 @@ }; | ||
stores, | ||
timeCached: cache.results[key][4], | ||
})) { | ||
@@ -651,3 +701,3 @@ cacheBreakable = true; | ||
} | ||
const [started, finished, result, updating] = cache.results[key]; | ||
const [started, finished, result, updating, timeCached] = cache.results[key]; | ||
return { | ||
@@ -660,2 +710,3 @@ started, | ||
updating, | ||
timeCached, | ||
}; | ||
@@ -676,2 +727,3 @@ } | ||
cacheBreakable, | ||
timeCached: -1, | ||
}; | ||
@@ -709,2 +761,3 @@ } | ||
clearAllCache, | ||
clearAllUnwatchedCache, | ||
getCached, | ||
@@ -711,0 +764,0 @@ setCached, |
@@ -300,2 +300,3 @@ 'use strict';Object.defineProperty(exports,'__esModule',{value:true});function _interopDefault(e){return(e&&(typeof e==='object')&&'default'in e)?e['default']:e}var React=require('react'),React__default=_interopDefault(React),produce$1=_interopDefault(require('immer'));const isEqual = require("fast-deep-equal"); | ||
for (const watchId of Object.keys(clientAsyncCache.listeners[key])) { | ||
console.log(`[${key}] Notifying listener with watch id: [${watchId}]`); | ||
clientAsyncCache.listeners[key][watchId](); | ||
@@ -305,4 +306,4 @@ } | ||
} | ||
function clearActionCache(key) { | ||
if (clientAsyncCache.actionOrd.hasOwnProperty(key)) { | ||
function clearActionCache(key, clearPending = true) { | ||
if (clearPending && clientAsyncCache.actionOrd.hasOwnProperty(key)) { | ||
clientAsyncCache.actionOrd[key] += 1; | ||
@@ -354,3 +355,8 @@ } | ||
cacheBreakHook !== undefined && | ||
cacheBreakHook({ args, result: cache.results[key][2], stores }) && | ||
cacheBreakHook({ | ||
args, | ||
result: cache.results[key][2], | ||
stores, | ||
timeCached: cache.results[key][4], | ||
}) && | ||
!cacheBreakLoop) { | ||
@@ -388,3 +394,3 @@ if (cacheBreakWatcher.hasOwnProperty(key)) { | ||
runPostActionHook(shortCircuitResponse, args, stores, EPostActionContext.SHORT_CIRCUIT); | ||
cache.results[key] = [true, true, shortCircuitResponse, false]; | ||
cache.results[key] = [true, true, shortCircuitResponse, false, Date.now()]; | ||
return cache.results[key]; | ||
@@ -394,6 +400,7 @@ } | ||
if (ssr || !onServer) { | ||
cache.actions[key] = () => action(args, stores).then(resp => { | ||
cache.actions[key] = () => action(args, stores) | ||
.then(resp => { | ||
if (currentActionOrd === cache.actionOrd[key]) { | ||
runPostActionHook(resp, args, stores, EPostActionContext.BECKON_RUN); | ||
cache.results[key] = [true, true, resp, false]; | ||
cache.results[key] = [true, true, resp, false, Date.now()]; | ||
} | ||
@@ -411,3 +418,9 @@ }) | ||
runPostActionHook(result, args, stores, EPostActionContext.BECKON_RUN); | ||
cache.results[key] = [true, true, result, false]; | ||
cache.results[key] = [ | ||
true, | ||
true, | ||
result, | ||
false, | ||
Date.now(), | ||
]; | ||
} | ||
@@ -437,2 +450,3 @@ }) | ||
false, | ||
-1, | ||
]; | ||
@@ -451,2 +465,3 @@ } | ||
false, | ||
-1, | ||
]; | ||
@@ -475,2 +490,6 @@ } | ||
const onAsyncStateChanged = () => { | ||
console.log(`[${key}][${watchId.current}] should update: ${shouldUpdate[key][watchId.current]}`); | ||
console.log(`[${key}][${watchId.current}] will update?: ${!isEqual$2(responseRef.current, cache.results[key])} - ${responseRef.current} !== ${cache.results[key]}`); | ||
console.log(responseRef.current); | ||
console.log(cache.results[key]); | ||
if (shouldUpdate[key][watchId.current] && !isEqual$2(responseRef.current, cache.results[key])) { | ||
@@ -490,4 +509,4 @@ responseRef.current = checkKeyAndReturnResponse(key, cache, initiate, ssr, args, stores, true, postActionEnabled, cacheBreakEnabled); | ||
React.useEffect(() => () => { | ||
delete cache.listeners[key][watchId.current]; | ||
shouldUpdate[key][watchId.current] = false; | ||
delete cache.listeners[key][watchId.current]; | ||
}, [key]); | ||
@@ -499,2 +518,3 @@ } | ||
if (prevKeyRef.current !== null && shouldUpdate.hasOwnProperty(prevKeyRef.current)) { | ||
delete cache.listeners[prevKeyRef.current][watchId.current]; | ||
shouldUpdate[prevKeyRef.current][watchId.current] = false; | ||
@@ -519,2 +539,3 @@ } | ||
stores: _stores, | ||
timeCached: _asyncCache.results[key][4], | ||
})) { | ||
@@ -536,3 +557,3 @@ delete _asyncCache.results[key]; | ||
if (shortCircuitResponse !== false) { | ||
_asyncCache.results[key] = [true, true, shortCircuitResponse, false]; | ||
_asyncCache.results[key] = [true, true, shortCircuitResponse, false, Date.now()]; | ||
runPostActionHook(shortCircuitResponse, args, _stores, EPostActionContext.SHORT_CIRCUIT); | ||
@@ -543,3 +564,3 @@ notifyListeners(key); | ||
} | ||
const [, prevFinished, prevResp] = _asyncCache.results[key] || [ | ||
const [, prevFinished, prevResp, prevUpdate, prevCacheTime] = _asyncCache.results[key] || [ | ||
false, | ||
@@ -553,5 +574,7 @@ false, | ||
}, | ||
false, | ||
-1, | ||
]; | ||
if (prevFinished && treatAsUpdate) { | ||
_asyncCache.results[key] = [true, true, prevResp, true]; | ||
_asyncCache.results[key] = [true, true, prevResp, true, prevCacheTime]; | ||
} | ||
@@ -569,2 +592,3 @@ else { | ||
false, | ||
-1, | ||
]; | ||
@@ -577,3 +601,3 @@ } | ||
if (currentActionOrd === _asyncCache.actionOrd[key]) { | ||
_asyncCache.results[key] = [true, true, result, false]; | ||
_asyncCache.results[key] = [true, true, result, false, Date.now()]; | ||
runPostActionHook(result, args, _stores, EPostActionContext.DIRECT_RUN); | ||
@@ -593,3 +617,3 @@ notifyListeners(key); | ||
if (currentActionOrd === _asyncCache.actionOrd[key]) { | ||
_asyncCache.results[key] = [true, true, result, false]; | ||
_asyncCache.results[key] = [true, true, result, false, Date.now()]; | ||
runPostActionHook(result, args, _stores, EPostActionContext.DIRECT_RUN); | ||
@@ -612,3 +636,11 @@ notifyListeners(key); | ||
}; | ||
const setCached = (args, result) => { | ||
const clearAllUnwatchedCache = () => { | ||
for (const key of Object.keys(shouldUpdate)) { | ||
if (!Object.values(shouldUpdate[key]).some(su => su)) { | ||
delete shouldUpdate[key]; | ||
clearActionCache(key, false); | ||
} | ||
} | ||
}; | ||
const setCached = (args, result, { notify = true }) => { | ||
const key = createKey(ordinal, args); | ||
@@ -618,5 +650,8 @@ const cache = onServer | ||
: clientAsyncCache; | ||
cache.results[key] = [true, true, result, false]; | ||
cache.results[key] = [true, true, result, false, Date.now()]; | ||
if (notify) { | ||
notifyListeners(key); | ||
} | ||
}; | ||
const updateCached = (args, updater) => { | ||
const updateCached = (args, updater, { notify = true, resetTimeCached = true } = {}) => { | ||
const key = createKey(ordinal, args); | ||
@@ -628,3 +663,17 @@ const cache = onServer | ||
const currentCached = cache.results[key][2].payload; | ||
cache.results[key][2].payload = produce$1(currentCached, s => updater(s, currentCached)); | ||
cache.results[key] = [ | ||
true, | ||
true, | ||
{ | ||
payload: produce$1(currentCached, s => updater(s, currentCached)), | ||
error: false, | ||
message: cache.results[key][2].message, | ||
tags: cache.results[key][2].tags, | ||
}, | ||
cache.results[key][3], | ||
cache.results[key][4], | ||
]; | ||
if (notify) { | ||
notifyListeners(key); | ||
} | ||
} | ||
@@ -645,2 +694,3 @@ }; | ||
stores, | ||
timeCached: cache.results[key][4], | ||
})) { | ||
@@ -650,3 +700,3 @@ cacheBreakable = true; | ||
} | ||
const [started, finished, result, updating] = cache.results[key]; | ||
const [started, finished, result, updating, timeCached] = cache.results[key]; | ||
return { | ||
@@ -659,2 +709,3 @@ started, | ||
updating, | ||
timeCached, | ||
}; | ||
@@ -675,2 +726,3 @@ } | ||
cacheBreakable, | ||
timeCached: -1, | ||
}; | ||
@@ -708,2 +760,3 @@ } | ||
clearAllCache, | ||
clearAllUnwatchedCache, | ||
getCached, | ||
@@ -710,0 +763,0 @@ setCached, |
{ | ||
"name": "pullstate", | ||
"version": "1.2.1-alpha.1", | ||
"version": "1.3.0", | ||
"description": "Simple state stores using immer and React hooks", | ||
@@ -48,4 +48,4 @@ "main": "dist/index.js", | ||
"jest-environment-jsdom-global": "1.2.0", | ||
"jest-dom": "^3.4.0", | ||
"lodash": "^4.17.14", | ||
"jest-dom": "^4.0.0", | ||
"lodash": "^4.17.15", | ||
"prettier": "^1.16.4", | ||
@@ -52,0 +52,0 @@ "react-test-renderer": "^16.8.3", |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
104165
2067
1