@rkrupinski/stan 1.2.1 → 1.3.0

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/dist/atom.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import type { SerializableParam, SetterOrUpdater, TagFromParam } from './types';
2
2
  import { type TypedOmit } from './internal';
3
- import type { WritableState } from './state';
4
- import type { Scoped } from './store';
3
+ import type { WritableState, Scoped } from './state';
5
4
  export type AtomEffect<T> = (param: {
6
5
  init(value: T): void;
7
6
  set: SetterOrUpdater<T>;
@@ -10,8 +9,9 @@ export type AtomEffect<T> = (param: {
10
9
  export type AtomOptions<T> = {
11
10
  tag?: string;
12
11
  effects?: ReadonlyArray<AtomEffect<T>>;
12
+ areValuesEqual?: <T>(a: T, b: T) => boolean;
13
13
  };
14
- export declare const atom: <T>(initialValue: T, { tag, effects }?: AtomOptions<T>) => Scoped<WritableState<T>>;
14
+ export declare const atom: <T>(initialValue: T, { tag, effects, areValuesEqual }?: AtomOptions<T>) => Scoped<WritableState<T>>;
15
15
  export type ValueFromParam<T, P extends SerializableParam> = (param: P) => T;
16
16
  export type AtomFamilyOptions<T, P extends SerializableParam> = TypedOmit<AtomOptions<T>, 'tag'> & {
17
17
  tag?: string | TagFromParam<P>;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{i as t,R as s,a,s as c,b as i,c as n,d as l}from"./store-C_86rrYV.js";export{D as DEFAULT_STORE,S as Store,m as makeStore,r as refresh,e as reset}from"./store-C_86rrYV.js";class o extends Error{}class h{#e;#t;constructor(e){this.#e=new Map,this.#t=e}#s(){const e=this.#e.keys().next().value;void 0!==e&&this.#e.delete(e)}has(e){return this.#e.has(e)}get(e){if(!this.has(e))return;const t=this.#e.get(e);return this.#e.delete(e),this.#e.set(e,t),t}set(e,t){this.#e.has(e)?this.#e.delete(e):this.#e.size>=this.#t&&this.#s(),this.#e.set(e,t)}delete(e){return this.#e.delete(e)}clear(){this.#e.clear()}}class u extends Map{}const d=(e,{cachePolicy:s={type:"keep-all"},keyMaker:a=t}={})=>{const c=(e=>{switch(e.type){case"keep-all":return new u;case"most-recent":return new h(1);case"lru":return new h(e.maxSize);default:return e}})(s);return t=>{const s=a(t);return c.has(s)||c.set(s,e(t)),c.get(s)}};let g=0;const z=(e,{tag:t,effects:c}={})=>{const i=e,r=`atom${t?`-${t}`:""}-${g++}`;return d((e=>{const n=new Set,l=new Set,o=(t=!1)=>s=>{if(!e.initialized.get(r))return;const c=e.value.get(r),i=a(s)?s(c):s;e.value.set(r,i),n.forEach((e=>e(i))),t||l.forEach((e=>e(i)))},h=o(),u=o(!0);return{tag:t,get:()=>(e.initialized.get(r)||(e.value.set(r,i),c?.forEach((t=>t({init(t){e.initialized.get(r)||e.value.set(r,t)},set:u,onSet(e){l.add(e)}}))),e.initialized.set(r,!0)),e.value.get(r)),set:h,subscribe:e=>(n.add(e),()=>{n.delete(e)}),[s](){h(i)}}}))},f=(e,{tag:t,...s}={})=>d((c=>z(a(e)?e(c):e,{tag:a(t)?t(c):t,...s})),{keyMaker:c});let v=0;const w=(e,{tag:t,areValuesEqual:s=l}={})=>{const a=`selector${t?`-${t}`:""}-${v++}`;return d((c=>{const r=new Set,l=new Set;let h=null,u=0;const d=new Set,g=e=>{const t=e(c);let a=t.get();return r.has(t)||(r.add(t),l.add(t.subscribe((e=>{s(a,e)||(a=e,z(),f())})))),a},z=()=>{const t=++u;l.forEach((e=>e())),l.clear(),r.clear(),h?.abort(new o),h=new AbortController;const s=e({get:g,signal:h.signal});c.value.set(a,s),n(s)&&s.then(void 0,(()=>{t===u&&c.initialized.set(a,!1)}))},f=()=>{d.forEach((e=>e(c.value.get(a))))};return{tag:t,get:()=>(c.initialized.get(a)||(z(),c.initialized.set(a,!0)),c.value.get(a)),subscribe:e=>(0===d.size&&c.mounted.set(a,!0),d.add(e),function(){d.delete(e),0===d.size&&c.mounted.set(a,!1)}),[i](){c.mounted.get(a)?(z(),f()):(c.initialized.set(a,!1),h=null)}}}))},y=(e,{cachePolicy:t,tag:s,...i}={})=>d((t=>w(e(t),{tag:a(s)?s(t):s,...i})),{cachePolicy:t,keyMaker:c});export{o as Aborted,z as atom,f as atomFamily,w as selector,y as selectorFamily};
1
+ import{i as t,d as s,R as a,a as c,s as n,b as i,c as o}from"./store-P73VI2VP.js";export{D as DEFAULT_STORE,S as Store,m as makeStore,r as refresh,e as reset}from"./store-P73VI2VP.js";class l extends Error{}class h{#e;#t;constructor(e){this.#e=new Map,this.#t=e}#s(){const e=this.#e.keys().next().value;void 0!==e&&this.#e.delete(e)}has(e){return this.#e.has(e)}get(e){if(!this.has(e))return;const t=this.#e.get(e);return this.#e.delete(e),this.#e.set(e,t),t}set(e,t){this.#e.has(e)?this.#e.delete(e):this.#e.size>=this.#t&&this.#s(),this.#e.set(e,t)}delete(e){return this.#e.delete(e)}clear(){this.#e.clear()}}class u extends Map{}const d=(e,{cachePolicy:s={type:"keep-all"},keyMaker:a=t}={})=>{const r=(e=>{switch(e.type){case"keep-all":return new u;case"most-recent":return new h(1);case"lru":return new h(e.maxSize);default:return e}})(s);return t=>{const s=a(t);return r.has(s)||r.set(s,e(t)),r.get(s)}};let g=0;const f=(e,{tag:t,effects:r,areValuesEqual:n=s}={})=>{const i=e,o=`atom${t?`-${t}`:""}-${g++}`;return d((e=>{const t=new Set,s=new Set;e.value.set(o,i),e.version.set(o,1);const l=(a=!1)=>r=>{if(!e.initialized.get(o))return;const i=e.value.get(o),l=c(r)?r(i):r;n(i,l)||((()=>{const t=e.version.get(o)??0;e.version.set(o,t+1)})(),e.value.set(o,l),[...t].forEach((e=>e(l))),a||s.forEach((e=>e(l))))},h=l(),u=l(!0);return{key:o,get:()=>(e.initialized.get(o)||(e.value.set(o,i),r?.forEach((t=>t({init(t){e.initialized.get(o)||e.value.set(o,t)},set:u,onSet(e){s.add(e)}}))),e.initialized.set(o,!0)),e.value.get(o)),set:h,subscribe:e=>(t.add(e),()=>{t.delete(e)}),[a](){h(i)}}}))},v=(e,{tag:t,...s}={})=>d((a=>f(c(e)?e(a):e,{tag:c(t)?t(a):t,...s})),{keyMaker:n});let k=0;const y=(e,{tag:t,areValuesEqual:a=s}={})=>{const r=`selector${t?`-${t}`:""}-${k++}`;return d((t=>{const s=new Map;t.deps.set(r,s);const c=new Set,n=new Set;let h=null;const u=new Set,d=e=>{const s=t.deps.get(e);if(!s||!s.size)return!1;for(const[e,a]of s.entries())if(t.version.get(e)!==a)return!0;for(const e of s.keys())if(d(e))return!0;return!1};let g=0;const f=()=>{s.clear(),c.clear(),n.forEach((e=>e())),n.clear(),h?.abort(new l),h=new AbortController;const i=e({get:(d=++g,e=>{const a=e(t),i=a.get();if(!s.has(a.key)&&d===g){s.set(a.key,t.version.get(a.key)??0);const e=()=>a.subscribe((()=>{v()}));c.add(e),t.mounted.get(r)&&n.add(e())}return i}),signal:h.signal});var d;if(!(!t.value.has(r)||!a(t.value.get(r),i)))return;if((()=>{const e=t.version.get(r)??0;t.version.set(r,e+1)})(),t.value.set(r,i),[...u].forEach((e=>e(t.value.get(r)))),!o(i))return;const f=t.version.get(r);i.then(void 0,(()=>{f===t.version.get(r)&&t.initialized.set(r,!1)}))},v=()=>{t.mounted.get(r)?f():t.initialized.set(r,!1)};return{key:r,get(){switch(!0){case!t.initialized.get(r):f(),t.initialized.set(r,!0);break;case d(r):f()}return t.value.get(r)},subscribe:e=>(0===u.size&&(c.forEach((e=>{n.add(e())})),t.mounted.set(r,!0)),u.add(e),function(){u.delete(e),0===u.size&&(n.forEach((e=>{e()})),n.clear(),t.mounted.set(r,!1))}),[i](){v()}}}))},z=(e,{cachePolicy:t,tag:s,...a}={})=>d((t=>y(e(t),{tag:c(s)?s(t):s,...a})),{cachePolicy:t,keyMaker:n});export{l as Aborted,f as atom,v as atomFamily,y as selector,z as selectorFamily};
@@ -1,8 +1,8 @@
1
1
  export { default as stableStringify } from 'fast-json-stable-stringify';
2
- export type TypedOmit<T, K extends keyof T> = Omit<T, K>;
3
2
  export declare const REFRESH_TAG: unique symbol;
4
3
  export declare const RESET_TAG: unique symbol;
4
+ export declare const identity: <T>(arg: T) => T;
5
5
  export declare const dejaVu: <T>(a: T, b: T) => boolean;
6
+ export type TypedOmit<T, K extends keyof T> = Omit<T, K>;
6
7
  export declare const isFunction: (candidate: any) => candidate is (...args: any[]) => any;
7
8
  export declare const isPromiseLike: (candidate: any) => candidate is PromiseLike<any>;
8
- export declare const identity: <T>(arg: T) => T;
package/dist/react.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type FC, type ReactNode } from 'react';
2
- import type { State, ReadonlyState, WritableState } from './state';
3
- import { type Scoped, type Store } from './store';
2
+ import type { Scoped, State, ReadonlyState, WritableState } from './state';
3
+ import { type Store } from './store';
4
4
  export type StanCtxType = {
5
5
  store: Store;
6
6
  };
@@ -23,5 +23,5 @@ export type AsyncValue<T> = {
23
23
  reason: string;
24
24
  };
25
25
  export declare const useStanValueAsync: <T>(scopedState: Scoped<State<PromiseLike<T>>>) => AsyncValue<T>;
26
- export declare const useStanRefresher: <T>(scopedState: Scoped<ReadonlyState<T>>) => () => void;
26
+ export declare const useStanRefresh: <T>(scopedState: Scoped<ReadonlyState<T>>) => () => void;
27
27
  export declare const useStanReset: <T>(scopedState: Scoped<WritableState<T>>) => () => void;
package/dist/react.js CHANGED
@@ -1 +1 @@
1
- import{jsx as r}from"react/jsx-runtime";import{createContext as e,useContext as t,useMemo as o,useRef as n,useState as s,useEffect as a,useCallback as c}from"react";import{D as u,m as i,r as m,e as p}from"./store-C_86rrYV.js";const l=e({store:u}),d=({store:e,children:t})=>{const n=o((()=>({store:e??i()})),[e]);return r(l.Provider,{value:n,children:t})},g=()=>t(l),y=r=>{const{store:e}=g(),t=r(e),o=n(t),[c,u]=s(t.get());return a((()=>(t!==o.current&&(u(t.get()),o.current=t),t.subscribe(u))),[t]),c},f=r=>{const{store:e}=g();return r(e).set},h=r=>[y(r),f(r)],v=r=>{const e=y(r),[t,o]=s({type:"loading"});return a((()=>{let r=!0;return"loading"!==t.type&&o({type:"loading"}),e.then((e=>{r&&o({type:"ready",value:e})}),(e=>{r&&o({type:"error",reason:e?.message??"unknown"})})),()=>{r=!1}}),[e]),t},b=r=>{const{store:e}=g(),t=r(e);return c((()=>{m(t)}),[t])},j=r=>{const{store:e}=g(),t=r(e);return c((()=>{p(t)}),[t])};export{d as StanProvider,f as useSetStanValue,h as useStan,g as useStanCtx,b as useStanRefresher,j as useStanReset,y as useStanValue,v as useStanValueAsync};
1
+ import{jsx as r}from"react/jsx-runtime";import{createContext as e,useContext as t,useMemo as o,useRef as s,useState as n,useEffect as c,useCallback as u}from"react";import{D as a,m as i,r as m,e as p}from"./store-P73VI2VP.js";const l=e({store:a}),d=({store:e,children:t})=>{const s=o((()=>({store:e??i()})),[e]);return r(l.Provider,{value:s,children:t})},g=()=>t(l),y=r=>{const{store:e}=g(),t=r(e),o=s(t),[u,a]=n((()=>t.get()));return c((()=>(t!==o.current&&(o.current=t,a(t.get())),t.subscribe(a))),[t]),u},f=r=>{const{store:e}=g();return r(e).set},h=r=>[y(r),f(r)],v=r=>{const e=y(r),[t,o]=n({type:"loading"});return c((()=>{let r=!0;return o({type:"loading"}),e.then((e=>{r&&o({type:"ready",value:e})}),(e=>{r&&o({type:"error",reason:e?.message??"unknown"})})),()=>{r=!1}}),[e]),t},b=r=>{const{store:e}=g(),t=r(e);return u((()=>{m(t)}),[t])},j=r=>{const{store:e}=g(),t=r(e);return u((()=>{p(t)}),[t])};export{d as StanProvider,f as useSetStanValue,h as useStan,g as useStanCtx,b as useStanRefresh,j as useStanReset,y as useStanValue,v as useStanValueAsync};
@@ -1,7 +1,6 @@
1
1
  import { type TypedOmit } from './internal';
2
- import type { ReadonlyState, State } from './state';
3
2
  import type { SerializableParam, TagFromParam } from './types';
4
- import type { Scoped } from './store';
3
+ import type { ReadonlyState, State, Scoped } from './state';
5
4
  import { type CachePolicy } from './cache';
6
5
  export interface GetFn {
7
6
  <T>(scopedState: Scoped<State<T>>): T;
package/dist/state.d.ts CHANGED
@@ -1,7 +1,8 @@
1
+ import type { Store } from './store';
1
2
  import type { SetterOrUpdater } from './types';
2
3
  import type { REFRESH_TAG, RESET_TAG } from './internal';
3
4
  export interface State<T> {
4
- tag?: string;
5
+ key: string;
5
6
  get(): T;
6
7
  subscribe(callback: (value: T) => void): () => void;
7
8
  }
@@ -12,3 +13,4 @@ export interface WritableState<T> extends State<T> {
12
13
  set: SetterOrUpdater<T>;
13
14
  [RESET_TAG](): void;
14
15
  }
16
+ export type Scoped<T extends State<any>> = (store: Store) => T;
@@ -0,0 +1 @@
1
+ function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var n,t;var r=e(t?n:(t=1,n=function(e,n){n||(n={}),"function"==typeof n&&(n={cmp:n});var t,r="boolean"==typeof n.cycles&&n.cycles,o=n.cmp&&(t=n.cmp,function(e){return function(n,r){var o={key:n,value:e[n]},a={key:r,value:e[r]};return t(o,a)}}),a=[];return function e(n){if(n&&n.toJSON&&"function"==typeof n.toJSON&&(n=n.toJSON()),void 0!==n){if("number"==typeof n)return isFinite(n)?""+n:"null";if("object"!=typeof n)return JSON.stringify(n);var t,c;if(Array.isArray(n)){for(c="[",t=0;t<n.length;t++)t&&(c+=","),c+=e(n[t])||"null";return c+"]"}if(null===n)return"null";if(-1!==a.indexOf(n)){if(r)return JSON.stringify("__cycle__");throw new TypeError("Converting circular structure to JSON")}var i=a.push(n)-1,s=Object.keys(n).sort(o&&o(n));for(c="",t=0;t<s.length;t++){var u=s[t],l=e(n[u]);l&&(c&&(c+=","),c+=JSON.stringify(u)+":"+l)}return a.splice(i,1),"{"+c+"}"}}(e)}));const o=Symbol("__refresh__"),a=Symbol("__reset__"),c=e=>e,i=(e,n)=>e===n,s=["[object AsyncFunction]","[object AsyncGeneratorFunction]","[object GeneratorFunction]","[object Function]"],u=e=>s.includes(Object.prototype.toString.call(e)),l=e=>!!e&&u(e.then),f=e=>{e[o]()},y=e=>{e[a]()};class p{value=new Map;version=new Map;mounted=new Map;initialized=new Map;deps=new Map}const _=()=>new p,b=_();export{b as D,a as R,p as S,u as a,o as b,l as c,i as d,y as e,c as i,_ as m,f as r,r as s};
package/dist/store.d.ts CHANGED
@@ -1,8 +1,11 @@
1
+ type Deps = Map<string, number>;
1
2
  export declare class Store {
2
3
  value: Map<string, any>;
4
+ version: Map<string, number>;
3
5
  mounted: Map<string, boolean>;
4
6
  initialized: Map<string, boolean>;
7
+ deps: Map<string, Deps>;
5
8
  }
6
9
  export declare const makeStore: () => Store;
7
10
  export declare const DEFAULT_STORE: Store;
8
- export type Scoped<T> = (store: Store) => T;
11
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rkrupinski/stan",
3
3
  "description": "Minimal, type-safe state management",
4
- "version": "1.2.1",
4
+ "version": "1.3.0",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {
7
7
  ".": "./dist/index.js",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "scripts": {
11
11
  "typecheck": "tsc",
12
- "lint": "eslint --max-warnings=0",
12
+ "lint": "eslint --cache --max-warnings=0",
13
13
  "test": "jest",
14
14
  "build": "rm -rf dist && rollup --config",
15
15
  "prepublishOnly": "yarn typecheck && yarn lint && yarn test && yarn build"
@@ -18,7 +18,8 @@
18
18
  "fast-json-stable-stringify": "2.1.0"
19
19
  },
20
20
  "devDependencies": {
21
- "@eslint/js": "^9.23.0",
21
+ "@eslint/eslintrc": "3.3.1",
22
+ "@eslint/js": "9.27.0",
22
23
  "@rkrupinski/prettierconfig": "1.0.1",
23
24
  "@rollup/plugin-commonjs": "28.0.3",
24
25
  "@rollup/plugin-node-resolve": "16.0.1",
@@ -29,8 +30,14 @@
29
30
  "@types/jest": "29.5.14",
30
31
  "@types/react": ">=18.0.0",
31
32
  "@types/react-dom": ">=18.0.0",
32
- "eslint": "^9.23.0",
33
- "eslint-plugin-react": "^7.37.4",
33
+ "@typescript-eslint/eslint-plugin": "8.32.1",
34
+ "@typescript-eslint/parser": "8.32.1",
35
+ "eslint": "9.27.0",
36
+ "eslint-import-resolver-typescript": "4.3.5",
37
+ "eslint-plugin-import": "2.31.0",
38
+ "eslint-plugin-jest": "28.11.0",
39
+ "eslint-plugin-react": "7.37.5",
40
+ "eslint-plugin-react-hooks": "5.2.0",
34
41
  "globals": "^16.0.0",
35
42
  "jest": "29.7.0",
36
43
  "jest-environment-jsdom": "29.7.0",
@@ -1 +0,0 @@
1
- function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var t,n;var r=e(n?t:(n=1,t=function(e,t){t||(t={}),"function"==typeof t&&(t={cmp:t});var n,r="boolean"==typeof t.cycles&&t.cycles,o=t.cmp&&(n=t.cmp,function(e){return function(t,r){var o={key:t,value:e[t]},c={key:r,value:e[r]};return n(o,c)}}),c=[];return function e(t){if(t&&t.toJSON&&"function"==typeof t.toJSON&&(t=t.toJSON()),void 0!==t){if("number"==typeof t)return isFinite(t)?""+t:"null";if("object"!=typeof t)return JSON.stringify(t);var n,i;if(Array.isArray(t)){for(i="[",n=0;n<t.length;n++)n&&(i+=","),i+=e(t[n])||"null";return i+"]"}if(null===t)return"null";if(-1!==c.indexOf(t)){if(r)return JSON.stringify("__cycle__");throw new TypeError("Converting circular structure to JSON")}var a=c.push(t)-1,u=Object.keys(t).sort(o&&o(t));for(i="",n=0;n<u.length;n++){var s=u[n],l=e(t[s]);l&&(i&&(i+=","),i+=JSON.stringify(s)+":"+l)}return c.splice(a,1),"{"+i+"}"}}(e)}));const o=Symbol("__refresh__"),c=Symbol("__reset__"),i=(e,t)=>e===t,a=["[object AsyncFunction]","[object AsyncGeneratorFunction]","[object GeneratorFunction]","[object Function]"],u=e=>a.includes(Object.prototype.toString.call(e)),s=e=>!!e&&u(e.then),l=e=>e,f=e=>{e[o]()},y=e=>{e[c]()};class p{value=new Map;mounted=new Map;initialized=new Map}const _=()=>new p,b=_();export{b as D,c as R,p as S,u as a,o as b,s as c,i as d,y as e,l as i,_ as m,f as r,r as s};