Comparing version 1.8.0 to 1.9.0
@@ -0,1 +1,10 @@ | ||
## 1.9.0 | ||
* 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/>`. | ||
## 1.8.0 | ||
@@ -2,0 +11,0 @@ |
@@ -45,2 +45,4 @@ import { IPullstateAllStores } from "./PullstateCore"; | ||
RUN_HIT_CACHE = "RUN_HIT_CACHE", | ||
READ_HIT_CACHE = "READ_HIT_CACHE", | ||
READ_RUN = "READ_RUN", | ||
SHORT_CIRCUIT = "SHORT_CIRCUIT", | ||
@@ -56,6 +58,8 @@ DIRECT_RUN = "DIRECT_RUN", | ||
}) => void; | ||
export interface IAsyncActionBeckonOptions { | ||
ssr?: boolean; | ||
export interface IAsyncActionReadOptions { | ||
postActionEnabled?: boolean; | ||
cacheBreakEnabled?: boolean; | ||
} | ||
export interface IAsyncActionBeckonOptions extends IAsyncActionReadOptions { | ||
ssr?: boolean; | ||
holdPrevious?: boolean; | ||
@@ -102,2 +106,3 @@ dormant?: boolean; | ||
export declare type TAsyncActionUpdateCached<A, R> = (args: A, updater: TUpdateFunction<R>, options?: IAsyncActionUpdateCachedOptions) => void; | ||
export declare type TAsyncActionRead<A, R> = (args?: A, options?: IAsyncActionReadOptions) => R; | ||
export declare type TAsyncActionDelayedRun<A> = (args: A, options: IAsyncActionRunOptions & { | ||
@@ -109,2 +114,3 @@ delay: number; | ||
export interface IOCreateAsyncActionOutput<A = any, R = any, T extends string = string> { | ||
read: TAsyncActionRead<A, R>; | ||
useBeckon: TAsyncActionBeckon<A, R, T>; | ||
@@ -111,0 +117,0 @@ useWatch: TAsyncActionWatch<A, R, T>; |
@@ -7,2 +7,7 @@ import { IPullstateAllStores } from "./PullstateCore"; | ||
export declare function errorResult<R = any, T extends string = string>(tags?: (EAsyncEndTags | T)[], message?: string): IAsyncActionResultNegative<T>; | ||
export declare class PullstateAsyncError extends Error { | ||
message: string; | ||
tags: string[]; | ||
constructor(message: string, tags: string[]); | ||
} | ||
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>; |
import { useStoreState } from "./useStoreState"; | ||
import { useStoreStateOpt } from "./useStoreStateOpt"; | ||
import { Store, update, TUpdateFunction } from "./Store"; | ||
import { Store, TUpdateFunction, update } from "./Store"; | ||
import { InjectStoreState } from "./InjectStoreState"; | ||
import { createPullstateCore, IPullstateInstanceConsumable, PullstateProvider, useStores, PullstateContext, useInstance } from "./PullstateCore"; | ||
import { createPullstateCore, IPullstateInstanceConsumable, PullstateContext, PullstateProvider, useInstance, useStores } from "./PullstateCore"; | ||
import { createAsyncAction, errorResult, successResult } from "./async"; | ||
import { EAsyncActionInjectType, InjectAsyncAction, TInjectAsyncActionProps } from "./InjectAsyncAction"; | ||
import { EAsyncEndTags, TPullstateAsyncAction, TAsyncActionResult } from "./async-types"; | ||
import { EAsyncEndTags, TAsyncActionResult, TPullstateAsyncAction } from "./async-types"; | ||
import { InjectStoreStateOpt } from "./InjectStoreStateOpt"; | ||
export { useStoreState, useStoreStateOpt, update, Store, InjectStoreState, InjectStoreStateOpt, PullstateProvider, useStores, useInstance, createPullstateCore, createAsyncAction, successResult, errorResult, EAsyncEndTags, IPullstateInstanceConsumable, InjectAsyncAction, EAsyncActionInjectType, TInjectAsyncActionProps, TPullstateAsyncAction, TAsyncActionResult, TUpdateFunction, PullstateContext, }; |
import React,{useState,useRef,useEffect,useContext,useMemo}from'react';import produce$1 from'immer';const isEqual = require("fast-deep-equal"); | ||
function useStoreState(store, getSubState) { | ||
function useStoreState(store, getSubState, deps) { | ||
const [subState, setSubState] = useState(() => getSubState ? getSubState(store.getRawState()) : store.getRawState()); | ||
@@ -25,3 +25,10 @@ const updateRef = useRef({ | ||
}, []); | ||
return subState; | ||
if (deps !== undefined) { | ||
const prevDeps = useRef(deps); | ||
if (!isEqual(deps, prevDeps)) { | ||
updateRef.current.getSubState = getSubState; | ||
updateRef.current.currentSubState = getSubState(store.getRawState()); | ||
} | ||
} | ||
return updateRef.current.currentSubState; | ||
}let updateListenerOrd = 0; | ||
@@ -232,4 +239,4 @@ function fastGet(obj, path) { | ||
} | ||
useState(getSubState) { | ||
return useStoreState(this, getSubState); | ||
useState(getSubState, deps) { | ||
return useStoreState(this, getSubState, deps); | ||
} | ||
@@ -328,2 +335,4 @@ update(updater, patchesCallback) { | ||
EPostActionContext["RUN_HIT_CACHE"] = "RUN_HIT_CACHE"; | ||
EPostActionContext["READ_HIT_CACHE"] = "READ_HIT_CACHE"; | ||
EPostActionContext["READ_RUN"] = "READ_RUN"; | ||
EPostActionContext["SHORT_CIRCUIT"] = "SHORT_CIRCUIT"; | ||
@@ -341,25 +350,22 @@ EPostActionContext["DIRECT_RUN"] = "DIRECT_RUN"; | ||
function keyFromObject(json) { | ||
if (json == null) { | ||
return `${json}`; | ||
if (json === null) { | ||
return "(n)"; | ||
} | ||
if (typeof json !== "object") { | ||
return `${json}`; | ||
} | ||
let prefix = "{"; | ||
for (const key of Object.keys(json).sort()) { | ||
prefix += key; | ||
if (typeof json[key] == null) { | ||
prefix += JSON.stringify(json[key]); | ||
const typeOf = typeof json; | ||
if (typeOf !== "object") { | ||
if (typeOf === "undefined") { | ||
return "(u)"; | ||
} | ||
else if (typeof json[key] === "string") { | ||
prefix += `~${json[key]}~`; | ||
else if (typeOf === "string") { | ||
return ":" + json + ";"; | ||
} | ||
else if (typeof json[key] === "boolean" || typeof json[key] === "number") { | ||
prefix += json[key]; | ||
else if (typeOf === "boolean" || typeOf === "number") { | ||
return "(" + json + ")"; | ||
} | ||
else { | ||
prefix += `{${keyFromObject(json[key])}}`; | ||
} | ||
} | ||
return (prefix += "}"); | ||
let prefix = "{"; | ||
for (const key of Object.keys(json).sort()) { | ||
prefix += key + keyFromObject(json[key]); | ||
} | ||
return prefix + "}"; | ||
} | ||
@@ -405,2 +411,8 @@ function notifyListeners(key) { | ||
} | ||
class PullstateAsyncError extends Error { | ||
constructor(message, tags) { | ||
super(message); | ||
this.tags = tags; | ||
} | ||
} | ||
function createAsyncAction(action, { forceContext = false, clientStores = {}, shortCircuitHook, cacheBreakHook, postActionHook, subsetKey, } = {}) { | ||
@@ -423,3 +435,3 @@ const ordinal = asyncCreationOrdinal++; | ||
} | ||
function checkKeyAndReturnResponse(key, cache, initiate, ssr, args, stores, fromListener = false, postActionEnabled = true, cacheBreakEnabled = true, holdingResult = undefined) { | ||
function getCachedResult(key, cache, args, stores, context, postActionEnabled, cacheBreakEnabled, fromListener) { | ||
if (cache.results.hasOwnProperty(key)) { | ||
@@ -455,3 +467,3 @@ const cacheBreakLoop = cacheBreakWatcher.hasOwnProperty(key) && cacheBreakWatcher[key] > 2; | ||
if (postActionEnabled && cache.results[key][1] && !fromListener) { | ||
runPostActionHook(cache.results[key][2], args, stores, initiate ? EPostActionContext.BECKON_HIT_CACHE : EPostActionContext.WATCH_HIT_CACHE); | ||
runPostActionHook(cache.results[key][2], args, stores, context); | ||
} | ||
@@ -461,2 +473,44 @@ return cache.results[key]; | ||
} | ||
return undefined; | ||
} | ||
function createInternalAction(key, cache, args, stores, currentActionOrd, postActionEnabled, context) { | ||
return () => action(args, stores) | ||
.then(resp => { | ||
if (currentActionOrd === cache.actionOrd[key]) { | ||
if (postActionEnabled) { | ||
runPostActionHook(resp, args, stores, context); | ||
} | ||
cache.results[key] = [true, true, resp, false, Date.now()]; | ||
} | ||
return resp; | ||
}) | ||
.catch(e => { | ||
console.error(e); | ||
const result = { | ||
payload: null, | ||
error: true, | ||
tags: [EAsyncEndTags.THREW_ERROR], | ||
message: e.message, | ||
}; | ||
if (currentActionOrd === cache.actionOrd[key]) { | ||
if (postActionEnabled) { | ||
runPostActionHook(result, args, stores, context); | ||
} | ||
cache.results[key] = [true, true, result, false, Date.now()]; | ||
} | ||
return result; | ||
}) | ||
.then(resp => { | ||
delete cache.actions[key]; | ||
if (!onServer) { | ||
notifyListeners(key); | ||
} | ||
return resp; | ||
}); | ||
} | ||
function checkKeyAndReturnResponse(key, cache, initiate, ssr, args, stores, fromListener = false, postActionEnabled = true, cacheBreakEnabled = true, holdingResult = undefined) { | ||
const cached = getCachedResult(key, cache, args, stores, initiate ? EPostActionContext.BECKON_HIT_CACHE : EPostActionContext.WATCH_HIT_CACHE, postActionEnabled, cacheBreakEnabled, fromListener); | ||
if (cached) { | ||
return cached; | ||
} | ||
if (!cache.actions.hasOwnProperty(key)) { | ||
@@ -474,28 +528,3 @@ const currentActionOrd = actionOrdUpdate(cache, key); | ||
if (ssr || !onServer) { | ||
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, Date.now()]; | ||
} | ||
}) | ||
.catch(e => { | ||
console.error(e); | ||
if (currentActionOrd === cache.actionOrd[key]) { | ||
const result = { | ||
payload: null, | ||
error: true, | ||
tags: [EAsyncEndTags.THREW_ERROR], | ||
message: e.message, | ||
}; | ||
runPostActionHook(result, args, stores, EPostActionContext.BECKON_RUN); | ||
cache.results[key] = [true, true, result, false, Date.now()]; | ||
} | ||
}) | ||
.then(() => { | ||
delete cache.actions[key]; | ||
if (!onServer) { | ||
notifyListeners(key); | ||
} | ||
}); | ||
cache.actions[key] = createInternalAction(key, cache, args, stores, currentActionOrd, postActionEnabled, EPostActionContext.BECKON_RUN); | ||
} | ||
@@ -544,2 +573,44 @@ if (!onServer) { | ||
} | ||
const read = (args = {}, { cacheBreakEnabled = true, postActionEnabled = true } = {}) => { | ||
const key = _createKey(ordinal, args); | ||
const cache = onServer ? useContext(PullstateContext)._asyncCache : clientAsyncCache; | ||
const stores = onServer || forceContext ? useContext(PullstateContext).stores : clientStores; | ||
const cached = getCachedResult(key, cache, args, stores, EPostActionContext.READ_HIT_CACHE, postActionEnabled, cacheBreakEnabled, false); | ||
if (cached) { | ||
if (!cached[2].error) { | ||
return cached[2].payload; | ||
} | ||
else { | ||
throw new PullstateAsyncError(cached[2].message, cached[2].tags); | ||
} | ||
} | ||
if (!cache.actions.hasOwnProperty(key)) { | ||
if (shortCircuitHook !== undefined) { | ||
const shortCircuitResponse = shortCircuitHook({ args, stores }); | ||
if (shortCircuitResponse !== false) { | ||
runPostActionHook(shortCircuitResponse, args, stores, EPostActionContext.SHORT_CIRCUIT); | ||
cache.results[key] = [true, true, shortCircuitResponse, false, Date.now()]; | ||
if (!shortCircuitResponse.error) { | ||
return shortCircuitResponse.payload; | ||
} | ||
else { | ||
throw new PullstateAsyncError(shortCircuitResponse.message, shortCircuitResponse.tags); | ||
} | ||
} | ||
} | ||
const currentActionOrd = actionOrdUpdate(cache, key); | ||
cache.actions[key] = createInternalAction(key, cache, args, stores, currentActionOrd, postActionEnabled, EPostActionContext.READ_RUN); | ||
if (onServer) { | ||
throw new Error(`Pullstate Async Action: action.read() : Resolve all async state for Suspense actions before Server-side render ( make use of instance.runAsyncAction() )`); | ||
} | ||
throw cache.actions[key](); | ||
} | ||
if (onServer) { | ||
throw new Error(`Pullstate Async Action: action.read() : Resolve all async state for Suspense actions before Server-side render ( make use of instance.runAsyncAction() )`); | ||
} | ||
const watchOrd = watchIdOrd++; | ||
throw new Promise(resolve => { | ||
cache.listeners[key][watchOrd] = resolve; | ||
}); | ||
}; | ||
const useWatch = (args = {}, { initiate = false, ssr = true, postActionEnabled = false, cacheBreakEnabled = false, holdPrevious = false, dormant = false, } = {}) => { | ||
@@ -623,21 +694,7 @@ const responseRef = useRef(); | ||
const key = _createKey(ordinal, args); | ||
if (_asyncCache.results.hasOwnProperty(key) && respectCache) { | ||
if (cacheBreakHook !== undefined && | ||
cacheBreakHook({ | ||
args, | ||
result: _asyncCache.results[key][2], | ||
stores: _stores, | ||
timeCached: _asyncCache.results[key][4], | ||
})) { | ||
delete _asyncCache.results[key]; | ||
if (respectCache) { | ||
const cached = getCachedResult(key, _asyncCache, args, _stores, EPostActionContext.RUN_HIT_CACHE, true, true, false); | ||
if (cached) { | ||
return cached[2]; | ||
} | ||
else { | ||
if (_asyncCache.results[key][1]) { | ||
runPostActionHook(_asyncCache.results[key][2], args, _stores, EPostActionContext.RUN_HIT_CACHE); | ||
return _asyncCache.results[key][2]; | ||
} | ||
else { | ||
return _asyncCache.results[key][2]; | ||
} | ||
} | ||
} | ||
@@ -684,26 +741,4 @@ if (!ignoreShortCircuit && shortCircuitHook !== undefined) { | ||
let currentActionOrd = actionOrdUpdate(_asyncCache, key); | ||
try { | ||
const result = await action(args, _stores); | ||
if (currentActionOrd === _asyncCache.actionOrd[key]) { | ||
_asyncCache.results[key] = [true, true, result, false, Date.now()]; | ||
runPostActionHook(result, args, _stores, EPostActionContext.DIRECT_RUN); | ||
notifyListeners(key); | ||
} | ||
return result; | ||
} | ||
catch (e) { | ||
console.error(e); | ||
const result = { | ||
error: true, | ||
message: e.message, | ||
tags: [EAsyncEndTags.THREW_ERROR], | ||
payload: null, | ||
}; | ||
if (currentActionOrd === _asyncCache.actionOrd[key]) { | ||
_asyncCache.results[key] = [true, true, result, false, Date.now()]; | ||
runPostActionHook(result, args, _stores, EPostActionContext.DIRECT_RUN); | ||
notifyListeners(key); | ||
} | ||
return result; | ||
} | ||
_asyncCache.actions[key] = createInternalAction(key, _asyncCache, args, _stores, currentActionOrd, true, EPostActionContext.DIRECT_RUN); | ||
return _asyncCache.actions[key](); | ||
}; | ||
@@ -832,2 +867,3 @@ const clearCache = (args = {}) => { | ||
return { | ||
read, | ||
useBeckon, | ||
@@ -834,0 +870,0 @@ useWatch, |
'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"); | ||
function useStoreState(store, getSubState) { | ||
function useStoreState(store, getSubState, deps) { | ||
const [subState, setSubState] = React.useState(() => getSubState ? getSubState(store.getRawState()) : store.getRawState()); | ||
@@ -25,3 +25,10 @@ const updateRef = React.useRef({ | ||
}, []); | ||
return subState; | ||
if (deps !== undefined) { | ||
const prevDeps = React.useRef(deps); | ||
if (!isEqual(deps, prevDeps)) { | ||
updateRef.current.getSubState = getSubState; | ||
updateRef.current.currentSubState = getSubState(store.getRawState()); | ||
} | ||
} | ||
return updateRef.current.currentSubState; | ||
}let updateListenerOrd = 0; | ||
@@ -232,4 +239,4 @@ function fastGet(obj, path) { | ||
} | ||
useState(getSubState) { | ||
return useStoreState(this, getSubState); | ||
useState(getSubState, deps) { | ||
return useStoreState(this, getSubState, deps); | ||
} | ||
@@ -327,2 +334,4 @@ update(updater, patchesCallback) { | ||
EPostActionContext["RUN_HIT_CACHE"] = "RUN_HIT_CACHE"; | ||
EPostActionContext["READ_HIT_CACHE"] = "READ_HIT_CACHE"; | ||
EPostActionContext["READ_RUN"] = "READ_RUN"; | ||
EPostActionContext["SHORT_CIRCUIT"] = "SHORT_CIRCUIT"; | ||
@@ -340,25 +349,22 @@ EPostActionContext["DIRECT_RUN"] = "DIRECT_RUN"; | ||
function keyFromObject(json) { | ||
if (json == null) { | ||
return `${json}`; | ||
if (json === null) { | ||
return "(n)"; | ||
} | ||
if (typeof json !== "object") { | ||
return `${json}`; | ||
} | ||
let prefix = "{"; | ||
for (const key of Object.keys(json).sort()) { | ||
prefix += key; | ||
if (typeof json[key] == null) { | ||
prefix += JSON.stringify(json[key]); | ||
const typeOf = typeof json; | ||
if (typeOf !== "object") { | ||
if (typeOf === "undefined") { | ||
return "(u)"; | ||
} | ||
else if (typeof json[key] === "string") { | ||
prefix += `~${json[key]}~`; | ||
else if (typeOf === "string") { | ||
return ":" + json + ";"; | ||
} | ||
else if (typeof json[key] === "boolean" || typeof json[key] === "number") { | ||
prefix += json[key]; | ||
else if (typeOf === "boolean" || typeOf === "number") { | ||
return "(" + json + ")"; | ||
} | ||
else { | ||
prefix += `{${keyFromObject(json[key])}}`; | ||
} | ||
} | ||
return (prefix += "}"); | ||
let prefix = "{"; | ||
for (const key of Object.keys(json).sort()) { | ||
prefix += key + keyFromObject(json[key]); | ||
} | ||
return prefix + "}"; | ||
} | ||
@@ -404,2 +410,8 @@ function notifyListeners(key) { | ||
} | ||
class PullstateAsyncError extends Error { | ||
constructor(message, tags) { | ||
super(message); | ||
this.tags = tags; | ||
} | ||
} | ||
function createAsyncAction(action, { forceContext = false, clientStores = {}, shortCircuitHook, cacheBreakHook, postActionHook, subsetKey, } = {}) { | ||
@@ -422,3 +434,3 @@ const ordinal = asyncCreationOrdinal++; | ||
} | ||
function checkKeyAndReturnResponse(key, cache, initiate, ssr, args, stores, fromListener = false, postActionEnabled = true, cacheBreakEnabled = true, holdingResult = undefined) { | ||
function getCachedResult(key, cache, args, stores, context, postActionEnabled, cacheBreakEnabled, fromListener) { | ||
if (cache.results.hasOwnProperty(key)) { | ||
@@ -454,3 +466,3 @@ const cacheBreakLoop = cacheBreakWatcher.hasOwnProperty(key) && cacheBreakWatcher[key] > 2; | ||
if (postActionEnabled && cache.results[key][1] && !fromListener) { | ||
runPostActionHook(cache.results[key][2], args, stores, initiate ? EPostActionContext.BECKON_HIT_CACHE : EPostActionContext.WATCH_HIT_CACHE); | ||
runPostActionHook(cache.results[key][2], args, stores, context); | ||
} | ||
@@ -460,2 +472,44 @@ return cache.results[key]; | ||
} | ||
return undefined; | ||
} | ||
function createInternalAction(key, cache, args, stores, currentActionOrd, postActionEnabled, context) { | ||
return () => action(args, stores) | ||
.then(resp => { | ||
if (currentActionOrd === cache.actionOrd[key]) { | ||
if (postActionEnabled) { | ||
runPostActionHook(resp, args, stores, context); | ||
} | ||
cache.results[key] = [true, true, resp, false, Date.now()]; | ||
} | ||
return resp; | ||
}) | ||
.catch(e => { | ||
console.error(e); | ||
const result = { | ||
payload: null, | ||
error: true, | ||
tags: [exports.EAsyncEndTags.THREW_ERROR], | ||
message: e.message, | ||
}; | ||
if (currentActionOrd === cache.actionOrd[key]) { | ||
if (postActionEnabled) { | ||
runPostActionHook(result, args, stores, context); | ||
} | ||
cache.results[key] = [true, true, result, false, Date.now()]; | ||
} | ||
return result; | ||
}) | ||
.then(resp => { | ||
delete cache.actions[key]; | ||
if (!onServer) { | ||
notifyListeners(key); | ||
} | ||
return resp; | ||
}); | ||
} | ||
function checkKeyAndReturnResponse(key, cache, initiate, ssr, args, stores, fromListener = false, postActionEnabled = true, cacheBreakEnabled = true, holdingResult = undefined) { | ||
const cached = getCachedResult(key, cache, args, stores, initiate ? EPostActionContext.BECKON_HIT_CACHE : EPostActionContext.WATCH_HIT_CACHE, postActionEnabled, cacheBreakEnabled, fromListener); | ||
if (cached) { | ||
return cached; | ||
} | ||
if (!cache.actions.hasOwnProperty(key)) { | ||
@@ -473,28 +527,3 @@ const currentActionOrd = actionOrdUpdate(cache, key); | ||
if (ssr || !onServer) { | ||
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, Date.now()]; | ||
} | ||
}) | ||
.catch(e => { | ||
console.error(e); | ||
if (currentActionOrd === cache.actionOrd[key]) { | ||
const result = { | ||
payload: null, | ||
error: true, | ||
tags: [exports.EAsyncEndTags.THREW_ERROR], | ||
message: e.message, | ||
}; | ||
runPostActionHook(result, args, stores, EPostActionContext.BECKON_RUN); | ||
cache.results[key] = [true, true, result, false, Date.now()]; | ||
} | ||
}) | ||
.then(() => { | ||
delete cache.actions[key]; | ||
if (!onServer) { | ||
notifyListeners(key); | ||
} | ||
}); | ||
cache.actions[key] = createInternalAction(key, cache, args, stores, currentActionOrd, postActionEnabled, EPostActionContext.BECKON_RUN); | ||
} | ||
@@ -543,2 +572,44 @@ if (!onServer) { | ||
} | ||
const read = (args = {}, { cacheBreakEnabled = true, postActionEnabled = true } = {}) => { | ||
const key = _createKey(ordinal, args); | ||
const cache = onServer ? React.useContext(PullstateContext)._asyncCache : clientAsyncCache; | ||
const stores = onServer || forceContext ? React.useContext(PullstateContext).stores : clientStores; | ||
const cached = getCachedResult(key, cache, args, stores, EPostActionContext.READ_HIT_CACHE, postActionEnabled, cacheBreakEnabled, false); | ||
if (cached) { | ||
if (!cached[2].error) { | ||
return cached[2].payload; | ||
} | ||
else { | ||
throw new PullstateAsyncError(cached[2].message, cached[2].tags); | ||
} | ||
} | ||
if (!cache.actions.hasOwnProperty(key)) { | ||
if (shortCircuitHook !== undefined) { | ||
const shortCircuitResponse = shortCircuitHook({ args, stores }); | ||
if (shortCircuitResponse !== false) { | ||
runPostActionHook(shortCircuitResponse, args, stores, EPostActionContext.SHORT_CIRCUIT); | ||
cache.results[key] = [true, true, shortCircuitResponse, false, Date.now()]; | ||
if (!shortCircuitResponse.error) { | ||
return shortCircuitResponse.payload; | ||
} | ||
else { | ||
throw new PullstateAsyncError(shortCircuitResponse.message, shortCircuitResponse.tags); | ||
} | ||
} | ||
} | ||
const currentActionOrd = actionOrdUpdate(cache, key); | ||
cache.actions[key] = createInternalAction(key, cache, args, stores, currentActionOrd, postActionEnabled, EPostActionContext.READ_RUN); | ||
if (onServer) { | ||
throw new Error(`Pullstate Async Action: action.read() : Resolve all async state for Suspense actions before Server-side render ( make use of instance.runAsyncAction() )`); | ||
} | ||
throw cache.actions[key](); | ||
} | ||
if (onServer) { | ||
throw new Error(`Pullstate Async Action: action.read() : Resolve all async state for Suspense actions before Server-side render ( make use of instance.runAsyncAction() )`); | ||
} | ||
const watchOrd = watchIdOrd++; | ||
throw new Promise(resolve => { | ||
cache.listeners[key][watchOrd] = resolve; | ||
}); | ||
}; | ||
const useWatch = (args = {}, { initiate = false, ssr = true, postActionEnabled = false, cacheBreakEnabled = false, holdPrevious = false, dormant = false, } = {}) => { | ||
@@ -622,21 +693,7 @@ const responseRef = React.useRef(); | ||
const key = _createKey(ordinal, args); | ||
if (_asyncCache.results.hasOwnProperty(key) && respectCache) { | ||
if (cacheBreakHook !== undefined && | ||
cacheBreakHook({ | ||
args, | ||
result: _asyncCache.results[key][2], | ||
stores: _stores, | ||
timeCached: _asyncCache.results[key][4], | ||
})) { | ||
delete _asyncCache.results[key]; | ||
if (respectCache) { | ||
const cached = getCachedResult(key, _asyncCache, args, _stores, EPostActionContext.RUN_HIT_CACHE, true, true, false); | ||
if (cached) { | ||
return cached[2]; | ||
} | ||
else { | ||
if (_asyncCache.results[key][1]) { | ||
runPostActionHook(_asyncCache.results[key][2], args, _stores, EPostActionContext.RUN_HIT_CACHE); | ||
return _asyncCache.results[key][2]; | ||
} | ||
else { | ||
return _asyncCache.results[key][2]; | ||
} | ||
} | ||
} | ||
@@ -683,26 +740,4 @@ if (!ignoreShortCircuit && shortCircuitHook !== undefined) { | ||
let currentActionOrd = actionOrdUpdate(_asyncCache, key); | ||
try { | ||
const result = await action(args, _stores); | ||
if (currentActionOrd === _asyncCache.actionOrd[key]) { | ||
_asyncCache.results[key] = [true, true, result, false, Date.now()]; | ||
runPostActionHook(result, args, _stores, EPostActionContext.DIRECT_RUN); | ||
notifyListeners(key); | ||
} | ||
return result; | ||
} | ||
catch (e) { | ||
console.error(e); | ||
const result = { | ||
error: true, | ||
message: e.message, | ||
tags: [exports.EAsyncEndTags.THREW_ERROR], | ||
payload: null, | ||
}; | ||
if (currentActionOrd === _asyncCache.actionOrd[key]) { | ||
_asyncCache.results[key] = [true, true, result, false, Date.now()]; | ||
runPostActionHook(result, args, _stores, EPostActionContext.DIRECT_RUN); | ||
notifyListeners(key); | ||
} | ||
return result; | ||
} | ||
_asyncCache.actions[key] = createInternalAction(key, _asyncCache, args, _stores, currentActionOrd, true, EPostActionContext.DIRECT_RUN); | ||
return _asyncCache.actions[key](); | ||
}; | ||
@@ -831,2 +866,3 @@ const clearCache = (args = {}) => { | ||
return { | ||
read, | ||
useBeckon, | ||
@@ -833,0 +869,0 @@ useWatch, |
@@ -41,3 +41,3 @@ import { Patch, PatchListener } from "immer"; | ||
useState(): S; | ||
useState<SS = any>(getSubState: (state: S) => SS): SS; | ||
useState<SS = any>(getSubState: (state: S) => SS, deps?: ReadonlyArray<any>): SS; | ||
update(updater: TUpdateFunction<S> | TUpdateFunction<S>[], patchesCallback?: (patches: Patch[], inversePatches: Patch[]) => void): void; | ||
@@ -44,0 +44,0 @@ applyPatches(patches: Patch[]): void; |
@@ -9,3 +9,3 @@ import { Store } from "./Store"; | ||
declare function useStoreState<S = any>(store: Store<S>): S; | ||
declare function useStoreState<S = any, SS = any>(store: Store<S>, getSubState: (state: S) => SS): SS; | ||
declare function useStoreState<S = any, SS = any>(store: Store<S>, getSubState: (state: S) => SS, deps?: ReadonlyArray<any>): SS; | ||
export { useStoreState }; |
{ | ||
"name": "pullstate", | ||
"version": "1.8.0", | ||
"version": "1.9.0", | ||
"description": "Simple state stores using immer and React hooks", | ||
@@ -44,4 +44,4 @@ "main": "dist/index.js", | ||
"@types/lodash": "^4.14.121", | ||
"@types/react": "^16.8.4", | ||
"@types/react-dom": "^16.8.2", | ||
"@types/react": "^16.9.17", | ||
"@types/react-dom": "^16.9.4", | ||
"benchmark": "^2.1.4", | ||
@@ -71,4 +71,4 @@ "cross-env": "^5.2.0", | ||
"immer": "^3.2.0", | ||
"react": "^16.8.2" | ||
"react": "^16.12.0" | ||
} | ||
} |
123674
18
2356