Comparing version 0.2.2 to 0.3.0
@@ -1,1 +0,1 @@ | ||
module.exports = require("./plugin").plugin; | ||
module.exports = require('babel-plugin-realar'); |
@@ -1,75 +0,13 @@ | ||
export { | ||
unit, | ||
shared, | ||
useOwn, | ||
useShared, | ||
changed, | ||
pending, | ||
effect, | ||
Shared, | ||
mock, | ||
unmock, | ||
AsyncPool, | ||
} | ||
type Pick<T, K extends keyof T> = { | ||
[P in K]: T[P]; | ||
}; | ||
type Exclude<T, U> = T extends U ? never : T; | ||
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>; | ||
interface Func<A extends any[] = [], R = void> { | ||
(...args: A): R; | ||
} | ||
type AsyncPool = ((...args: any[]) => Promise<any>) & { | ||
pending: boolean | ||
}; | ||
type UnitAsyncMethodsPending<T> = { | ||
[P in keyof T]: T[P] extends (...args: any[]) => Promise<any> | ||
? T[P] & { pending: boolean; } | ||
: T[P]; | ||
}; | ||
type UnitInstance<T> = Omit<UnitAsyncMethodsPending<T>, "constructor" | "destructor" | "expression">; | ||
type UnitFactory<A extends any[], T> = (...args: A) => UnitInstance<T>; | ||
type UnitClass<A extends any[], T> = new (...args: A) => UnitInstance<T>; | ||
type UnitConstructorParameters<T> = T extends { constructor: (...args: any[]) => any } | ||
? Parameters<T["constructor"]> | ||
: []; | ||
type Unit<T> = UnitFactory<UnitConstructorParameters<T>, T> & UnitClass<UnitConstructorParameters<T>, T>; | ||
interface KeyedObject { | ||
[key: string]: unknown; | ||
} | ||
interface UnitSchemaInterface extends KeyedObject { | ||
constructor?: Function | ((...args: any[]) => void); | ||
destructor?: () => void; | ||
expression?: () => void; | ||
} | ||
declare function unit<T extends UnitSchemaInterface>(schema: T): Unit<T>; | ||
declare function shared<T extends UnitSchemaInterface>(unit: Unit<T>): UnitInstance<T>; | ||
declare function useOwn<T extends UnitSchemaInterface>(unit: Unit<T>, ...args: UnitConstructorParameters<T>): UnitInstance<T>; | ||
declare function useShared<T extends UnitSchemaInterface>(unit: Unit<T>): UnitInstance<T>; | ||
declare function changed(value: any): boolean; | ||
declare function pending(async: Func<any, Promise<any>>): boolean; | ||
declare function effect(fn: () => () => void): void; | ||
declare function effect(fn: () => void): void; | ||
type UnitShared = Unit<{ | ||
constructor?: () => void; | ||
}>; | ||
declare function Shared<T extends UnitShared>(props: { unit: T }): null; | ||
declare function mock(unit: Unit<any>): any; | ||
declare function unmock(unit?: Unit<any>): any; | ||
import { FC } from 'react'; | ||
export { ssr_decorator as ssr, box_decorator as box, sel_decorator as sel, reaction, expression, shared, initial, observe, use, free, mock, }; | ||
declare function ssr_decorator(key: string): (constructor: any) => void; | ||
declare function box_decorator(_proto: any, key: any, descriptor?: any): any; | ||
declare function sel_decorator(_proto: any, key: any, descriptor: any): any; | ||
declare function reaction<T>(target: () => T, listener: (value: T) => void): () => void; | ||
declare function expression(body: () => void): () => void; | ||
declare function initial(data: any): void; | ||
declare function mock<M>(Class: new (init?: any) => M, mocked: M): M; | ||
declare function shared<M>(Class: new (init?: any) => M): M; | ||
declare function observe<T extends FC<P>, P>(Component: T): import("react").MemoExoticComponent<(props: P) => import("react").ReactElement<any, any>>; | ||
declare function use<T extends unknown[], M>(Class: new (...args: T) => M, deps?: T): M; | ||
declare function free(): void; |
@@ -1,1 +0,119 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react");let e=1,n=0,o=0,r=new Set,c=[],f=null,s=0,u=new Map,i=new Map,l=new Set,p=new Map,d=[],a=null,h=new Map;function g(){if(o||r.clear(),o++,o>1e4)throw new Error("Tick deep limit exception")}function w(t){let e;do{e=t,t=new Set;for(const n of e){const e=i.get(n);if(e)for(const n of e)l.add(n),t.add(n)}}while(t.size)}function y(){if(o>1||!r.size)return void o--;let t=1e4;for(;--t;){w(r),r.clear();for(const t of l){const e=p.get(t);e&&e()}if(!r.size)break}if(o--,!t)throw new Error("Limit of expressions iteration")}function M(){const t=++e;return a&&a.push(t),t}function x(t){const e=u.get(t);if(e)for(const n of e){const e=i.get(n);e&&e.delete(t)}const n=i.get(t);if(n)for(const e of n){const n=u.get(e);n&&n.delete(t)}u.delete(t),i.delete(t),l.delete(t),p.delete(t)}function b(){d.push(a),a=[]}function S(){const t=++n;return h.set(t,a),a=d.pop(),t}function m(t){const e=h.get(t);for(const t of e)x(t);h.delete(t)}function E(){c.push([f,s])}function O(){[f,s]=c.pop()}function v(t){E(),f=new Set,s=t}function k(){l.delete(s),u.set(s,f);for(const t of f){let e=i.get(t);e||i.set(t,e=new Set),e.add(s)}O()}function j(t){const e=M();return p.set(e,t),e}function P(t){v(t),g()}function z(){y(),k()}function U(){E(),f=null,s=1,g()}function F(){y(),O()}let R=0,T=new Map,A=new Map,I=new Map,_=new Map,q=new Map,L=new Set,$=0,B=[],C=new Map,D=new Map,G=new Map,H=0;function J(t){const e=++R;return T.set(t,e),A.set(e,t),L.add(e),H||H||(H=setTimeout(()=>{H=0;const t=[];for(const e of L)I.has(e)||t.push(A.get(e));if(t.length){for(const e of t)console.error("Unit without holder detected",e);throw new Error("Memory leak detected")}L.clear()})),e}function K(t){B.push($),$=t}function N(){$=B.pop()}function Q(t,e){const n=T.get(t),o=(I.get(n)||0)+1;if(I.set(n,o),1===arguments.length&&(e=$),e){let t=_.get(e);t||_.set(e,t=new Set),t.add(n);let o=q.get(n);o||q.set(n,o=new Set),o.add(e)}return n}function V(t){I.set(t,I.get(t)-1),function(){let t=[];for(const[e,n]of I)n||(t.push(e),I.delete(e));if(!t.length)return;let e,n=[];do{n.push.apply(n,t),e=[];for(const n of t){const t=_.get(n);if(t)for(const n of t){const t=I.get(n)-1;I.set(n,t),t||e.push(n)}}t=e}while(t.length);n=n.reverse();for(const t of n)W(t)}()}function W(t){T.delete(A.get(t)),A.delete(t),I.delete(t);const e=_.get(t);if(e)for(const n of e){let e=q.get(n);e.delete(t),e.size||q.delete(n)}_.delete(t);let n=C.get(t);if(n){U();for(const t of n)t();F(),C.delete(t)}if(n=D.get(t),n){for(const t of n)m(t);D.delete(t)}if(n=G.get(t),n){for(const t of n)x(t);G.delete(t)}}function X(t){let e=C.get($);e||C.set($,e=[]),e.push(t)}function Y(t){let e=D.get($);e||D.set($,e=[]),e.push(t)}let Z=new Map,tt=0,et=0,nt=0,ot=[],rt=[];function ct(t){ot.push([et,nt]),nt=0,et=t}function ft(){[et,nt]=ot.pop()}function st(t){return(t+1)%16777215}function ut(t,e,n){let o=Z.get(et);o||Z.set(et,o=new Map);const r=++nt;if(e){if(o.has(r))return o.get(r);{const n=e(t);return Q(n),o.set(r,n),n}}if(n=n||[],o.has(r)){let[e,c]=o.get(r),f=n.length!==c.length;if(!f){if(0===n.length)return e;let t=n.length;for(;t--;)if(!Object.is(c[t],n[t])){f=1;break}}return f?(e&&V(e),e=t.apply(null,n),Q(e),o.set(r,[e,n]),e):e}{const e=t.apply(null,n);return Q(e),o.set(r,[e,n]),e}}const it=Symbol(),lt=Symbol(),pt=function(){const t={};t[lt]=!0;const e=["constructor","destructor","expression"];for(let n=0,o=e.length;n<o;n++)t[e[n]]=ht(e[n]);return t}();let dt=0;function at(t,e){let n=M(),c=0;return t&&t[lt]&&(c=Q(t)),e||(e=$),{get:()=>{return e=n,f&&f.add(e),t;var e},set:f=>{Object.is(t,f)||(c&&(c=V(c)),t=f,f&&f[lt]&&(c=Q(f,e)),function(t){const e=!o;e&&g(),r.add(t),e&&y()}(n))}}}function ht(t){return function(){throw new Error(`Manual call of unit "${t}" unsupported`)}}function gt(t){let e=arguments,n=e[0],o=e[1],r=e[2],c=e[3];if(5!==e.length)throw new Error("Invalid `unit` call. Please check your babel config.");function f(){const t=Et(f);if(t)return t.apply(this,arguments);let e=Object.create(pt),s=J(e);K(s),b(),++dt;let u=n.call(e);--dt;let i=S();Y(i);let l=4;for(let t of o)Object.defineProperty(e,t,at(u[l++],s));for(let t of r)Object.defineProperty(e,t,{get:u[l++]});for(let t of c)Object.defineProperty(e,t,{value:u[l++]});return u[0]&&u[0].apply(e,arguments),u[1]&&X(u[1]),u[2]&&u[3](),N(),e}return f[it]=c,f}gt.link=function(t){let e=Q(t,0);return()=>V(e)},gt.v=[function(){let e;if(0!==tt)return void tt++;try{e=t.useReducer(st,0)[1]}catch(t){if(-1===String(t).indexOf("Invalid hook call"))throw t;return void ct(0)}tt++;const n=t.useRef();if(!n.current){const t=J(e),o=Q(e),r=j(e);K(t),function(t){let e=G.get($);e||G.set($,e=[]),e.push(t)}(r),N();const c=()=>()=>{V(o),Z.delete(t)};n.current=[t,r,c]}const[o,r,c]=n.current;t.useEffect(c,rt),ct(o),K(o),P(r)},function(){et?(tt--,0===tt&&(z(),N(),ft())):ft()}],gt.b=at,gt.c=[j,P,z,function(){const t=M();return l.add(t),t},function(t){return f&&f.add(t),!l.has(t)||(v(t),!1)},function(){k()},U,F];let wt=new Map,yt=0,Mt=[],xt=0,bt=0,St=0;function mt(){return bt}function Et(t){return wt.get(t)}function Ot(t,e){if(!e&&xt){let e=null;if(t&&t[it]&&(e=t[it]),!e)throw"Test mocks ony unit supported";const n={};for(const t of e)n[t]=xt();const o=function(){return n};return wt.set(t,o),n}wt.set(t,e)}function vt(){const t=Array.prototype.slice.call(arguments);if(t.length)for(const e of t)Ot.delete(e);else wt.clear()}Ot.s=function(t){Mt.push([bt,xt,St]);const e=++yt;bt=e,xt=t;const n=J(e);St=Q(n),K(n)},Ot.f=function(){V(St),function(){for(const t of L)W(t)}(),N(),vt(),[bt,xt,St]=Mt.pop()};const kt=new Map,jt=[];function Pt(t){let e=kt.get(1);e||kt.set(1,e=new Map);let n=e.get(t);return n||e.set(t,n=t()),n}exports.Shared=function({unit:e}){const n=t.useRef();if(!n.current){const t=Q(Pt(e)),o=()=>()=>V(t);n.current=o}return t.useEffect(n.current,jt),null},exports.changed=function(t,e,n,o){if(4!==arguments.length)throw new Error('Unsupported "changed" function call outside of unit "expression"');let r=!1;if(n.has(o)){const c=n.get(o);r=!(e||Object.is)(t,c),r&&n.set(o,t)}else n.set(o,t);return r},exports.effect=function(t){if(!(t&&t instanceof Function))throw new Error('Only function supported as argument for "effect" function');const e=t();e instanceof Function&&X(e)},exports.mock=Ot,exports.pending=function(t){if(t){const e=t.pending;if(!0===e||!1===e)return e}throw new Error('Function "pending" support only async unit method as agrument')},exports.shared=function(t){if(dt||mt())return Pt(t);throw new Error("`shared` function supported only in unit schema and unit tests")},exports.unit=gt,exports.unmock=vt,exports.useOwn=function(t){if(!et&&!mt())throw new Error("Unsupported useOwn outside render function");const e=Array.prototype.slice.call(arguments,1);return ut(t,0,e.length?e:0)},exports.useShared=function(t){if(!et&&!mt())throw new Error("Unsupported useShared outside render function");return ut(t,Pt)}; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.mock = exports.free = exports.use = exports.observe = exports.initial = exports.shared = exports.expression = exports.reaction = exports.sel = exports.box = exports.ssr = void 0; | ||
const react_1 = require("react"); | ||
const reactive_box_1 = require("reactive-box"); | ||
const ssr_map = new Map(); | ||
const shareds = new Map(); | ||
let initial_data; | ||
function ssr_decorator(key) { | ||
return function (constructor) { | ||
ssr_map.set(constructor, key); | ||
}; | ||
} | ||
exports.ssr = ssr_decorator; | ||
function box_decorator(_proto, key, descriptor) { | ||
const { initializer } = descriptor || {}; | ||
const applyProperty = (target) => { | ||
const [get, set] = reactive_box_1.box(initializer && initializer()); | ||
Object.defineProperty(target, key, { get, set }); | ||
}; | ||
return { | ||
get() { | ||
applyProperty(this); | ||
return this[key]; | ||
}, | ||
set(value) { | ||
applyProperty(this); | ||
this[key] = value; | ||
}, | ||
}; | ||
} | ||
exports.box = box_decorator; | ||
function sel_decorator(_proto, key, descriptor) { | ||
return { | ||
get() { | ||
const [get] = reactive_box_1.sel(descriptor.get); | ||
Object.defineProperty(this, key, { get }); | ||
return this[key]; | ||
}, | ||
}; | ||
} | ||
exports.sel = sel_decorator; | ||
function reaction(target, listener) { | ||
const [get] = reactive_box_1.sel(target); | ||
const [run, stop] = reactive_box_1.expr(get, () => { | ||
listener(run()); | ||
}); | ||
run(); | ||
return stop; | ||
} | ||
exports.reaction = reaction; | ||
function expression(body) { | ||
const [run, stop] = reactive_box_1.expr(body); | ||
run(); | ||
return stop; | ||
} | ||
exports.expression = expression; | ||
function initial(data) { | ||
initial_data = data; | ||
} | ||
exports.initial = initial; | ||
function mock(Class, mocked) { | ||
shareds.set(Class, mocked); | ||
return mocked; | ||
} | ||
exports.mock = mock; | ||
function shared(Class) { | ||
let instance = shareds.get(Class); | ||
if (!instance) { | ||
if (ssr_map.has(Class)) { | ||
const key = ssr_map.get(Class); | ||
if (initial_data && initial_data.hasOwnProperty(key)) { | ||
instance = new Class(initial_data[key]); | ||
} | ||
else { | ||
instance = new Class(); | ||
} | ||
} | ||
else { | ||
instance = new Class(); | ||
} | ||
shareds.set(Class, instance); | ||
} | ||
return instance; | ||
} | ||
exports.shared = shared; | ||
function useForceUpdate() { | ||
return react_1.useReducer(() => [], [])[1]; | ||
} | ||
function observe(Component) { | ||
return react_1.memo((props) => { | ||
const forceUpdate = useForceUpdate(); | ||
const ref = react_1.useRef(); | ||
if (!ref.current) { | ||
const [Observed, free] = reactive_box_1.expr(Component, forceUpdate); | ||
ref.current = [Observed, free]; | ||
} | ||
react_1.useEffect(() => ref.current[1], []); | ||
return ref.current[0](props); | ||
}); | ||
} | ||
exports.observe = observe; | ||
function use(Class, deps) { | ||
return react_1.useMemo(() => (deps ? new Class(...deps) : new Class()), deps || []); | ||
} | ||
exports.use = use; | ||
function free() { | ||
try { | ||
shareds.forEach(instance => { | ||
instance.destructor && instance.destructor(); | ||
}); | ||
} | ||
finally { | ||
shareds.clear(); | ||
initial_data = void 0; | ||
} | ||
} | ||
exports.free = free; | ||
//# sourceMappingURL=index.js.map |
@@ -1,6 +0,1 @@ | ||
const | ||
lib_name = process.env.REALAR_DEV ? process.cwd() : "realar", | ||
{ mock } = require(lib_name); | ||
beforeEach(() => mock.s(jest.fn)); | ||
afterEach(mock.f); | ||
afterEach(require('realar').free); |
123
package.json
{ | ||
"name": "realar", | ||
"version": "0.2.2", | ||
"version": "0.3.0", | ||
"description": "React state manager", | ||
@@ -11,29 +11,48 @@ "repository": { | ||
}, | ||
"homepage": "https://github.com/betula/realar#readme", | ||
"license": "MIT", | ||
"main": "build/index.js", | ||
"types": "build/index.d.ts", | ||
"files": [ | ||
"build", | ||
"babel", | ||
"jest" | ||
], | ||
"scripts": { | ||
"bootstrap": "npx lerna bootstrap --no-ci && npm run build", | ||
"clean": "npm run test:clean && npm run build:clean && npm run perf:clean && lerna clean --yes", | ||
"publish": "npm run test && npm run build:prod && lerna publish", | ||
"reinstall": "npm run clean && npm run bootstrap", | ||
"test": "npm run types:ts:check && npm run test:clean && npm run test:run", | ||
"test:ci": "npm run types:ts:check && npm run test:clean:ci && npm run test:run:ci", | ||
"test:run": "cross-env REALAR_DEV=true jest --runInBand", | ||
"test:run:ci": "npm run test:run -- --coverage", | ||
"test:clean": "jest --clearCache", | ||
"test:clean:ci": "npm run test:clean && rimraf coverage", | ||
"build:clean": "rimraf build", | ||
"build:lib": "rollup -c", | ||
"build": "npm run types:ts:build && npm run build:lib", | ||
"build:prod": "cross-env REALAR_BUILD_TERSER=true npm run build", | ||
"build:watch": "cross-env REALAR_DEV=true npm run build && chokidar \"lib/**\" -c \"cross-env REALAR_DEV=true npm run build\"", | ||
"lerna:clean": "lerna run clean", | ||
"perf:realar": "cd perf/realar && cross-env NODE_ENV=development parcel index.html --port 1200", | ||
"perf:mobx": "cd perf/mobx && cross-env NODE_ENV=development parcel index.html --port 1201", | ||
"perf": "npm run perf:clean && concurrently --kill-others \"npm run perf:realar\" \"npm run perf:mobx\"", | ||
"perf:clean": "rimraf perf/*/dist perf/*/.cache", | ||
"perf:realar:watch": "concurrently --kill-others \"npm run build:watch\" \"npm run perf:realar\"", | ||
"types:ts:build": "cpy lib/types/typescript.d.ts build --rename index.d.ts", | ||
"types:ts:build:watch": "npm run types:ts:build && chokidar \"lib/**/*.ts\" -c \"npm run types:ts:build\"", | ||
"types:ts:check": "cd types/typescript && tsc --noEmit" | ||
"build": "tsc", | ||
"build:watch": "tsc -w", | ||
"test": "jest", | ||
"publish": "npm run clear && npm run build && lerna publish", | ||
"format": "prettier --write src tests babel jest", | ||
"clear": "rimraf build" | ||
}, | ||
"dependencies": { | ||
"reactive-box": ">=0.5.0" | ||
}, | ||
"peerDependencies": { | ||
"react": ">=16.8.0" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "7.12.10", | ||
"@babel/plugin-proposal-class-properties": "7.12.1", | ||
"@babel/plugin-proposal-decorators": "7.12.1", | ||
"@babel/preset-env": "7.12.11", | ||
"@babel/preset-react": "7.12.10", | ||
"@babel/preset-typescript": "7.12.7", | ||
"@types/enzyme-adapter-react-16": "1.0.6", | ||
"@types/jest": "26.0.19", | ||
"@types/react": "17.0.0", | ||
"babel-jest": "26.6.3", | ||
"babel-plugin-realar": ">=0.1.1", | ||
"cross-env": "7.0.3", | ||
"enzyme": "3.11.0", | ||
"enzyme-adapter-react-16": "1.15.5", | ||
"jest": "26.6.3", | ||
"lerna": "3.22.1", | ||
"prettier": "2.2.1", | ||
"react": "17.0.1", | ||
"react-dom": "17.0.1", | ||
"rimraf": "3.0.2", | ||
"typescript": "4.1.3" | ||
}, | ||
"author": "Slava Birch <mail@betula.co> (http://betula.co)", | ||
@@ -53,43 +72,6 @@ "keywords": [ | ||
"typescript", | ||
"javascript" | ||
"javascript", | ||
"jsx", | ||
"decorator" | ||
], | ||
"main": "build/index.js", | ||
"module": "build/index.esm.js", | ||
"types": "build/index.d.ts", | ||
"files": [ | ||
"babel", | ||
"jest", | ||
"build" | ||
], | ||
"peerDependencies": { | ||
"react": ">=16.8.0" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "7.11.1", | ||
"@babel/plugin-proposal-decorators": "7.10.5", | ||
"@babel/preset-env": "7.11.0", | ||
"@babel/preset-react": "7.10.4", | ||
"@rollup/plugin-node-resolve": "8.4.0", | ||
"@types/react": "16.9.49", | ||
"babel-jest": "26.2.2", | ||
"chokidar-cli": "2.1.0", | ||
"concurrently": "5.3.0", | ||
"cpy-cli": "3.1.1", | ||
"cross-env": "7.0.2", | ||
"deasync": "0.1.20", | ||
"enzyme": "3.11.0", | ||
"enzyme-adapter-react-16": "1.15.3", | ||
"execa": "4.0.3", | ||
"jest": "26.2.2", | ||
"lerna": "3.22.1", | ||
"mobx": "5.15.5", | ||
"mobx-react": "6.2.5", | ||
"parcel": "1.12.4", | ||
"react": "16.13.1", | ||
"react-dom": "16.13.1", | ||
"rimraf": "3.0.2", | ||
"rollup": "2.23.1", | ||
"rollup-plugin-terser": "7.0.0", | ||
"typescript": "4.0.2" | ||
}, | ||
"browserslist": [ | ||
@@ -102,6 +84,11 @@ "last 2 Chrome versions" | ||
}, | ||
"alias": { | ||
"realar": "./build" | ||
"prettier": { | ||
"arrowParens": "avoid", | ||
"printWidth": 100, | ||
"singleQuote": true, | ||
"trailingComma": "es5", | ||
"tabWidth": 2, | ||
"useTabs": false | ||
}, | ||
"gitHead": "ac3917e679dc4c380c1c64c6ca22e2408cca4202" | ||
"gitHead": "3da3733c538da3d9dc5827e0d66ef5f77527f100" | ||
} |
@@ -1,6 +0,6 @@ | ||
# Realar <sup><sup>βeta</sup></sup> | ||
# Realar | ||
[![npm version](https://img.shields.io/npm/v/realar?style=flat-square)](https://www.npmjs.com/package/realar) [![typescript support](https://img.shields.io/npm/types/typescript?style=flat-square)](./lib/types/typescript.d.ts) [![npm bundle size](https://img.shields.io/bundlephobia/minzip/realar?style=flat-square)](https://bundlephobia.com/result?p=realar) [![code coverage](https://img.shields.io/coveralls/github/betula/realar?style=flat-square)](https://coveralls.io/github/betula/realar) | ||
[![npm version](https://img.shields.io/npm/v/realar?style=flat-square)](https://www.npmjs.com/package/realar) [![npm bundle size](https://img.shields.io/bundlephobia/minzip/realar@0.3.0?style=flat-square)](https://bundlephobia.com/result?p=realar@0.3.0) [![code coverage](https://img.shields.io/coveralls/github/betula/realar?style=flat-square)](https://coveralls.io/github/betula/realar) [![typescript supported](https://img.shields.io/npm/types/typescript?style=flat-square)](./src/index.ts) | ||
Reactive state manager for React. | ||
Reactive state manager for React based on [reactive-box](https://github.com/betula/reactive-box). | ||
@@ -12,31 +12,28 @@ Light, Fast, and Pretty looked :kissing_heart: | ||
```javascript | ||
import React from "react"; | ||
import axios from "axios"; | ||
import { unit, useOwn } from "realar"; | ||
import React from 'react'; | ||
import { box, sel, shared } from 'realar'; | ||
const Todos = unit({ | ||
todos: [], // Init immutable store | ||
async fetch() { | ||
const { data } = await axios.get("/api/todos"); | ||
this.todos = data; // Update immutable store | ||
}, | ||
constructor() { | ||
this.fetch(); | ||
}, | ||
// get completed() { // Cached selector | ||
// return this.todos.filter(task => task.completed); | ||
// }, | ||
}); | ||
class Counter { | ||
@box value = 0; | ||
@sel get next() { | ||
return this.value + 1; | ||
} | ||
increment = () => this.value += 1; | ||
decrement = () => this.value -= 1; | ||
} | ||
const sharedCounter = () => shared(Counter); | ||
const App = () => { | ||
// Use the own instance of Todos | ||
const { todos, fetch } = useOwn(Todos); | ||
const { value, next, increment, decrement } = sharedCounter(); | ||
if (fetch.pending) { | ||
return ( | ||
<div>Loading</div> | ||
) | ||
} | ||
return ( | ||
<ul>{todos.map(todo => <li>{todo.text}</li>)}</ul> | ||
<p> | ||
Counter: {value} (next value: {next}) | ||
<br /> | ||
<button onClick={decrement}>Prev</button> | ||
<button onClick={increment}>Next</button> | ||
</p> | ||
); | ||
@@ -46,12 +43,7 @@ }; | ||
### Documentation | ||
+ [Basic understanding](./docs/understanding/index.md) | ||
<!-- | ||
### Demos | ||
+ [Hello](https://github.com/realar-project/hello) - shared state demonstration. | ||
+ [Todos](https://github.com/realar-project/todos) - todomvc implementation. | ||
+ [Todos](https://github.com/realar-project/todos) - todomvc implementation. --> | ||
@@ -62,3 +54,3 @@ | ||
```bash | ||
npm i -P realar | ||
npm install --save realar | ||
# or | ||
@@ -68,14 +60,3 @@ yarn add realar | ||
And update your babel config: | ||
Enjoy and happy coding! | ||
```javascript | ||
// .babelrc.js | ||
module.exports = { | ||
"plugins": [ | ||
"realar/babel" | ||
] | ||
} | ||
``` | ||
Enjoy! | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
21
1
1
12664
2
8
133
59
1
+ Addedreactive-box@>=0.5.0
+ Addedreactive-box@0.9.0(transitive)