statedrive 0.0.14 → 0.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -8
- package/dist/_hook_factory.d.ts +12 -0
- package/dist/hooks.d.ts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/react/src/hooks.d.ts +12 -0
- package/dist/react/src/index.d.ts +4 -0
- package/dist/react.modern.js +2 -0
- package/dist/react.modern.js.map +1 -0
- package/dist/src/_hook_factory.d.ts +12 -0
- package/dist/src/state.d.ts +4 -0
- package/dist/src/subscribe.d.ts +8 -0
- package/dist/src/types.d.ts +18 -0
- package/dist/src/util.d.ts +2 -0
- package/dist/state.d.ts +4 -0
- package/dist/statedrive.modern.js +2 -0
- package/dist/statedrive.modern.js.map +1 -0
- package/dist/subscribe.d.ts +8 -0
- package/dist/types.d.ts +18 -0
- package/dist/util.d.ts +2 -0
- package/package.json +3 -3
- package/react/src/hooks.ts +22 -18
- package/src/_hook_factory.ts +6 -5
package/README.md
CHANGED
|
@@ -15,13 +15,15 @@ Each state is a unique atom to which you can attach event listeners and run stat
|
|
|
15
15
|
## For [ui-lib](https://github.com/hydrophobefireman/ui-lib)
|
|
16
16
|
|
|
17
17
|
```js
|
|
18
|
-
import {
|
|
18
|
+
import {createState} from "statedrive";
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
## For react
|
|
22
22
|
|
|
23
23
|
```js
|
|
24
|
-
import {createState} from "statedrive
|
|
24
|
+
import {createState} from "statedrive";
|
|
25
|
+
import {buildReactStatedrive} from "statedrive/react";
|
|
26
|
+
const {} = buildReactStateDrive(react);
|
|
25
27
|
```
|
|
26
28
|
|
|
27
29
|
everything else is the same.
|
|
@@ -31,14 +33,14 @@ everything else is the same.
|
|
|
31
33
|
1. Create a state atom
|
|
32
34
|
state.js
|
|
33
35
|
```js
|
|
34
|
-
import {
|
|
35
|
-
export const userNameAtom = createState({
|
|
36
|
+
import {createState} from "statedrive";
|
|
37
|
+
export const userNameAtom = createState({initialValue: "Foo"});
|
|
36
38
|
```
|
|
37
39
|
2. Use it within a react/ui-lib component
|
|
38
40
|
some-component.js
|
|
39
41
|
```ts
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
+
import {useSharedState} from "statedrive";
|
|
43
|
+
import {userNameAtom} from "./state.js";
|
|
42
44
|
export function ComponentA() {
|
|
43
45
|
const [name, setName] = useSharedState(userNameAtom);
|
|
44
46
|
return <input value={name} onChange={(e) => setName(e.target.value)} />;
|
|
@@ -51,8 +53,8 @@ everything else is the same.
|
|
|
51
53
|
3. Use it within your app elsewhere (any place where hooks don't work)
|
|
52
54
|
util.js
|
|
53
55
|
```js
|
|
54
|
-
import {
|
|
55
|
-
import {
|
|
56
|
+
import {get, set} from "statedrive";
|
|
57
|
+
import {userNameAtom} from "./state.js";
|
|
56
58
|
function updateName(newValue) {
|
|
57
59
|
setUserNameAtom, newValue;
|
|
58
60
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { useCallback as UseCallbackType, useEffect as UseEffectType, useMemo as UseMemoType, useState as UseStateType } from "@hydrophobefireman/ui-lib";
|
|
2
|
+
import { SelectorOptions, SetSharedState, State } from "./types";
|
|
3
|
+
export declare namespace Hooks {
|
|
4
|
+
type useEffect = typeof UseEffectType;
|
|
5
|
+
type useState = typeof UseStateType;
|
|
6
|
+
type useCallback = typeof UseCallbackType;
|
|
7
|
+
type useMemo = typeof UseMemoType;
|
|
8
|
+
}
|
|
9
|
+
export declare function createUseSharedState(useEffect: Hooks.useEffect, useState: Hooks.useState): <T>(state: State<T>) => [T, SetSharedState<T>];
|
|
10
|
+
export declare function createUseSelector(useEffect: Hooks.useEffect, useState: Hooks.useState, useMemo: Hooks.useMemo, useCallback: Hooks.useCallback): <R>(func: (options: SelectorOptions<R>) => R) => R;
|
|
11
|
+
export declare function createUseSharedStateValue(useSharedState: ReturnType<typeof createUseSharedState>): <T>(s: State<T>) => T;
|
|
12
|
+
export declare function createUseSetSharedState(useSharedState: ReturnType<typeof createUseSharedState>): <T>(s: State<T>) => SetSharedState<T>;
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const useSharedState: <T>(state: import("./types").State<T>) => [T, import("./types").SetSharedState<T>];
|
|
2
|
+
export declare const useSelector: <R>(func: (options: import("./types").SelectorOptions<R>) => R) => R;
|
|
3
|
+
export declare const useSharedStateValue: <T>(s: import("./types").State<T>) => T;
|
|
4
|
+
export declare const useSetSharedState: <T>(s: import("./types").State<T>) => import("./types").SetSharedState<T>;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as factory from "../../src/_hook_factory";
|
|
2
|
+
export declare function buildReactStatedrive(data: {
|
|
3
|
+
useEffect: factory.Hooks.useEffect;
|
|
4
|
+
useState: factory.Hooks.useState;
|
|
5
|
+
useMemo: factory.Hooks.useMemo;
|
|
6
|
+
useCallback: factory.Hooks.useCallback;
|
|
7
|
+
}): {
|
|
8
|
+
useSharedState: <T>(state: import(".").State<T>) => [T, import(".").SetSharedState<T>];
|
|
9
|
+
useSelector: <R>(func: (options: import(".").SelectorOptions<R>) => R) => R;
|
|
10
|
+
useSharedStateValue: <T_1>(s: import(".").State<T_1>) => T_1;
|
|
11
|
+
useSetSharedState: <T_2>(s: import(".").State<T_2>) => import(".").SetSharedState<T_2>;
|
|
12
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const t=new WeakMap;function n(n,e,u){const r=t.get(n);r&&r.forEach(t=>t(e,u))}function e(n,e){let u=t.get(n);null==u&&(u=new Set,t.set(n,u)),u.add(e)}function u(n,e){const u=t.get(n);u&&u.delete(e)}const r=new WeakMap;function c(t){const n=function(t){return{name:t.name}}(t||{});return r.set(n,t.initialValue),n}function o(t){return r.get(t)}function f(t,e){const u=o(t),c=function(t,n){return"function"==typeof t?t(n):t}(e,u);r.set(t,c),n(t,u,c)}function a(t,n){return function(r){const[c,a]=n(()=>o(r));return t(()=>{const t=(t,n)=>a(n);return e(r,t),()=>u(r,t)},[r]),[c,t=>f(r,t)]}}function s(t,n,r,c){return function(f){const a=r(()=>new Set,[]),[,s]=n(null),i=c(()=>s({}),[]),l=c(t=>(a.has(t)||(a.add(t),e(t,i)),o(t)),[a]);return t(()=>()=>a.forEach(t=>u(t,i)),[a,i]),f({get:l})}}function i(t){return function(n){return t(n)[0]}}function l(t){return function(n){return t(n)[1]}}function S(t){const n=a(t.useEffect,t.useState);return{useSharedState:n,useSelector:s(t.useEffect,t.useState,t.useMemo,t.useCallback),useSharedStateValue:i(n),useSetSharedState:l(n)}}export{S as buildReactStatedrive,c as createState,o as get,n as notify,f as set,e as subscribe,u as unsubscribe};
|
|
2
|
+
//# sourceMappingURL=react.modern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.modern.js","sources":["../src/subscribe.ts","../src/state.ts","../src/util.ts","../src/_hook_factory.ts","../react/src/hooks.ts"],"sourcesContent":["import { State } from \"./types\";\n\ninterface Listener<T> {\n (oldValue: T, newValue: T): void;\n}\ntype ListenerMap<T> = WeakMap<State<T>, Set<Listener<T>>>;\nconst listenerMap: ListenerMap<unknown> = new WeakMap();\n\nexport function notify<T>(state: State<T>, oldValue: T, newValue: T) {\n const listeners = (listenerMap as ListenerMap<T>).get(state);\n if (listeners) listeners.forEach((fn) => fn(oldValue, newValue));\n}\n\nexport function subscribe<T>(state: State<T>, callback: Listener<T>) {\n let listeners = (listenerMap as ListenerMap<T>).get(state);\n if (listeners == null) {\n listeners = new Set();\n listenerMap.set(state, listeners);\n }\n listeners.add(callback);\n}\n\nexport function unsubscribe<T>(state: State<T>, callback: Listener<T>) {\n const listeners = (listenerMap as ListenerMap<T>).get(state);\n if (listeners) listeners.delete(callback);\n}\n","import { State, StateOptions, StateUpdater } from \"./types\";\n\nimport { consumeUpdater } from \"./util\";\nimport { notify } from \"./subscribe\";\n\nconst valueMap = new WeakMap<State<unknown>, unknown>();\n\nexport function createState<T>(options: StateOptions<T>): State<T> {\n const state = _state(options || {});\n valueMap.set(state, options.initialValue);\n return state;\n}\n\nfunction _state<T>(options: StateOptions<T> | State<T>) {\n return { name: options.name };\n}\n\nexport function get<T>(state: State<T>): T {\n return valueMap.get(state) as T;\n}\n\nexport function set<T>(state: State<T>, newValue: StateUpdater<T>) {\n const oldValue = get(state);\n const next = consumeUpdater(newValue, oldValue);\n valueMap.set(state, next);\n notify(state, oldValue, next);\n}\n","import { StateUpdater, FunctionUpdater } from \"./types\";\n\nexport function consumeUpdater<T>(u: StateUpdater<T>, oldValue: T) {\n if (typeof u === \"function\") return (u as FunctionUpdater<T>)(oldValue);\n return u;\n}\n","import type {\n useCallback as UseCallbackType,\n useEffect as UseEffectType,\n useMemo as UseMemoType,\n useState as UseStateType,\n} from \"@hydrophobefireman/ui-lib\";\n\nimport {get, set} from \"./state\";\nimport {subscribe, unsubscribe} from \"./subscribe\";\nimport {SelectorOptions, SetSharedState, State, StateUpdater} from \"./types\";\n\nexport namespace Hooks {\n export type useEffect = typeof UseEffectType;\n export type useState = typeof UseStateType;\n export type useCallback = typeof UseCallbackType;\n export type useMemo = typeof UseMemoType;\n}\n\nexport function createUseSharedState(\n useEffect: Hooks.useEffect,\n useState: Hooks.useState\n) {\n return function useSharedState<T>(state: State<T>): [T, SetSharedState<T>] {\n const [value, setValue] = useState(() => get(state));\n\n useEffect(() => {\n const listener = (_: T, newVal: T) => setValue(newVal);\n subscribe(state, listener);\n return () => unsubscribe(state, listener);\n }, [state]);\n\n return [value, (nextValue: StateUpdater<T>) => set(state, nextValue)];\n };\n}\n\nexport function createUseSelector(\n useEffect: Hooks.useEffect,\n useState: Hooks.useState,\n useMemo: Hooks.useMemo,\n useCallback: Hooks.useCallback\n) {\n return function useSelector<R>(func: (options: SelectorOptions<R>) => R): R {\n const hasSubscribed = useMemo(() => new Set<State<unknown>>(), []);\n const [, setState] = useState(null);\n const fn = useCallback(() => setState({}), []);\n const _get = useCallback(\n <S>(s: State<S>): S => {\n if (!hasSubscribed.has(s)) {\n hasSubscribed.add(s);\n subscribe(s, fn);\n }\n return get(s);\n },\n [hasSubscribed]\n );\n useEffect(\n () => () => hasSubscribed.forEach((x) => unsubscribe(x, fn)),\n [hasSubscribed, fn]\n );\n return func({get: _get});\n };\n}\n\nexport function createUseSharedStateValue(\n useSharedState: ReturnType<typeof createUseSharedState>\n) {\n return function useSharedStateValue<T>(s: State<T>): T {\n return useSharedState(s)[0];\n };\n}\nexport function createUseSetSharedState(\n useSharedState: ReturnType<typeof createUseSharedState>\n) {\n return function useSetSharedState<T>(s: State<T>): SetSharedState<T> {\n return useSharedState(s)[1];\n };\n}\n","import * as factory from \"../../src/_hook_factory\";\n\nexport function buildReactStatedrive(data: {\n useEffect: factory.Hooks.useEffect;\n useState: factory.Hooks.useState;\n useMemo: factory.Hooks.useMemo;\n useCallback: factory.Hooks.useCallback;\n}) {\n const useSharedState = /*#__PURE__*/ factory.createUseSharedState(\n data.useEffect,\n data.useState\n );\n\n const useSelector = /*#__PURE__*/ factory.createUseSelector(\n data.useEffect,\n data.useState,\n data.useMemo,\n data.useCallback\n );\n\n const useSharedStateValue =\n /*#__PURE__*/ factory.createUseSharedStateValue(useSharedState);\n\n const useSetSharedState =\n /*#__PURE__*/ factory.createUseSetSharedState(useSharedState);\n return {useSharedState, useSelector, useSharedStateValue, useSetSharedState};\n}\n"],"names":["listenerMap","WeakMap","notify","state","oldValue","newValue","listeners","get","forEach","fn","subscribe","callback","Set","set","add","unsubscribe","delete","valueMap","createState","options","name","_state","initialValue","next","u","consumeUpdater","createUseSharedState","useEffect","useState","value","setValue","listener","_","newVal","nextValue","createUseSelector","useMemo","useCallback","func","hasSubscribed","setState","_get","s","has","x","createUseSharedStateValue","useSharedState","createUseSetSharedState","buildReactStatedrive","data","factory","useSelector","useSharedStateValue","useSetSharedState"],"mappings":"AAMA,MAAMA,EAAoC,IAAIC,iBAE9BC,EAAUC,EAAiBC,EAAaC,GACtD,MAAMC,EAAaN,EAA+BO,IAAIJ,GAClDG,GAAWA,EAAUE,QAASC,GAAOA,EAAGL,EAAUC,aAGxCK,EAAaP,EAAiBQ,GAC5C,IAAIL,EAAaN,EAA+BO,IAAIJ,GACnC,MAAbG,IACFA,EAAY,IAAIM,IAChBZ,EAAYa,IAAIV,EAAOG,IAEzBA,EAAUQ,IAAIH,YAGAI,EAAeZ,EAAiBQ,GAC9C,MAAML,EAAaN,EAA+BO,IAAIJ,GAClDG,GAAWA,EAAUU,OAAOL,GCnBlC,MAAMM,EAAW,IAAIhB,iBAELiB,EAAeC,GAC7B,MAAMhB,EAKR,SAAmBgB,GACjB,MAAO,CAAEC,KAAMD,EAAQC,MANTC,CAAOF,GAAW,IAEhC,OADAF,EAASJ,IAAIV,EAAOgB,EAAQG,cACrBnB,WAOOI,EAAOJ,GACrB,OAAOc,EAASV,IAAIJ,YAGNU,EAAOV,EAAiBE,GACtC,MAAMD,EAAWG,EAAIJ,GACfoB,WCrB0BC,EAAoBpB,GACpD,MAAiB,mBAANoB,EAA0BA,EAAyBpB,GACvDoB,EDmBMC,CAAepB,EAAUD,GACtCa,EAASJ,IAAIV,EAAOoB,GACpBrB,EAAOC,EAAOC,EAAUmB,YEPVG,EACdC,EACAC,GAEA,gBAAkCzB,GAChC,MAAO0B,EAAOC,GAAYF,EAAS,IAAMrB,EAAIJ,IAQ7C,OANAwB,EAAU,KACR,MAAMI,EAAW,CAACC,EAAMC,IAAcH,EAASG,GAE/C,OADAvB,EAAUP,EAAO4B,GACV,IAAMhB,EAAYZ,EAAO4B,IAC/B,CAAC5B,IAEG,CAAC0B,EAAQK,GAA+BrB,EAAIV,EAAO+B,cAI9CC,EACdR,EACAC,EACAQ,EACAC,GAEA,gBAA+BC,GAC7B,MAAMC,EAAgBH,EAAQ,IAAM,IAAIxB,IAAuB,MACtD4B,GAAYZ,EAAS,MACxBnB,EAAK4B,EAAY,IAAMG,EAAS,IAAK,IACrCC,EAAOJ,EACPK,IACGH,EAAcI,IAAID,KACrBH,EAAczB,IAAI4B,GAClBhC,EAAUgC,EAAGjC,IAERF,EAAImC,IAEb,CAACH,IAMH,OAJAZ,EACE,IAAM,IAAMY,EAAc/B,QAASoC,GAAM7B,EAAY6B,EAAGnC,IACxD,CAAC8B,EAAe9B,IAEX6B,EAAK,CAAC/B,IAAKkC,cAINI,EACdC,GAEA,gBAAuCJ,GACrC,OAAOI,EAAeJ,GAAG,aAGbK,EACdD,GAEA,gBAAqCJ,GACnC,OAAOI,EAAeJ,GAAG,aCxEbM,EAAqBC,GAMnC,MAAMH,EAA+BI,EACnCD,EAAKtB,UACLsB,EAAKrB,UAeP,MAAO,CAACkB,eAAAA,EAAgBK,YAZUD,EAChCD,EAAKtB,UACLsB,EAAKrB,SACLqB,EAAKb,QACLa,EAAKZ,aAQ8Be,oBAJrBF,EAAkCJ,GAIQO,kBAD1CH,EAAgCJ"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { useCallback as UseCallbackType, useEffect as UseEffectType, useMemo as UseMemoType, useState as UseStateType } from "@hydrophobefireman/ui-lib";
|
|
2
|
+
import { SelectorOptions, SetSharedState, State } from "./types";
|
|
3
|
+
export declare namespace Hooks {
|
|
4
|
+
type useEffect = typeof UseEffectType;
|
|
5
|
+
type useState = typeof UseStateType;
|
|
6
|
+
type useCallback = typeof UseCallbackType;
|
|
7
|
+
type useMemo = typeof UseMemoType;
|
|
8
|
+
}
|
|
9
|
+
export declare function createUseSharedState(useEffect: Hooks.useEffect, useState: Hooks.useState): <T>(state: State<T>) => [T, SetSharedState<T>];
|
|
10
|
+
export declare function createUseSelector(useEffect: Hooks.useEffect, useState: Hooks.useState, useMemo: Hooks.useMemo, useCallback: Hooks.useCallback): <R>(func: (options: SelectorOptions<R>) => R) => R;
|
|
11
|
+
export declare function createUseSharedStateValue(useSharedState: ReturnType<typeof createUseSharedState>): <T>(s: State<T>) => T;
|
|
12
|
+
export declare function createUseSetSharedState(useSharedState: ReturnType<typeof createUseSharedState>): <T>(s: State<T>) => SetSharedState<T>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { State, StateOptions, StateUpdater } from "./types";
|
|
2
|
+
export declare function createState<T>(options: StateOptions<T>): State<T>;
|
|
3
|
+
export declare function get<T>(state: State<T>): T;
|
|
4
|
+
export declare function set<T>(state: State<T>, newValue: StateUpdater<T>): void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { State } from "./types";
|
|
2
|
+
interface Listener<T> {
|
|
3
|
+
(oldValue: T, newValue: T): void;
|
|
4
|
+
}
|
|
5
|
+
export declare function notify<T>(state: State<T>, oldValue: T, newValue: T): void;
|
|
6
|
+
export declare function subscribe<T>(state: State<T>, callback: Listener<T>): void;
|
|
7
|
+
export declare function unsubscribe<T>(state: State<T>, callback: Listener<T>): void;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface StateOptions<T> {
|
|
2
|
+
name?: string;
|
|
3
|
+
initialValue?: T;
|
|
4
|
+
}
|
|
5
|
+
export interface State<T> {
|
|
6
|
+
name: string | void;
|
|
7
|
+
}
|
|
8
|
+
export interface FunctionUpdater<T> {
|
|
9
|
+
(previous?: T): T;
|
|
10
|
+
}
|
|
11
|
+
export interface SetSharedState<T> {
|
|
12
|
+
(val: StateUpdater<T>): void;
|
|
13
|
+
}
|
|
14
|
+
export interface SelectorOptions<T> {
|
|
15
|
+
get(s: State<T>): T;
|
|
16
|
+
}
|
|
17
|
+
export declare type StateUpdater<T> = T | FunctionUpdater<T>;
|
|
18
|
+
export {};
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { State, StateOptions, StateUpdater } from "./types";
|
|
2
|
+
export declare function createState<T>(options: StateOptions<T>): State<T>;
|
|
3
|
+
export declare function get<T>(state: State<T>): T;
|
|
4
|
+
export declare function set<T>(state: State<T>, newValue: StateUpdater<T>): void;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{useState as n,useEffect as t,useCallback as e,useMemo as o}from"@hydrophobefireman/ui-lib";const u=new WeakMap;function r(n,t,e){const o=u.get(n);o&&o.forEach(n=>n(t,e))}function c(n,t){let e=u.get(n);null==e&&(e=new Set,u.set(n,e)),e.add(t)}function i(n,t){const e=u.get(n);e&&e.delete(t)}const f=new WeakMap;function a(n){const t=function(n){return{name:n.name}}(n||{});return f.set(t,n.initialValue),t}function s(n){return f.get(n)}function l(n,t){const e=s(n),o=function(n,t){return"function"==typeof n?n(t):n}(t,e);f.set(n,o),r(n,e,o)}function d(n,t){return function(e){const[o,u]=t(()=>s(e));return n(()=>{const n=(n,t)=>u(t);return c(e,n),()=>i(e,n)},[e]),[o,n=>l(e,n)]}}function p(n,t,e,o){return function(u){const r=e(()=>new Set,[]),[,f]=t(null),a=o(()=>f({}),[]),l=o(n=>(r.has(n)||(r.add(n),c(n,a)),s(n)),[r]);return n(()=>()=>r.forEach(n=>i(n,a)),[r,a]),u({get:l})}}function g(n){return function(t){return n(t)[0]}}function h(n){return function(t){return n(t)[1]}}const m=d(t,n),w=p(t,n,o,e),b=g(m),k=h(m);export{a as createState,s as get,r as notify,l as set,c as subscribe,i as unsubscribe,w as useSelector,k as useSetSharedState,m as useSharedState,b as useSharedStateValue};
|
|
2
|
+
//# sourceMappingURL=statedrive.modern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statedrive.modern.js","sources":["../src/subscribe.ts","../src/state.ts","../src/util.ts","../src/_hook_factory.ts","../src/hooks.ts"],"sourcesContent":["import { State } from \"./types\";\n\ninterface Listener<T> {\n (oldValue: T, newValue: T): void;\n}\ntype ListenerMap<T> = WeakMap<State<T>, Set<Listener<T>>>;\nconst listenerMap: ListenerMap<unknown> = new WeakMap();\n\nexport function notify<T>(state: State<T>, oldValue: T, newValue: T) {\n const listeners = (listenerMap as ListenerMap<T>).get(state);\n if (listeners) listeners.forEach((fn) => fn(oldValue, newValue));\n}\n\nexport function subscribe<T>(state: State<T>, callback: Listener<T>) {\n let listeners = (listenerMap as ListenerMap<T>).get(state);\n if (listeners == null) {\n listeners = new Set();\n listenerMap.set(state, listeners);\n }\n listeners.add(callback);\n}\n\nexport function unsubscribe<T>(state: State<T>, callback: Listener<T>) {\n const listeners = (listenerMap as ListenerMap<T>).get(state);\n if (listeners) listeners.delete(callback);\n}\n","import { State, StateOptions, StateUpdater } from \"./types\";\n\nimport { consumeUpdater } from \"./util\";\nimport { notify } from \"./subscribe\";\n\nconst valueMap = new WeakMap<State<unknown>, unknown>();\n\nexport function createState<T>(options: StateOptions<T>): State<T> {\n const state = _state(options || {});\n valueMap.set(state, options.initialValue);\n return state;\n}\n\nfunction _state<T>(options: StateOptions<T> | State<T>) {\n return { name: options.name };\n}\n\nexport function get<T>(state: State<T>): T {\n return valueMap.get(state) as T;\n}\n\nexport function set<T>(state: State<T>, newValue: StateUpdater<T>) {\n const oldValue = get(state);\n const next = consumeUpdater(newValue, oldValue);\n valueMap.set(state, next);\n notify(state, oldValue, next);\n}\n","import { StateUpdater, FunctionUpdater } from \"./types\";\n\nexport function consumeUpdater<T>(u: StateUpdater<T>, oldValue: T) {\n if (typeof u === \"function\") return (u as FunctionUpdater<T>)(oldValue);\n return u;\n}\n","import type {\n useCallback as UseCallbackType,\n useEffect as UseEffectType,\n useMemo as UseMemoType,\n useState as UseStateType,\n} from \"@hydrophobefireman/ui-lib\";\n\nimport {get, set} from \"./state\";\nimport {subscribe, unsubscribe} from \"./subscribe\";\nimport {SelectorOptions, SetSharedState, State, StateUpdater} from \"./types\";\n\nexport namespace Hooks {\n export type useEffect = typeof UseEffectType;\n export type useState = typeof UseStateType;\n export type useCallback = typeof UseCallbackType;\n export type useMemo = typeof UseMemoType;\n}\n\nexport function createUseSharedState(\n useEffect: Hooks.useEffect,\n useState: Hooks.useState\n) {\n return function useSharedState<T>(state: State<T>): [T, SetSharedState<T>] {\n const [value, setValue] = useState(() => get(state));\n\n useEffect(() => {\n const listener = (_: T, newVal: T) => setValue(newVal);\n subscribe(state, listener);\n return () => unsubscribe(state, listener);\n }, [state]);\n\n return [value, (nextValue: StateUpdater<T>) => set(state, nextValue)];\n };\n}\n\nexport function createUseSelector(\n useEffect: Hooks.useEffect,\n useState: Hooks.useState,\n useMemo: Hooks.useMemo,\n useCallback: Hooks.useCallback\n) {\n return function useSelector<R>(func: (options: SelectorOptions<R>) => R): R {\n const hasSubscribed = useMemo(() => new Set<State<unknown>>(), []);\n const [, setState] = useState(null);\n const fn = useCallback(() => setState({}), []);\n const _get = useCallback(\n <S>(s: State<S>): S => {\n if (!hasSubscribed.has(s)) {\n hasSubscribed.add(s);\n subscribe(s, fn);\n }\n return get(s);\n },\n [hasSubscribed]\n );\n useEffect(\n () => () => hasSubscribed.forEach((x) => unsubscribe(x, fn)),\n [hasSubscribed, fn]\n );\n return func({get: _get});\n };\n}\n\nexport function createUseSharedStateValue(\n useSharedState: ReturnType<typeof createUseSharedState>\n) {\n return function useSharedStateValue<T>(s: State<T>): T {\n return useSharedState(s)[0];\n };\n}\nexport function createUseSetSharedState(\n useSharedState: ReturnType<typeof createUseSharedState>\n) {\n return function useSetSharedState<T>(s: State<T>): SetSharedState<T> {\n return useSharedState(s)[1];\n };\n}\n","import * as factory from \"./_hook_factory\";\n\nimport {\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from \"@hydrophobefireman/ui-lib\";\n\nexport const useSharedState = /*#__PURE__*/ factory.createUseSharedState(\n useEffect,\n useState\n);\n\nexport const useSelector = /*#__PURE__*/ factory.createUseSelector(\n useEffect,\n useState,\n useMemo,\n useCallback\n);\n\nexport const useSharedStateValue =\n /*#__PURE__*/ factory.createUseSharedStateValue(useSharedState);\n\nexport const useSetSharedState =\n /*#__PURE__*/ factory.createUseSetSharedState(useSharedState);\n"],"names":["listenerMap","WeakMap","notify","state","oldValue","newValue","listeners","get","forEach","fn","subscribe","callback","Set","set","add","unsubscribe","delete","valueMap","createState","options","name","_state","initialValue","next","u","consumeUpdater","createUseSharedState","useEffect","useState","value","setValue","listener","_","newVal","nextValue","createUseSelector","useMemo","useCallback","func","hasSubscribed","setState","_get","s","has","x","createUseSharedStateValue","useSharedState","createUseSetSharedState","factory","useSelector","useSharedStateValue","useSetSharedState"],"mappings":"kGAMA,MAAMA,EAAoC,IAAIC,iBAE9BC,EAAUC,EAAiBC,EAAaC,GACtD,MAAMC,EAAaN,EAA+BO,IAAIJ,GAClDG,GAAWA,EAAUE,QAASC,GAAOA,EAAGL,EAAUC,aAGxCK,EAAaP,EAAiBQ,GAC5C,IAAIL,EAAaN,EAA+BO,IAAIJ,GACnC,MAAbG,IACFA,EAAY,IAAIM,IAChBZ,EAAYa,IAAIV,EAAOG,IAEzBA,EAAUQ,IAAIH,YAGAI,EAAeZ,EAAiBQ,GAC9C,MAAML,EAAaN,EAA+BO,IAAIJ,GAClDG,GAAWA,EAAUU,OAAOL,GCnBlC,MAAMM,EAAW,IAAIhB,iBAELiB,EAAeC,GAC7B,MAAMhB,EAKR,SAAmBgB,GACjB,MAAO,CAAEC,KAAMD,EAAQC,MANTC,CAAOF,GAAW,IAEhC,OADAF,EAASJ,IAAIV,EAAOgB,EAAQG,cACrBnB,WAOOI,EAAOJ,GACrB,OAAOc,EAASV,IAAIJ,YAGNU,EAAOV,EAAiBE,GACtC,MAAMD,EAAWG,EAAIJ,GACfoB,WCrB0BC,EAAoBpB,GACpD,MAAiB,mBAANoB,EAA0BA,EAAyBpB,GACvDoB,EDmBMC,CAAepB,EAAUD,GACtCa,EAASJ,IAAIV,EAAOoB,GACpBrB,EAAOC,EAAOC,EAAUmB,YEPVG,EACdC,EACAC,GAEA,gBAAkCzB,GAChC,MAAO0B,EAAOC,GAAYF,EAAS,IAAMrB,EAAIJ,IAQ7C,OANAwB,EAAU,KACR,MAAMI,EAAW,CAACC,EAAMC,IAAcH,EAASG,GAE/C,OADAvB,EAAUP,EAAO4B,GACV,IAAMhB,EAAYZ,EAAO4B,IAC/B,CAAC5B,IAEG,CAAC0B,EAAQK,GAA+BrB,EAAIV,EAAO+B,cAI9CC,EACdR,EACAC,EACAQ,EACAC,GAEA,gBAA+BC,GAC7B,MAAMC,EAAgBH,EAAQ,IAAM,IAAIxB,IAAuB,MACtD4B,GAAYZ,EAAS,MACxBnB,EAAK4B,EAAY,IAAMG,EAAS,IAAK,IACrCC,EAAOJ,EACPK,IACGH,EAAcI,IAAID,KACrBH,EAAczB,IAAI4B,GAClBhC,EAAUgC,EAAGjC,IAERF,EAAImC,IAEb,CAACH,IAMH,OAJAZ,EACE,IAAM,IAAMY,EAAc/B,QAASoC,GAAM7B,EAAY6B,EAAGnC,IACxD,CAAC8B,EAAe9B,IAEX6B,EAAK,CAAC/B,IAAKkC,cAINI,EACdC,GAEA,gBAAuCJ,GACrC,OAAOI,EAAeJ,GAAG,aAGbK,EACdD,GAEA,gBAAqCJ,GACnC,OAAOI,EAAeJ,GAAG,ICjEhBI,MAAAA,EAA+BE,EAC1CrB,EACAC,GAGWqB,EAA4BD,EACvCrB,EACAC,EACAQ,EACAC,GAGWa,EACGF,EAAkCF,GAErCK,EACGH,EAAgCF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { State } from "./types";
|
|
2
|
+
interface Listener<T> {
|
|
3
|
+
(oldValue: T, newValue: T): void;
|
|
4
|
+
}
|
|
5
|
+
export declare function notify<T>(state: State<T>, oldValue: T, newValue: T): void;
|
|
6
|
+
export declare function subscribe<T>(state: State<T>, callback: Listener<T>): void;
|
|
7
|
+
export declare function unsubscribe<T>(state: State<T>, callback: Listener<T>): void;
|
|
8
|
+
export {};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface StateOptions<T> {
|
|
2
|
+
name?: string;
|
|
3
|
+
initialValue?: T;
|
|
4
|
+
}
|
|
5
|
+
export interface State<T> {
|
|
6
|
+
name: string | void;
|
|
7
|
+
}
|
|
8
|
+
export interface FunctionUpdater<T> {
|
|
9
|
+
(previous?: T): T;
|
|
10
|
+
}
|
|
11
|
+
export interface SetSharedState<T> {
|
|
12
|
+
(val: StateUpdater<T>): void;
|
|
13
|
+
}
|
|
14
|
+
export interface SelectorOptions<T> {
|
|
15
|
+
get(s: State<T>): T;
|
|
16
|
+
}
|
|
17
|
+
export declare type StateUpdater<T> = T | FunctionUpdater<T>;
|
|
18
|
+
export {};
|
package/dist/util.d.ts
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "statedrive",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/statedrive.modern.js",
|
|
6
6
|
"module": "dist/statedrive.modern.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"typescript": "^4.3.2"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@hydrophobefireman/ui-lib": "
|
|
36
|
-
"react": "
|
|
35
|
+
"@hydrophobefireman/ui-lib": "^2.0.0",
|
|
36
|
+
"react": "^18.2.0"
|
|
37
37
|
}
|
|
38
38
|
}
|
package/react/src/hooks.ts
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
import * as factory from "../../src/_hook_factory";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export function buildReactStatedrive(data: {
|
|
4
|
+
useEffect: factory.Hooks.useEffect;
|
|
5
|
+
useState: factory.Hooks.useState;
|
|
6
|
+
useMemo: factory.Hooks.useMemo;
|
|
7
|
+
useCallback: factory.Hooks.useCallback;
|
|
8
|
+
}) {
|
|
9
|
+
const useSharedState = /*#__PURE__*/ factory.createUseSharedState(
|
|
10
|
+
data.useEffect,
|
|
11
|
+
data.useState
|
|
12
|
+
);
|
|
4
13
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
14
|
+
const useSelector = /*#__PURE__*/ factory.createUseSelector(
|
|
15
|
+
data.useEffect,
|
|
16
|
+
data.useState,
|
|
17
|
+
data.useMemo,
|
|
18
|
+
data.useCallback
|
|
19
|
+
);
|
|
9
20
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
useState,
|
|
13
|
-
useMemo,
|
|
14
|
-
useCallback
|
|
15
|
-
);
|
|
21
|
+
const useSharedStateValue =
|
|
22
|
+
/*#__PURE__*/ factory.createUseSharedStateValue(useSharedState);
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
export const useSetSharedState = /*#__PURE__*/ factory.createUseSetSharedState(
|
|
22
|
-
useSharedState
|
|
23
|
-
);
|
|
24
|
+
const useSetSharedState =
|
|
25
|
+
/*#__PURE__*/ factory.createUseSetSharedState(useSharedState);
|
|
26
|
+
return {useSharedState, useSelector, useSharedStateValue, useSetSharedState};
|
|
27
|
+
}
|
package/src/_hook_factory.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { SelectorOptions, SetSharedState, State, StateUpdater } from "./types";
|
|
2
1
|
import type {
|
|
3
2
|
useCallback as UseCallbackType,
|
|
4
3
|
useEffect as UseEffectType,
|
|
5
4
|
useMemo as UseMemoType,
|
|
6
5
|
useState as UseStateType,
|
|
7
6
|
} from "@hydrophobefireman/ui-lib";
|
|
8
|
-
import { get, set } from "./state";
|
|
9
|
-
import { subscribe, unsubscribe } from "./subscribe";
|
|
10
7
|
|
|
11
|
-
|
|
8
|
+
import {get, set} from "./state";
|
|
9
|
+
import {subscribe, unsubscribe} from "./subscribe";
|
|
10
|
+
import {SelectorOptions, SetSharedState, State, StateUpdater} from "./types";
|
|
11
|
+
|
|
12
|
+
export namespace Hooks {
|
|
12
13
|
export type useEffect = typeof UseEffectType;
|
|
13
14
|
export type useState = typeof UseStateType;
|
|
14
15
|
export type useCallback = typeof UseCallbackType;
|
|
@@ -56,7 +57,7 @@ export function createUseSelector(
|
|
|
56
57
|
() => () => hasSubscribed.forEach((x) => unsubscribe(x, fn)),
|
|
57
58
|
[hasSubscribed, fn]
|
|
58
59
|
);
|
|
59
|
-
return func({
|
|
60
|
+
return func({get: _get});
|
|
60
61
|
};
|
|
61
62
|
}
|
|
62
63
|
|