observable-slice
Advanced tools
Comparing version 0.0.14 to 0.0.15
@@ -8,3 +8,3 @@ /** | ||
willNotify?: ((prev: any, next: any) => boolean) | undefined; | ||
}>>({ initState, pubs, useSubs, notifyMiddleware, onPub, }: { | ||
}>>({ initState, pubs, useSubs, notifyMiddleware, logger, }: { | ||
/** | ||
@@ -33,6 +33,5 @@ * The uncontrolled initial state of the slice. | ||
/** | ||
* Will be called with the new state each time an action is dispatched. | ||
* This is useful for logging or persistance. | ||
* Add additionally functionality to the slice before it handles each event. For example a logger. | ||
*/ | ||
onPub?: ((state: State) => void) | undefined; | ||
logger?: ((name: 'get' | 'notify-subs' | 'add-sub' | 'rm-sub' | 'notify-sub', state: State) => unknown) | undefined; | ||
}) => { | ||
@@ -39,0 +38,0 @@ /** |
@@ -1,1 +0,1 @@ | ||
function e(e){if(e&&e.__esModule)return e;var n=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var r=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,r.get?r:{enumerable:!0,get:function(){return e[t]}})}}),n.default=e,n}var n=/*#__PURE__*/e(require("react"));exports.create=function(e){var t=e.pubs,r=e.useSubs,u=e.notifyMiddleware,c=e.onPub,f=e.initState,o=new Set,i=function(){return o.forEach(function(e){return e()})},a=u?u(i):i,b={get:function(){return f},pub:function(e){f=e(f),a(),null==c||c(f)},sub:function(e,n,t){var r=e(f),u=function(){var u=e(f);(t?t(r,u):r!==u)&&(n(u),r=u)};return o.add(u),function(){o.delete(u)}},useSub:function(e,t){var r=n.useState(function(){return e(f)}),u=r[0],c=r[1];return n.useEffect(function(){var n=function(){return c(function(n){var r=e(f);return(t?t(n,r):n!==r)?r:n})};return o.add(n),function(){o.delete(n)}},[]),u}};return t&&Object.keys(t).forEach(function(e){b[e]=function(n){return b.pub(function(r){return t[e](r,n)})}}),r&&Object.keys(r).forEach(function(e){b[e]=function(n){var t=r[e](n);return b.useSub(t.select,t.willNotify)}}),b}; | ||
function t(t){if(t&&t.__esModule)return t;var n=Object.create(null);return t&&Object.keys(t).forEach(function(e){if("default"!==e){var u=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(n,e,u.get?u:{enumerable:!0,get:function(){return t[e]}})}}),n.default=t,n}var n=/*#__PURE__*/t(require("react"));exports.create=function(t){var e=t.pubs,u=t.useSubs,r=t.notifyMiddleware,c=t.logger,f=t.initState,o=new Set,i=function(){return o.forEach(function(t){return t()})},a=r?r(i):i,s=c||function(){},b={get:function(){return s("get",f),f},pub:function(t){f=t(f),s("notify-subs",f),a()},sub:function(t,n,e){var u=t(f),r=function(){var r=t(f);(e?e(u,r):u!==r)&&(s("notify-sub",f),n(r),u=r)};return s("add-sub",f),o.add(r),function(){s("rm-sub",f),o.delete(r)}},useSub:function(t,e){var u=n.useState(function(){return t(f)}),r=u[0],c=u[1];return n.useEffect(function(){var n=function(){return c(function(n){var u=t(f);return(e?e(n,u):n!==u)?(s("notify-sub",f),u):n})};return s("add-sub",f),o.add(n),function(){s("rm-sub",f),o.delete(n)}},[]),r}};return e&&Object.keys(e).forEach(function(t){b[t]=function(n){return b.pub(function(u){return e[t](u,n)})}}),u&&Object.keys(u).forEach(function(t){b[t]=function(n){var e=u[t](n);return b.useSub(e.select,e.willNotify)}}),b}; |
@@ -1,1 +0,1 @@ | ||
import*as n from"react";var t=function(t){var u=t.pubs,r=t.useSubs,e=t.notifyMiddleware,o=t.onPub,c=t.initState,f=new Set,i=function(){return f.forEach(function(n){return n()})},a=e?e(i):i,s={get:function(){return c},pub:function(n){c=n(c),a(),null==o||o(c)},sub:function(n,t,u){var r=n(c),e=function(){var e=n(c);(u?u(r,e):r!==e)&&(t(e),r=e)};return f.add(e),function(){f.delete(e)}},useSub:function(t,u){var r=n.useState(function(){return t(c)}),e=r[0],o=r[1];return n.useEffect(function(){var n=function(){return o(function(n){var r=t(c);return(u?u(n,r):n!==r)?r:n})};return f.add(n),function(){f.delete(n)}},[]),e}};return u&&Object.keys(u).forEach(function(n){s[n]=function(t){return s.pub(function(r){return u[n](r,t)})}}),r&&Object.keys(r).forEach(function(n){s[n]=function(t){var u=r[n](t);return s.useSub(u.select,u.willNotify)}}),s};export{t as create}; | ||
import*as n from"react";var t=function(t){var u=t.pubs,r=t.useSubs,e=t.notifyMiddleware,o=t.logger,f=t.initState,i=new Set,c=function(){return i.forEach(function(n){return n()})},a=e?e(c):c,s=o||function(){},b={get:function(){return s("get",f),f},pub:function(n){f=n(f),s("notify-subs",f),a()},sub:function(n,t,u){var r=n(f),e=function(){var e=n(f);(u?u(r,e):r!==e)&&(s("notify-sub",f),t(e),r=e)};return s("add-sub",f),i.add(e),function(){s("rm-sub",f),i.delete(e)}},useSub:function(t,u){var r=n.useState(function(){return t(f)}),e=r[0],o=r[1];return n.useEffect(function(){var n=function(){return o(function(n){var r=t(f);return(u?u(n,r):n!==r)?(s("notify-sub",f),r):n})};return s("add-sub",f),i.add(n),function(){s("rm-sub",f),i.delete(n)}},[]),e}};return u&&Object.keys(u).forEach(function(n){b[n]=function(t){return b.pub(function(r){return u[n](r,t)})}}),r&&Object.keys(r).forEach(function(n){b[n]=function(t){var u=r[n](t);return b.useSub(u.select,u.willNotify)}}),b};export{t as create}; |
@@ -1,1 +0,1 @@ | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],n):n((e||self).observableSlice={},e.react)}(this,function(e,n){function t(e){if(e&&e.__esModule)return e;var n=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var r=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,r.get?r:{enumerable:!0,get:function(){return e[t]}})}}),n.default=e,n}var r=/*#__PURE__*/t(n);e.create=function(e){var n=e.pubs,t=e.useSubs,u=e.notifyMiddleware,f=e.onPub,o=e.initState,c=new Set,i=function(){return c.forEach(function(e){return e()})},a=u?u(i):i,l={get:function(){return o},pub:function(e){o=e(o),a(),null==f||f(o)},sub:function(e,n,t){var r=e(o),u=function(){var u=e(o);(t?t(r,u):r!==u)&&(n(u),r=u)};return c.add(u),function(){c.delete(u)}},useSub:function(e,n){var t=r.useState(function(){return e(o)}),u=t[0],f=t[1];return r.useEffect(function(){var t=function(){return f(function(t){var r=e(o);return(n?n(t,r):t!==r)?r:t})};return c.add(t),function(){c.delete(t)}},[]),u}};return n&&Object.keys(n).forEach(function(e){l[e]=function(t){return l.pub(function(r){return n[e](r,t)})}}),t&&Object.keys(t).forEach(function(e){l[e]=function(n){var r=t[e](n);return l.useSub(r.select,r.willNotify)}}),l}}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e||self).observableSlice={},e.react)}(this,function(e,t){function n(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var u=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,u.get?u:{enumerable:!0,get:function(){return e[n]}})}}),t.default=e,t}var u=/*#__PURE__*/n(t);e.create=function(e){var t=e.pubs,n=e.useSubs,r=e.notifyMiddleware,f=e.logger,o=e.initState,i=new Set,c=function(){return i.forEach(function(e){return e()})},a=r?r(c):c,s=f||function(){},b={get:function(){return s("get",o),o},pub:function(e){o=e(o),s("notify-subs",o),a()},sub:function(e,t,n){var u=e(o),r=function(){var r=e(o);(n?n(u,r):u!==r)&&(s("notify-sub",o),t(r),u=r)};return s("add-sub",o),i.add(r),function(){s("rm-sub",o),i.delete(r)}},useSub:function(e,t){var n=u.useState(function(){return e(o)}),r=n[0],f=n[1];return u.useEffect(function(){var n=function(){return f(function(n){var u=e(o);return(t?t(n,u):n!==u)?(s("notify-sub",o),u):n})};return s("add-sub",o),i.add(n),function(){s("rm-sub",o),i.delete(n)}},[]),r}};return t&&Object.keys(t).forEach(function(e){b[e]=function(n){return b.pub(function(u){return t[e](u,n)})}}),n&&Object.keys(n).forEach(function(e){b[e]=function(t){var u=n[e](t);return b.useSub(u.select,u.willNotify)}}),b}}); |
{ | ||
"name": "observable-slice", | ||
"version": "0.0.14", | ||
"version": "0.0.15", | ||
"description": "An observable for global state that can be subscribed to with react hooks, or callbacks", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -109,2 +109,3 @@ [![license-shield]][license-url] [![linkedin-shield]][linkedin-url] ![size-url] ![size-url2] [![npm-v]][npm-url] [![gh-shield]][gh-url] | ||
| $useSub | fn | | Each entry defined in create.subs will create a react hook that may be consumed to subscribe to the slice. These hooks may also accept one parameter. For example, the useTodo subscription may accept the id of the todo to subscribe to. | | ||
| logger | fn | | Add additionally functionality to the slice before it handles each eventFor example a logger, or a persister. | | ||
## Roadmap | ||
@@ -111,0 +112,0 @@ |
@@ -312,15 +312,25 @@ import { act, renderHook } from '@testing-library/react'; | ||
}); | ||
it('runs side effects after actions are dispatched', () => { | ||
const onPub = jest.fn(); | ||
it('runs side effects before internal events are handled', () => { | ||
const logger = jest.fn(); | ||
const slice = create({ | ||
initState: 0, | ||
onPub | ||
}) | ||
logger, | ||
}); | ||
slice.pub(() => 1) | ||
slice.get(); | ||
expect(logger).toHaveBeenCalledWith('get', 0); | ||
expect(onPub).toHaveBeenCalledTimes(1) | ||
expect(onPub).toHaveBeenCalledWith(1) | ||
expect(slice.get()).toBe(1) | ||
}) | ||
const rm = slice.sub( | ||
s => s, | ||
() => {} | ||
); | ||
expect(logger).toHaveBeenCalledWith('add-sub', 0); | ||
slice.pub(() => 1); | ||
expect(logger).toHaveBeenCalledWith('notify-subs', 1); | ||
expect(logger).toHaveBeenCalledWith('notify-sub', 1); | ||
rm(); | ||
expect(logger).toHaveBeenCalledWith('rm-sub', 1); | ||
}); | ||
}); |
@@ -24,3 +24,3 @@ import * as React from 'react'; | ||
notifyMiddleware, | ||
onPub, | ||
logger, | ||
}: { | ||
@@ -50,6 +50,8 @@ /** | ||
/** | ||
* Will be called with the new state each time an action is dispatched. | ||
* This is useful for logging or persistance. | ||
* Add additionally functionality to the slice before it handles each event. For example a logger. | ||
*/ | ||
onPub?: (state: State) => void; | ||
logger?: ( | ||
name: 'get' | 'notify-subs' | 'add-sub' | 'rm-sub' | 'notify-sub', | ||
state: State | ||
) => unknown; | ||
}) => { | ||
@@ -60,9 +62,13 @@ let state = initState; | ||
const notify = notifyMiddleware ? notifyMiddleware(_notify) : _notify; | ||
const log = logger ? logger : () => {}; | ||
const res: any = { | ||
get: () => state, | ||
get: () => { | ||
log('get', state); | ||
return state; | ||
}, | ||
pub: (replace: (state: State) => State) => { | ||
state = replace(state); | ||
log('notify-subs', state); | ||
notify(); | ||
onPub?.(state) | ||
}, | ||
@@ -79,2 +85,3 @@ sub: <T>( | ||
if (update) { | ||
log('notify-sub', state); | ||
cb(next); | ||
@@ -85,5 +92,7 @@ prev = next; | ||
log('add-sub', state); | ||
subscribers.add(sub); | ||
return () => { | ||
log('rm-sub', state); | ||
subscribers.delete(sub); | ||
@@ -102,8 +111,14 @@ }; | ||
const update = willNotify ? willNotify(prev, next) : prev !== next; | ||
return update ? next : prev; | ||
if (update) { | ||
log('notify-sub', state); | ||
return next; | ||
} | ||
return prev; | ||
}); | ||
log('add-sub', state); | ||
subscribers.add(sub); | ||
return () => { | ||
log('rm-sub', state); | ||
subscribers.delete(sub); | ||
@@ -110,0 +125,0 @@ }; |
Sorry, the diff of this file is not supported yet
29030
550
121