Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

realar

Package Overview
Dependencies
Maintainers
1
Versions
129
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

realar - npm Package Compare versions

Comparing version 0.2.2 to 0.3.0

build/index.js.map

2

babel/index.js

@@ -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);
{
"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!
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc