Comparing version 1.10.5 to 1.11.0
@@ -0,1 +1,42 @@ | ||
### 1.11.0 | ||
Added `AsyncActionName.use(args, options)` - a new way to make use of your Async Actions. By default it acts just like `useBeckon()`, except it returns an object instead of an array. | ||
The object now includes more helpful flags, and is shaped like so: | ||
```ts | ||
{ | ||
isLoading: boolean; | ||
isFinished: boolean; | ||
isUpdating: boolean; | ||
isStarted: boolean; | ||
endTags: string[]; | ||
renderPayload: ((payload) => any) => any; | ||
message: string; | ||
raw: TPullstateAsyncWatchResponse<R, T>; | ||
payload: R; | ||
error: boolean; | ||
} | ||
``` | ||
If you want `use()` to act like `useWatch()` (i.e. not initiating the action when the hook is first called), then pass in an options object as the second argument, containing `initiate: false`. | ||
`raw` is the same as you would expect to receive from `useWatch()`. The first array property will be `true` if you have not set `initiate: false`, since that represents if this action has been started - and this method acts like `useBeckon()` by default. | ||
`renderPayload` is a very useful function. You can use this in your React tree to conditionally render stuff only when your action payload has returned successfully. You can use it like so: | ||
```typescript jsx | ||
const userAction = LoadUserAction.use({ id: userId }); | ||
return ( | ||
<div> | ||
{userAction.renderPayload(user => ( | ||
<span>User Name: {user.name}</span> | ||
))} | ||
</div> | ||
); | ||
``` | ||
The inner `<span>` there will not render if our action hasn't resolved successfully. | ||
#### 1.10.5 | ||
@@ -33,12 +74,12 @@ | ||
* Added the ability to pass a third option to `useStoreState()` - this allows the our listener to be dynamically updated to listen to a different sub-state of our store. Similar to how the last argument in `useEffect()` and such work. | ||
* see https://github.com/lostpebble/pullstate/issues/22 | ||
- Added the ability to pass a third option to `useStoreState()` - this allows the our listener to be dynamically updated to listen to a different sub-state of our store. Similar to how the last argument in `useEffect()` and such work. | ||
- see https://github.com/lostpebble/pullstate/issues/22 | ||
#### React Suspense! | ||
* You can now use Async Actions with React Suspense. Simply use them with the format: `myAction.read(args)` inside a component which is inside of `<Suspend/>`. | ||
- You can now use Async Actions with React Suspense. Simply use them with the format: `myAction.read(args)` inside a component which is inside of `<Suspend/>`. | ||
## 1.8.0 | ||
* Added the passable option `{ dormant: true }` to Async Function's `useBeckon()` or `useWatch()`, which will basically just make the action completely dormant - no execution or hitting of cache or anything, but will still respect the option `{ holdPrevious: true }`, returning the last completed result for this action if it exists. | ||
- Added the passable option `{ dormant: true }` to Async Function's `useBeckon()` or `useWatch()`, which will basically just make the action completely dormant - no execution or hitting of cache or anything, but will still respect the option `{ holdPrevious: true }`, returning the last completed result for this action if it exists. | ||
@@ -45,0 +86,0 @@ ### 1.7.3 |
@@ -62,2 +62,3 @@ import { IPullstateAllStores } from "./PullstateCore"; | ||
cacheBreakEnabled?: boolean; | ||
key?: string; | ||
} | ||
@@ -76,2 +77,3 @@ export interface IAsyncActionBeckonOptions extends IAsyncActionReadOptions { | ||
respectCache?: boolean; | ||
key?: string; | ||
_asyncCache?: IPullstateAsyncCache; | ||
@@ -82,2 +84,3 @@ _stores?: S; | ||
checkCacheBreak?: boolean; | ||
key?: string; | ||
} | ||
@@ -95,2 +98,3 @@ export interface IGetCachedResponse<R, T extends string> { | ||
notify?: boolean; | ||
key?: string; | ||
} | ||
@@ -101,2 +105,3 @@ export interface IAsyncActionUpdateCachedOptions extends IAsyncActionSetCachedOptions { | ||
} | ||
export declare type TAsyncActionUse<A, R, T extends string> = (args?: A, options?: IAsyncActionWatchOptions) => TUseResponse<R, T>; | ||
export declare type TAsyncActionBeckon<A, R, T extends string> = (args?: A, options?: IAsyncActionBeckonOptions) => TPullstateAsyncBeckonResponse<R, T>; | ||
@@ -119,2 +124,3 @@ export declare type TAsyncActionWatch<A, R, T extends string> = (args?: A, options?: IAsyncActionWatchOptions) => TPullstateAsyncWatchResponse<R, T>; | ||
export interface IOCreateAsyncActionOutput<A = any, R = any, T extends string = string> { | ||
use: TAsyncActionUse<A, R, T>; | ||
read: TAsyncActionRead<A, R>; | ||
@@ -148,3 +154,2 @@ useBeckon: TAsyncActionBeckon<A, R, T>; | ||
forceContext?: boolean; | ||
clientStores?: S; | ||
shortCircuitHook?: TPullstateAsyncShortCircuitHook<A, R, T, S>; | ||
@@ -155,2 +160,22 @@ cacheBreakHook?: TPullstateAsyncCacheBreakHook<A, R, T, S>; | ||
} | ||
export declare type TRunWithPayload<R> = (func: (payload: R) => any) => any; | ||
export interface IBaseObjResponse<R, T extends string> { | ||
isLoading: boolean; | ||
isFinished: boolean; | ||
isUpdating: boolean; | ||
isStarted: boolean; | ||
endTags: (T | EAsyncEndTags)[]; | ||
renderPayload: TRunWithPayload<R>; | ||
message: string; | ||
raw: TPullstateAsyncWatchResponse<R, T>; | ||
} | ||
export interface IBaseObjSuccessResponse<R, T extends string> extends IBaseObjResponse<R, T> { | ||
payload: R; | ||
error: false; | ||
} | ||
export interface IBaseObjErrorResponse<R, T extends string> extends IBaseObjResponse<R, T> { | ||
payload: null; | ||
error: true; | ||
} | ||
export declare type TUseResponse<R = any, T extends string = string> = IBaseObjSuccessResponse<R, T> | IBaseObjErrorResponse<R, T>; | ||
export {}; |
@@ -12,2 +12,2 @@ import { IPullstateAllStores } from "./PullstateCore"; | ||
} | ||
export declare function createAsyncAction<A = any, R = any, T extends string = string, S extends IPullstateAllStores = IPullstateAllStores>(action: TPullstateAsyncAction<A, R, T, S>, { forceContext, clientStores, shortCircuitHook, cacheBreakHook, postActionHook, subsetKey, }?: ICreateAsyncActionOptions<A, R, T, S>): IOCreateAsyncActionOutput<A, R, T>; | ||
export declare function createAsyncAction<A = any, R = any, T extends string = string, S extends IPullstateAllStores = IPullstateAllStores>(action: TPullstateAsyncAction<A, R, T, S>, { forceContext, shortCircuitHook, cacheBreakHook, postActionHook, subsetKey, }?: ICreateAsyncActionOptions<A, R, T, S>): IOCreateAsyncActionOutput<A, R, T>; |
@@ -9,3 +9,4 @@ import { useStoreState } from "./useStoreState"; | ||
import { InjectStoreStateOpt } from "./InjectStoreStateOpt"; | ||
import { TUseResponse } from "./async-types"; | ||
export * from "./async-types"; | ||
export { useStoreState, useStoreStateOpt, update, Store, InjectStoreState, InjectStoreStateOpt, PullstateProvider, useStores, useInstance, createPullstateCore, createAsyncAction, successResult, errorResult, IPullstateInstanceConsumable, IPullstateAllStores, InjectAsyncAction, EAsyncActionInjectType, TInjectAsyncActionProps, TUpdateFunction, PullstateContext, }; | ||
export { useStoreState, useStoreStateOpt, update, Store, InjectStoreState, InjectStoreStateOpt, PullstateProvider, useStores, useInstance, createPullstateCore, createAsyncAction, successResult, errorResult, IPullstateInstanceConsumable, IPullstateAllStores, InjectAsyncAction, EAsyncActionInjectType, TInjectAsyncActionProps, TUpdateFunction, PullstateContext, TUseResponse, }; |
@@ -317,5 +317,3 @@ import isEqual from'fast-deep-equal/es6';import React,{useRef,useState,useEffect,useContext,useMemo}from'react';import produce$1,{produceWithPatches,produce,applyPatches}from'immer';function useStoreState(store, getSubState, deps) { | ||
: updater.reduce((previousValue, currentUpdater) => { | ||
return produce(previousValue, s => { | ||
currentUpdater(s, previousValue); | ||
}); | ||
return produce(previousValue, s => currentUpdater(s, previousValue)); | ||
}, currentState)); | ||
@@ -379,5 +377,3 @@ } | ||
if (clientAsyncCache.listeners.hasOwnProperty(key)) { | ||
console.log(`[${key}] Notifying (${Object.keys(clientAsyncCache.listeners[key]).length}) listeners`); | ||
for (const watchId of Object.keys(clientAsyncCache.listeners[key])) { | ||
console.log(`[${key}] Notifying listener with watch id: [${watchId}]`); | ||
clientAsyncCache.listeners[key][watchId](); | ||
@@ -425,6 +421,20 @@ } | ||
} | ||
function createAsyncAction(action, { forceContext = false, clientStores = {}, shortCircuitHook, cacheBreakHook, postActionHook, subsetKey, } = {}) { | ||
const storeErrorProxy = new Proxy({}, { | ||
get: function (obj, prop) { | ||
throw new Error(`Pullstate: Trying to access store (${String(prop)}) inside async actions without the correct usage or setup. | ||
If this error occurred on the server: | ||
* If using run(), make use of your created instance for this request: instance.runAsyncAction() | ||
* If using read(), useWatch(), useBeckon() etc. - make sure you have properly set up your <PullstateProvider/> | ||
If this error occurred on the client: | ||
* Make sure you have created your "pullstateCore" object with all your stores, using createPullstateCore(), and are making use of instantiate() before rendering.`); | ||
}, | ||
}); | ||
function createAsyncAction(action, { forceContext = false, shortCircuitHook, cacheBreakHook, postActionHook, subsetKey, } = {}) { | ||
const ordinal = asyncCreationOrdinal++; | ||
const onServer = typeof window === "undefined"; | ||
function _createKey(keyOrdinal, args) { | ||
function _createKey(keyOrdinal, args, customKey) { | ||
if (customKey) { | ||
return `${keyOrdinal}-c-${customKey}`; | ||
} | ||
if (subsetKey !== undefined) { | ||
@@ -577,6 +587,10 @@ return `${keyOrdinal}-${keyFromObject(subsetKey(args))}`; | ||
} | ||
const read = (args = {}, { cacheBreakEnabled = true, postActionEnabled = true } = {}) => { | ||
const key = _createKey(ordinal, args); | ||
const read = (args = {}, { cacheBreakEnabled = true, postActionEnabled = true, key: customKey } = {}) => { | ||
const key = _createKey(ordinal, args, customKey); | ||
const cache = onServer ? useContext(PullstateContext)._asyncCache : clientAsyncCache; | ||
const stores = onServer || forceContext ? useContext(PullstateContext).stores : clientStores; | ||
const stores = onServer || forceContext | ||
? useContext(PullstateContext).stores | ||
: clientStores.loaded | ||
? clientStores.stores | ||
: storeErrorProxy; | ||
const cached = getCachedResult(key, cache, args, stores, EPostActionContext.READ_HIT_CACHE, postActionEnabled, cacheBreakEnabled, false); | ||
@@ -620,6 +634,6 @@ if (cached) { | ||
}; | ||
const useWatch = (args = {}, { initiate = false, ssr = true, postActionEnabled = false, cacheBreakEnabled = false, holdPrevious = false, dormant = false, } = {}) => { | ||
const useWatch = (args = {}, { initiate = false, ssr = true, postActionEnabled = false, cacheBreakEnabled = false, holdPrevious = false, dormant = false, key: customKey, } = {}) => { | ||
const responseRef = useRef(); | ||
const prevKeyRef = useRef("."); | ||
const key = dormant ? "." : _createKey(ordinal, args); | ||
const key = dormant ? "." : _createKey(ordinal, args, customKey); | ||
let watchId = useRef(-1); | ||
@@ -640,3 +654,7 @@ if (watchId.current === -1) { | ||
const cache = onServer ? useContext(PullstateContext)._asyncCache : clientAsyncCache; | ||
const stores = onServer || forceContext ? useContext(PullstateContext).stores : clientStores; | ||
const stores = onServer || forceContext | ||
? useContext(PullstateContext).stores | ||
: clientStores.loaded | ||
? clientStores.stores | ||
: storeErrorProxy; | ||
if (!onServer) { | ||
@@ -699,4 +717,4 @@ const onAsyncStateChanged = () => { | ||
}; | ||
const run = async (args = {}, { treatAsUpdate = false, ignoreShortCircuit = false, respectCache = false, _asyncCache = clientAsyncCache, _stores = clientStores, } = {}) => { | ||
const key = _createKey(ordinal, args); | ||
const run = async (args = {}, { treatAsUpdate = false, ignoreShortCircuit = false, respectCache = false, key: customKey, _asyncCache = clientAsyncCache, _stores = clientStores.loaded ? clientStores.stores : storeErrorProxy, } = {}) => { | ||
const key = _createKey(ordinal, args, customKey); | ||
if (respectCache) { | ||
@@ -751,4 +769,4 @@ const cached = getCachedResult(key, _asyncCache, args, _stores, EPostActionContext.RUN_HIT_CACHE, true, true, false); | ||
}; | ||
const clearCache = (args = {}) => { | ||
const key = _createKey(ordinal, args); | ||
const clearCache = (args = {}, customKey) => { | ||
const key = _createKey(ordinal, args, customKey); | ||
clearActionCache(key); | ||
@@ -772,4 +790,4 @@ }; | ||
const setCached = (args, result, options) => { | ||
const { notify = true } = options || {}; | ||
const key = _createKey(ordinal, args); | ||
const { notify = true, key: customKey } = options || {}; | ||
const key = _createKey(ordinal, args, customKey); | ||
const cache = onServer ? useContext(PullstateContext)._asyncCache : clientAsyncCache; | ||
@@ -785,4 +803,4 @@ cache.results[key] = [true, true, result, false, Date.now()]; | ||
const updateCached = (args, updater, options) => { | ||
const { notify = true, resetTimeCached = true, runPostActionHook: postAction = false } = options || {}; | ||
const key = _createKey(ordinal, args); | ||
const { notify = true, resetTimeCached = true, runPostActionHook: postAction = false, key: customKey } = options || {}; | ||
const key = _createKey(ordinal, args, customKey); | ||
const cache = onServer ? useContext(PullstateContext)._asyncCache : clientAsyncCache; | ||
@@ -798,3 +816,3 @@ if (cache.results.hasOwnProperty(key) && !cache.results[key][2].error) { | ||
if (postAction) { | ||
runPostActionHook(newResult, args, clientStores, EPostActionContext.CACHE_UPDATE); | ||
runPostActionHook(newResult, args, clientStores.loaded ? clientStores.stores : storeErrorProxy, EPostActionContext.CACHE_UPDATE); | ||
} | ||
@@ -814,4 +832,4 @@ cache.results[key] = [ | ||
const getCached = (args = {}, options) => { | ||
const { checkCacheBreak = false } = options || {}; | ||
const key = _createKey(ordinal, args); | ||
const { checkCacheBreak = false, key: customKey } = options || {}; | ||
const key = _createKey(ordinal, args, customKey); | ||
let cacheBreakable = false; | ||
@@ -821,3 +839,7 @@ const cache = onServer ? useContext(PullstateContext)._asyncCache : clientAsyncCache; | ||
if (checkCacheBreak && cacheBreakHook !== undefined) { | ||
const stores = onServer ? useContext(PullstateContext).stores : clientStores; | ||
const stores = onServer | ||
? useContext(PullstateContext).stores | ||
: clientStores.loaded | ||
? clientStores.stores | ||
: storeErrorProxy; | ||
if (cacheBreakHook({ | ||
@@ -882,3 +904,32 @@ args, | ||
}; | ||
const use = (args, { initiate = true, ssr = true, postActionEnabled, cacheBreakEnabled, holdPrevious = false, dormant = false, key } = {}) => { | ||
if (postActionEnabled == null) { | ||
postActionEnabled = initiate; | ||
} | ||
if (cacheBreakEnabled == null) { | ||
cacheBreakEnabled = initiate; | ||
} | ||
const raw = useWatch(args, { initiate, ssr, postActionEnabled, cacheBreakEnabled, holdPrevious, dormant, key }); | ||
const [isStarted, isFinished, result, isUpdating] = raw; | ||
const renderPayload = func => { | ||
if (!result.error) { | ||
return func(result.payload); | ||
} | ||
return React.Fragment; | ||
}; | ||
return { | ||
isStarted, | ||
isFinished, | ||
isUpdating, | ||
isLoading: isStarted && (!isFinished || isUpdating), | ||
endTags: result.tags, | ||
error: result.error, | ||
payload: result.payload, | ||
renderPayload, | ||
message: result.message, | ||
raw, | ||
}; | ||
}; | ||
return { | ||
use, | ||
read, | ||
@@ -902,5 +953,9 @@ useBeckon, | ||
let singleton = null; | ||
const clientStores = { | ||
internalClientStores: true, | ||
loaded: false, | ||
stores: {}, | ||
}; | ||
class PullstateSingleton { | ||
constructor(allStores) { | ||
this.originStores = {}; | ||
if (singleton !== null) { | ||
@@ -910,7 +965,8 @@ console.error(`Pullstate: createPullstate() - Should not be creating the core Pullstate class more than once! In order to re-use pull state, you need to call instantiate() on your already created object.`); | ||
singleton = this; | ||
this.originStores = allStores; | ||
clientStores.stores = allStores; | ||
clientStores.loaded = true; | ||
} | ||
instantiate({ hydrateSnapshot, ssr = false, } = {}) { | ||
if (!ssr) { | ||
const instantiated = new PullstateInstance(this.originStores, false); | ||
const instantiated = new PullstateInstance(clientStores.stores, false); | ||
if (hydrateSnapshot != null) { | ||
@@ -923,5 +979,5 @@ instantiated.hydrateFromSnapshot(hydrateSnapshot); | ||
const newStores = {}; | ||
for (const storeName of Object.keys(this.originStores)) { | ||
for (const storeName of Object.keys(clientStores.stores)) { | ||
if (hydrateSnapshot == null) { | ||
newStores[storeName] = new Store(this.originStores[storeName]._getInitialState()); | ||
newStores[storeName] = new Store(clientStores.stores[storeName]._getInitialState()); | ||
} | ||
@@ -932,3 +988,3 @@ else if (hydrateSnapshot.hasOwnProperty(storeName)) { | ||
else { | ||
newStores[storeName] = new Store(this.originStores[storeName]._getInitialState()); | ||
newStores[storeName] = new Store(clientStores.stores[storeName]._getInitialState()); | ||
console.warn(`Pullstate (instantiate): store [${storeName}] didn't hydrate any state (data was non-existent on hydration object)`); | ||
@@ -938,3 +994,3 @@ } | ||
ssr, | ||
reactionCreators: this.originStores[storeName]._getReactionCreators(), | ||
reactionCreators: clientStores.stores[storeName]._getReactionCreators(), | ||
}); | ||
@@ -951,3 +1007,2 @@ } | ||
createAsyncAction(action, options = {}) { | ||
options.clientStores = this.originStores; | ||
return createAsyncAction(action, options); | ||
@@ -954,0 +1009,0 @@ } |
@@ -317,5 +317,3 @@ 'use strict';Object.defineProperty(exports,'__esModule',{value:true});function _interopDefault(e){return(e&&(typeof e==='object')&&'default'in e)?e['default']:e}var isEqual=_interopDefault(require('fast-deep-equal/es6')),React=require('react'),React__default=_interopDefault(React),produce=require('immer'),produce__default=_interopDefault(produce);function useStoreState(store, getSubState, deps) { | ||
: updater.reduce((previousValue, currentUpdater) => { | ||
return produce.produce(previousValue, s => { | ||
currentUpdater(s, previousValue); | ||
}); | ||
return produce.produce(previousValue, s => currentUpdater(s, previousValue)); | ||
}, currentState)); | ||
@@ -377,5 +375,3 @@ } | ||
if (clientAsyncCache.listeners.hasOwnProperty(key)) { | ||
console.log(`[${key}] Notifying (${Object.keys(clientAsyncCache.listeners[key]).length}) listeners`); | ||
for (const watchId of Object.keys(clientAsyncCache.listeners[key])) { | ||
console.log(`[${key}] Notifying listener with watch id: [${watchId}]`); | ||
clientAsyncCache.listeners[key][watchId](); | ||
@@ -423,6 +419,20 @@ } | ||
} | ||
function createAsyncAction(action, { forceContext = false, clientStores = {}, shortCircuitHook, cacheBreakHook, postActionHook, subsetKey, } = {}) { | ||
const storeErrorProxy = new Proxy({}, { | ||
get: function (obj, prop) { | ||
throw new Error(`Pullstate: Trying to access store (${String(prop)}) inside async actions without the correct usage or setup. | ||
If this error occurred on the server: | ||
* If using run(), make use of your created instance for this request: instance.runAsyncAction() | ||
* If using read(), useWatch(), useBeckon() etc. - make sure you have properly set up your <PullstateProvider/> | ||
If this error occurred on the client: | ||
* Make sure you have created your "pullstateCore" object with all your stores, using createPullstateCore(), and are making use of instantiate() before rendering.`); | ||
}, | ||
}); | ||
function createAsyncAction(action, { forceContext = false, shortCircuitHook, cacheBreakHook, postActionHook, subsetKey, } = {}) { | ||
const ordinal = asyncCreationOrdinal++; | ||
const onServer = typeof window === "undefined"; | ||
function _createKey(keyOrdinal, args) { | ||
function _createKey(keyOrdinal, args, customKey) { | ||
if (customKey) { | ||
return `${keyOrdinal}-c-${customKey}`; | ||
} | ||
if (subsetKey !== undefined) { | ||
@@ -575,6 +585,10 @@ return `${keyOrdinal}-${keyFromObject(subsetKey(args))}`; | ||
} | ||
const read = (args = {}, { cacheBreakEnabled = true, postActionEnabled = true } = {}) => { | ||
const key = _createKey(ordinal, args); | ||
const read = (args = {}, { cacheBreakEnabled = true, postActionEnabled = true, key: customKey } = {}) => { | ||
const key = _createKey(ordinal, args, customKey); | ||
const cache = onServer ? React.useContext(PullstateContext)._asyncCache : clientAsyncCache; | ||
const stores = onServer || forceContext ? React.useContext(PullstateContext).stores : clientStores; | ||
const stores = onServer || forceContext | ||
? React.useContext(PullstateContext).stores | ||
: clientStores.loaded | ||
? clientStores.stores | ||
: storeErrorProxy; | ||
const cached = getCachedResult(key, cache, args, stores, exports.EPostActionContext.READ_HIT_CACHE, postActionEnabled, cacheBreakEnabled, false); | ||
@@ -618,6 +632,6 @@ if (cached) { | ||
}; | ||
const useWatch = (args = {}, { initiate = false, ssr = true, postActionEnabled = false, cacheBreakEnabled = false, holdPrevious = false, dormant = false, } = {}) => { | ||
const useWatch = (args = {}, { initiate = false, ssr = true, postActionEnabled = false, cacheBreakEnabled = false, holdPrevious = false, dormant = false, key: customKey, } = {}) => { | ||
const responseRef = React.useRef(); | ||
const prevKeyRef = React.useRef("."); | ||
const key = dormant ? "." : _createKey(ordinal, args); | ||
const key = dormant ? "." : _createKey(ordinal, args, customKey); | ||
let watchId = React.useRef(-1); | ||
@@ -638,3 +652,7 @@ if (watchId.current === -1) { | ||
const cache = onServer ? React.useContext(PullstateContext)._asyncCache : clientAsyncCache; | ||
const stores = onServer || forceContext ? React.useContext(PullstateContext).stores : clientStores; | ||
const stores = onServer || forceContext | ||
? React.useContext(PullstateContext).stores | ||
: clientStores.loaded | ||
? clientStores.stores | ||
: storeErrorProxy; | ||
if (!onServer) { | ||
@@ -697,4 +715,4 @@ const onAsyncStateChanged = () => { | ||
}; | ||
const run = async (args = {}, { treatAsUpdate = false, ignoreShortCircuit = false, respectCache = false, _asyncCache = clientAsyncCache, _stores = clientStores, } = {}) => { | ||
const key = _createKey(ordinal, args); | ||
const run = async (args = {}, { treatAsUpdate = false, ignoreShortCircuit = false, respectCache = false, key: customKey, _asyncCache = clientAsyncCache, _stores = clientStores.loaded ? clientStores.stores : storeErrorProxy, } = {}) => { | ||
const key = _createKey(ordinal, args, customKey); | ||
if (respectCache) { | ||
@@ -749,4 +767,4 @@ const cached = getCachedResult(key, _asyncCache, args, _stores, exports.EPostActionContext.RUN_HIT_CACHE, true, true, false); | ||
}; | ||
const clearCache = (args = {}) => { | ||
const key = _createKey(ordinal, args); | ||
const clearCache = (args = {}, customKey) => { | ||
const key = _createKey(ordinal, args, customKey); | ||
clearActionCache(key); | ||
@@ -770,4 +788,4 @@ }; | ||
const setCached = (args, result, options) => { | ||
const { notify = true } = options || {}; | ||
const key = _createKey(ordinal, args); | ||
const { notify = true, key: customKey } = options || {}; | ||
const key = _createKey(ordinal, args, customKey); | ||
const cache = onServer ? React.useContext(PullstateContext)._asyncCache : clientAsyncCache; | ||
@@ -783,4 +801,4 @@ cache.results[key] = [true, true, result, false, Date.now()]; | ||
const updateCached = (args, updater, options) => { | ||
const { notify = true, resetTimeCached = true, runPostActionHook: postAction = false } = options || {}; | ||
const key = _createKey(ordinal, args); | ||
const { notify = true, resetTimeCached = true, runPostActionHook: postAction = false, key: customKey } = options || {}; | ||
const key = _createKey(ordinal, args, customKey); | ||
const cache = onServer ? React.useContext(PullstateContext)._asyncCache : clientAsyncCache; | ||
@@ -796,3 +814,3 @@ if (cache.results.hasOwnProperty(key) && !cache.results[key][2].error) { | ||
if (postAction) { | ||
runPostActionHook(newResult, args, clientStores, exports.EPostActionContext.CACHE_UPDATE); | ||
runPostActionHook(newResult, args, clientStores.loaded ? clientStores.stores : storeErrorProxy, exports.EPostActionContext.CACHE_UPDATE); | ||
} | ||
@@ -812,4 +830,4 @@ cache.results[key] = [ | ||
const getCached = (args = {}, options) => { | ||
const { checkCacheBreak = false } = options || {}; | ||
const key = _createKey(ordinal, args); | ||
const { checkCacheBreak = false, key: customKey } = options || {}; | ||
const key = _createKey(ordinal, args, customKey); | ||
let cacheBreakable = false; | ||
@@ -819,3 +837,7 @@ const cache = onServer ? React.useContext(PullstateContext)._asyncCache : clientAsyncCache; | ||
if (checkCacheBreak && cacheBreakHook !== undefined) { | ||
const stores = onServer ? React.useContext(PullstateContext).stores : clientStores; | ||
const stores = onServer | ||
? React.useContext(PullstateContext).stores | ||
: clientStores.loaded | ||
? clientStores.stores | ||
: storeErrorProxy; | ||
if (cacheBreakHook({ | ||
@@ -880,3 +902,32 @@ args, | ||
}; | ||
const use = (args, { initiate = true, ssr = true, postActionEnabled, cacheBreakEnabled, holdPrevious = false, dormant = false, key } = {}) => { | ||
if (postActionEnabled == null) { | ||
postActionEnabled = initiate; | ||
} | ||
if (cacheBreakEnabled == null) { | ||
cacheBreakEnabled = initiate; | ||
} | ||
const raw = useWatch(args, { initiate, ssr, postActionEnabled, cacheBreakEnabled, holdPrevious, dormant, key }); | ||
const [isStarted, isFinished, result, isUpdating] = raw; | ||
const renderPayload = func => { | ||
if (!result.error) { | ||
return func(result.payload); | ||
} | ||
return React__default.Fragment; | ||
}; | ||
return { | ||
isStarted, | ||
isFinished, | ||
isUpdating, | ||
isLoading: isStarted && (!isFinished || isUpdating), | ||
endTags: result.tags, | ||
error: result.error, | ||
payload: result.payload, | ||
renderPayload, | ||
message: result.message, | ||
raw, | ||
}; | ||
}; | ||
return { | ||
use, | ||
read, | ||
@@ -900,5 +951,9 @@ useBeckon, | ||
let singleton = null; | ||
const clientStores = { | ||
internalClientStores: true, | ||
loaded: false, | ||
stores: {}, | ||
}; | ||
class PullstateSingleton { | ||
constructor(allStores) { | ||
this.originStores = {}; | ||
if (singleton !== null) { | ||
@@ -908,7 +963,8 @@ console.error(`Pullstate: createPullstate() - Should not be creating the core Pullstate class more than once! In order to re-use pull state, you need to call instantiate() on your already created object.`); | ||
singleton = this; | ||
this.originStores = allStores; | ||
clientStores.stores = allStores; | ||
clientStores.loaded = true; | ||
} | ||
instantiate({ hydrateSnapshot, ssr = false, } = {}) { | ||
if (!ssr) { | ||
const instantiated = new PullstateInstance(this.originStores, false); | ||
const instantiated = new PullstateInstance(clientStores.stores, false); | ||
if (hydrateSnapshot != null) { | ||
@@ -921,5 +977,5 @@ instantiated.hydrateFromSnapshot(hydrateSnapshot); | ||
const newStores = {}; | ||
for (const storeName of Object.keys(this.originStores)) { | ||
for (const storeName of Object.keys(clientStores.stores)) { | ||
if (hydrateSnapshot == null) { | ||
newStores[storeName] = new Store(this.originStores[storeName]._getInitialState()); | ||
newStores[storeName] = new Store(clientStores.stores[storeName]._getInitialState()); | ||
} | ||
@@ -930,3 +986,3 @@ else if (hydrateSnapshot.hasOwnProperty(storeName)) { | ||
else { | ||
newStores[storeName] = new Store(this.originStores[storeName]._getInitialState()); | ||
newStores[storeName] = new Store(clientStores.stores[storeName]._getInitialState()); | ||
console.warn(`Pullstate (instantiate): store [${storeName}] didn't hydrate any state (data was non-existent on hydration object)`); | ||
@@ -936,3 +992,3 @@ } | ||
ssr, | ||
reactionCreators: this.originStores[storeName]._getReactionCreators(), | ||
reactionCreators: clientStores.stores[storeName]._getReactionCreators(), | ||
}); | ||
@@ -949,3 +1005,2 @@ } | ||
createAsyncAction(action, options = {}) { | ||
options.clientStores = this.originStores; | ||
return createAsyncAction(action, options); | ||
@@ -952,0 +1007,0 @@ } |
@@ -12,4 +12,8 @@ import React from "react"; | ||
}) => JSX.Element; | ||
export declare const clientStores: { | ||
internalClientStores: true; | ||
stores: IPullstateAllStores; | ||
loaded: boolean; | ||
}; | ||
export declare class PullstateSingleton<S extends IPullstateAllStores = IPullstateAllStores> { | ||
private readonly originStores; | ||
constructor(allStores: S); | ||
@@ -16,0 +20,0 @@ instantiate({ hydrateSnapshot, ssr, }?: { |
{ | ||
"name": "pullstate", | ||
"version": "1.10.5", | ||
"version": "1.11.0", | ||
"description": "Simple state stores using immer and React hooks", | ||
@@ -17,2 +17,3 @@ "main": "dist/index.js", | ||
"uglify": "terser ./dist/index.js -o ./dist/index.js", | ||
"check-size": "minified-size ./dist/index.es.js", | ||
"benchmark-all": "cross-env TS_NODE_PROJECT=./test/tsconfig.json node -r ts-node/register --max-old-space-size=4096 test/benchmark/all.ts", | ||
@@ -19,0 +20,0 @@ "benchmark-async-argument": "cross-env TS_NODE_PROJECT=./test/tsconfig.json node -r ts-node/register --max-old-space-size=4096 test/benchmark/benchmark-async-argument.ts", |
133825
2527