New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@automerge/automerge-repo-react-hooks

Package Overview
Dependencies
Maintainers
4
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@automerge/automerge-repo-react-hooks - npm Package Compare versions

Comparing version 1.1.4 to 1.1.5

2

dist/index.js

@@ -1,1 +0,1 @@

import T,{createContext as k,useContext as A,useState as x,useRef as U,useEffect as g,useMemo as D}from"react";const O=k(null);function b(){const t=A(O);if(!t)throw new Error("Repo was not found on RepoContext.");return t}function P(t){const[s,o]=x(),i=b(),f=t?i.find(t):null,d=U(null);return g(()=>{if(o(void 0),!f)return;d.current=f,f.doc().then(a=>{d.current===f&&o(a)}).catch(a=>console.error(a));const u=a=>o(a.doc);return f.on("change",u),()=>{f.removeListener("change",u)}},[f]),[s,(u,a)=>{f&&f.change(u,a)}]}const H=t=>{const[s,o]=x({}),[i,f]=x({}),d=b();return g(()=>{const u=(e,r)=>{r&&o(l=>({...l,[e]:r}))},a=e=>{const r=e.documentId,l=({doc:v})=>u(r,v);e.on("change",l),f(v=>({...v,[r]:l}))},n=e=>{d.find(e).off("change",i[e]),o(r=>{const{[e]:l,...v}=r;return v})};return t&&(t.filter(e=>!s[e]).forEach(e=>{const r=d.find(e);r.doc().then(l=>{u(e,l),a(r)}).catch(l=>{console.error(`Error loading document ${e} in useDocuments: `,l)})}),Object.keys(s).map(e=>e).filter(e=>!t.includes(e)).forEach(n)),()=>{Object.entries(i).forEach(([e,r])=>{d.find(e).off("change",r)})}},[t]),s},M=(t,s=!1)=>{history[s?"pushState":"replaceState"]("","","#"+t),window.dispatchEvent(new HashChangeEvent("hashchange",{newURL:window.location.origin+window.location.pathname+t,oldURL:window.location.href}))},N=()=>{const[t,s]=x(window.location.hash);return g(()=>{const o=()=>void s(window.location.hash);return window.addEventListener("hashchange",o),()=>void window.removeEventListener("hashchange",o)},[]),t},S=(t,s)=>new URLSearchParams(s.slice(1)).get(t),B=(t,s,o)=>{const i=new URLSearchParams(o.slice(1));return i.set(t,s),i.toString()},$=(t,s)=>t&&(S(t,s)||localStorage.getItem(t)),q=(t,s)=>{t&&s!==S(t,window.location.hash)&&M(B(t,s,window.location.hash)),t&&localStorage.setItem(t,s)},z=({key:t="automergeUrl",onNoDocument:s=i=>i.create(),onInvalidAutomergeUrl:o}={})=>{const i=b(),f=N(),d=D(()=>{const u=$(t,f);try{return u?i.find(u):s(i)}catch(a){if(u&&o)return o(i,a);throw a}},[f,i,s,o]);return g(()=>{d&&q(t,d.url)},[f,d]),d};function F(t){const s=b(),[o,i]=x(t?s.find(t):void 0);return g(()=>{i(t?s.find(t):void 0)},[t]),o}function R(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var L=T,J=function(t){return typeof t=="function"},K=function(t){var s=L.useState(t),o=s[0],i=s[1],f=L.useRef(o),d=L.useCallback(function(u){f.current=J(u)?u(f.current):u,i(f.current)},[]);return[o,d,f]},Q=K;const E=R(Q);var I={exports:{}};(function(t){var s=Object.prototype.hasOwnProperty,o="~";function i(){}Object.create&&(i.prototype=Object.create(null),new i().__proto__||(o=!1));function f(n,e,r){this.fn=n,this.context=e,this.once=r||!1}function d(n,e,r,l,v){if(typeof r!="function")throw new TypeError("The listener must be a function");var p=new f(r,l||n,v),h=o?o+e:e;return n._events[h]?n._events[h].fn?n._events[h]=[n._events[h],p]:n._events[h].push(p):(n._events[h]=p,n._eventsCount++),n}function u(n,e){--n._eventsCount===0?n._events=new i:delete n._events[e]}function a(){this._events=new i,this._eventsCount=0}a.prototype.eventNames=function(){var n=[],e,r;if(this._eventsCount===0)return n;for(r in e=this._events)s.call(e,r)&&n.push(o?r.slice(1):r);return Object.getOwnPropertySymbols?n.concat(Object.getOwnPropertySymbols(e)):n},a.prototype.listeners=function(n){var e=o?o+n:n,r=this._events[e];if(!r)return[];if(r.fn)return[r.fn];for(var l=0,v=r.length,p=new Array(v);l<v;l++)p[l]=r[l].fn;return p},a.prototype.listenerCount=function(n){var e=o?o+n:n,r=this._events[e];return r?r.fn?1:r.length:0},a.prototype.emit=function(n,e,r,l,v,p){var h=o?o+n:n;if(!this._events[h])return!1;var c=this._events[h],m=arguments.length,y,w;if(c.fn){switch(c.once&&this.removeListener(n,c.fn,void 0,!0),m){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,e),!0;case 3:return c.fn.call(c.context,e,r),!0;case 4:return c.fn.call(c.context,e,r,l),!0;case 5:return c.fn.call(c.context,e,r,l,v),!0;case 6:return c.fn.call(c.context,e,r,l,v,p),!0}for(w=1,y=new Array(m-1);w<m;w++)y[w-1]=arguments[w];c.fn.apply(c.context,y)}else{var j=c.length,_;for(w=0;w<j;w++)switch(c[w].once&&this.removeListener(n,c[w].fn,void 0,!0),m){case 1:c[w].fn.call(c[w].context);break;case 2:c[w].fn.call(c[w].context,e);break;case 3:c[w].fn.call(c[w].context,e,r);break;case 4:c[w].fn.call(c[w].context,e,r,l);break;default:if(!y)for(_=1,y=new Array(m-1);_<m;_++)y[_-1]=arguments[_];c[w].fn.apply(c[w].context,y)}}return!0},a.prototype.on=function(n,e,r){return d(this,n,e,r,!1)},a.prototype.once=function(n,e,r){return d(this,n,e,r,!0)},a.prototype.removeListener=function(n,e,r,l){var v=o?o+n:n;if(!this._events[v])return this;if(!e)return u(this,v),this;var p=this._events[v];if(p.fn)p.fn===e&&(!l||p.once)&&(!r||p.context===r)&&u(this,v);else{for(var h=0,c=[],m=p.length;h<m;h++)(p[h].fn!==e||l&&!p[h].once||r&&p[h].context!==r)&&c.push(p[h]);c.length?this._events[v]=c.length===1?c[0]:c:u(this,v)}return this},a.prototype.removeAllListeners=function(n){var e;return n?(e=o?o+n:n,this._events[e]&&u(this,e)):(this._events=new i,this._eventsCount=0),this},a.prototype.off=a.prototype.removeListener,a.prototype.addListener=a.prototype.on,a.prefixed=o,a.EventEmitter=a,t.exports=a})(I);var V=I.exports;const W=R(V),C=new W,X=({handle:t,localUserId:s,offlineTimeout:o=3e4,getTime:i=()=>new Date().getTime()})=>{const[f,d,u]=E({}),[a,n,e]=E({});return g(()=>{const r=p=>{const[h,c]=p.message;h!==s&&(e.current[h]||C.emit("new_peer",p),d({...u.current,[h]:c}),n({...e.current,[h]:i()}))},l=()=>{const p=u.current,h=e.current,c=i();for(const m in h)c-h[m]>o&&(delete p[m],delete h[m]);d(p),n(h)};t.on("ephemeral-message",r);const v=setInterval(l,o);return()=>{t.removeListener("ephemeral-message",r),clearInterval(v)}},[t,s,o,i]),[f,a]},Y=({handle:t,userId:s,initialState:o,heartbeatTime:i=15e3})=>{const[f,d,u]=E(o),a=n=>{const e=typeof n=="function"?n(u.current):n;d(e),t.broadcast([s,e])};return g(()=>{if(!s)return;const n=()=>void t.broadcast([s,u.current]);n();const e=setInterval(n,i);return()=>void clearInterval(e)},[t,s,i]),g(()=>{let n;const e=C.on("new_peer",()=>{n=setTimeout(()=>t.broadcast([s,u.current]),500)});return()=>{e.off("new_peer"),n&&clearTimeout(n)}},[t,s,C]),[f,a]};export{O as RepoContext,z as useBootstrap,P as useDocument,H as useDocuments,F as useHandle,Y as useLocalAwareness,X as useRemoteAwareness,b as useRepo};
import T,{createContext as k,useContext as A,useRef as U,useState as x,useEffect as g,useMemo as D}from"react";const C=k(null);function L(){const n=A(C);if(!n)throw new Error("Repo was not found on RepoContext.");return n}function P(n){const s=L(),r=n?s.find(n):null,i=U(null),[m,v]=x(()=>r==null?void 0:r.docSync());return g(()=>{if(v(r==null?void 0:r.docSync()),!r)return;i.current=r,r.doc().then(e=>{i.current===r&&v(e)}).catch(e=>console.error(e));const p=e=>v(e.doc);r.on("change",p);const l=()=>v(void 0);return r.on("delete",l),()=>{r.removeListener("change",p),r.removeListener("delete",l)}},[r]),[m,(p,l)=>{r&&r.change(p,l)}]}const H=n=>{const[s,r]=x({}),[i,m]=x({}),v=L();return g(()=>{const p=(t,a)=>{a&&r(f=>({...f,[t]:a}))},l=t=>{r(a=>{const{[t]:f,...u}=a;return u})},e=t=>{const a=t.documentId,f={change:({doc:u})=>p(a,u),delete:()=>l(a)};t.on("change",f.change),t.on("delete",f.delete),m(u=>({...u,[a]:u}))},o=t=>{const a=v.find(t);a.off("change",i[t].change),a.off("delete",i[t].delete),r(f=>{const{[t]:u,...h}=f;return h})};return n&&(n.filter(t=>!s[t]).forEach(t=>{const a=v.find(t);a.doc().then(f=>{p(t,f),e(a)}).catch(f=>{console.error(`Error loading document ${t} in useDocuments: `,f)})}),Object.keys(s).map(t=>t).filter(t=>!n.includes(t)).forEach(o)),()=>{Object.entries(i).forEach(([t,a])=>{const f=v.find(t);f.off("change",a.change),f.off("delete",a.delete)})}},[n]),s},M=(n,s=!1)=>{history[s?"pushState":"replaceState"]("","","#"+n),window.dispatchEvent(new HashChangeEvent("hashchange",{newURL:window.location.origin+window.location.pathname+n,oldURL:window.location.href}))},N=()=>{const[n,s]=x(window.location.hash);return g(()=>{const r=()=>void s(window.location.hash);return window.addEventListener("hashchange",r),()=>void window.removeEventListener("hashchange",r)},[]),n},O=(n,s)=>new URLSearchParams(s.slice(1)).get(n),B=(n,s,r)=>{const i=new URLSearchParams(r.slice(1));return i.set(n,s),i.toString()},$=(n,s)=>n&&(O(n,s)||localStorage.getItem(n)),q=(n,s)=>{n&&s!==O(n,window.location.hash)&&M(B(n,s,window.location.hash)),n&&localStorage.setItem(n,s)},z=({key:n="automergeUrl",onNoDocument:s=i=>i.create(),onInvalidAutomergeUrl:r}={})=>{const i=L(),m=N(),v=D(()=>{const p=$(n,m);try{return p?i.find(p):s(i)}catch(l){if(p&&r)return r(i,l);throw l}},[m,i,s,r]);return g(()=>{v&&q(n,v.url)},[m,v]),v};function F(n){const s=L(),[r,i]=x(n?s.find(n):void 0);return g(()=>{i(n?s.find(n):void 0)},[n]),r}function R(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var b=T,J=function(n){return typeof n=="function"},K=function(n){var s=b.useState(n),r=s[0],i=s[1],m=b.useRef(r),v=b.useCallback(function(p){m.current=J(p)?p(m.current):p,i(m.current)},[]);return[r,v,m]},Q=K;const S=R(Q);var I={exports:{}};(function(n){var s=Object.prototype.hasOwnProperty,r="~";function i(){}Object.create&&(i.prototype=Object.create(null),new i().__proto__||(r=!1));function m(e,o,t){this.fn=e,this.context=o,this.once=t||!1}function v(e,o,t,a,f){if(typeof t!="function")throw new TypeError("The listener must be a function");var u=new m(t,a||e,f),h=r?r+o:o;return e._events[h]?e._events[h].fn?e._events[h]=[e._events[h],u]:e._events[h].push(u):(e._events[h]=u,e._eventsCount++),e}function p(e,o){--e._eventsCount===0?e._events=new i:delete e._events[o]}function l(){this._events=new i,this._eventsCount=0}l.prototype.eventNames=function(){var e=[],o,t;if(this._eventsCount===0)return e;for(t in o=this._events)s.call(o,t)&&e.push(r?t.slice(1):t);return Object.getOwnPropertySymbols?e.concat(Object.getOwnPropertySymbols(o)):e},l.prototype.listeners=function(e){var o=r?r+e:e,t=this._events[o];if(!t)return[];if(t.fn)return[t.fn];for(var a=0,f=t.length,u=new Array(f);a<f;a++)u[a]=t[a].fn;return u},l.prototype.listenerCount=function(e){var o=r?r+e:e,t=this._events[o];return t?t.fn?1:t.length:0},l.prototype.emit=function(e,o,t,a,f,u){var h=r?r+e:e;if(!this._events[h])return!1;var c=this._events[h],w=arguments.length,y,d;if(c.fn){switch(c.once&&this.removeListener(e,c.fn,void 0,!0),w){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,o),!0;case 3:return c.fn.call(c.context,o,t),!0;case 4:return c.fn.call(c.context,o,t,a),!0;case 5:return c.fn.call(c.context,o,t,a,f),!0;case 6:return c.fn.call(c.context,o,t,a,f,u),!0}for(d=1,y=new Array(w-1);d<w;d++)y[d-1]=arguments[d];c.fn.apply(c.context,y)}else{var j=c.length,_;for(d=0;d<j;d++)switch(c[d].once&&this.removeListener(e,c[d].fn,void 0,!0),w){case 1:c[d].fn.call(c[d].context);break;case 2:c[d].fn.call(c[d].context,o);break;case 3:c[d].fn.call(c[d].context,o,t);break;case 4:c[d].fn.call(c[d].context,o,t,a);break;default:if(!y)for(_=1,y=new Array(w-1);_<w;_++)y[_-1]=arguments[_];c[d].fn.apply(c[d].context,y)}}return!0},l.prototype.on=function(e,o,t){return v(this,e,o,t,!1)},l.prototype.once=function(e,o,t){return v(this,e,o,t,!0)},l.prototype.removeListener=function(e,o,t,a){var f=r?r+e:e;if(!this._events[f])return this;if(!o)return p(this,f),this;var u=this._events[f];if(u.fn)u.fn===o&&(!a||u.once)&&(!t||u.context===t)&&p(this,f);else{for(var h=0,c=[],w=u.length;h<w;h++)(u[h].fn!==o||a&&!u[h].once||t&&u[h].context!==t)&&c.push(u[h]);c.length?this._events[f]=c.length===1?c[0]:c:p(this,f)}return this},l.prototype.removeAllListeners=function(e){var o;return e?(o=r?r+e:e,this._events[o]&&p(this,o)):(this._events=new i,this._eventsCount=0),this},l.prototype.off=l.prototype.removeListener,l.prototype.addListener=l.prototype.on,l.prefixed=r,l.EventEmitter=l,n.exports=l})(I);var V=I.exports;const W=R(V),E=new W,X=({handle:n,localUserId:s,offlineTimeout:r=3e4,getTime:i=()=>new Date().getTime()})=>{const[m,v,p]=S({}),[l,e,o]=S({});return g(()=>{const t=u=>{const[h,c]=u.message;h!==s&&(o.current[h]||E.emit("new_peer",u),v({...p.current,[h]:c}),e({...o.current,[h]:i()}))},a=()=>{const u=p.current,h=o.current,c=i();for(const w in h)c-h[w]>r&&(delete u[w],delete h[w]);v(u),e(h)};n.on("ephemeral-message",t);const f=setInterval(a,r);return()=>{n.removeListener("ephemeral-message",t),clearInterval(f)}},[n,s,r,i]),[m,l]},Y=({handle:n,userId:s,initialState:r,heartbeatTime:i=15e3})=>{const[m,v,p]=S(r),l=e=>{const o=typeof e=="function"?e(p.current):e;v(o),n.broadcast([s,o])};return g(()=>{if(!s)return;const e=()=>void n.broadcast([s,p.current]);e();const o=setInterval(e,i);return()=>void clearInterval(o)},[n,s,i]),g(()=>{let e;const o=E.on("new_peer",()=>{e=setTimeout(()=>n.broadcast([s,p.current]),500)});return()=>{o.off("new_peer"),e&&clearTimeout(e)}},[n,s,E]),[m,l]};export{C as RepoContext,z as useBootstrap,P as useDocument,H as useDocuments,F as useHandle,Y as useLocalAwareness,X as useRemoteAwareness,L as useRepo};
{
"name": "@automerge/automerge-repo-react-hooks",
"version": "1.1.4",
"version": "1.1.5",
"description": "Hooks to access an Automerge Repo from your react app.",

@@ -18,3 +18,3 @@ "repository": "https://github.com/automerge/automerge-repo/tree/master/packages/automerge-repo-react-hooks",

"@automerge/automerge": "^2.1.9",
"@automerge/automerge-repo": "1.1.4",
"@automerge/automerge-repo": "1.1.5",
"eventemitter3": "^5.0.1",

@@ -46,3 +46,3 @@ "react": "^18.2.0",

},
"gitHead": "e819a7ed6302ce34f372b119ea3e8bab052e3af6"
"gitHead": "64edfaea5e53e77cd9158fc1df52fea85801db71"
}

@@ -6,2 +6,3 @@ # React Hooks for Automerge Repo

#### [useBootstrap](./src/useBootstrap.ts)
This hook is used to load a document based on the URL hash, for example `//myapp/#documentId=[document ID]`.

@@ -11,4 +12,5 @@ It can also load the document ID from localStorage, or create a new document if none is specified.

#### [useLocalAwareness](./src/useLocalAwareness.ts) & [useRemoteAwareness](./src/useRemoteAwareness.ts)
These hooks implement ephemeral awareness/presence, similar to [Yjs Awareness](https://docs.yjs.dev/getting-started/adding-awareness).
They allow temporary state to be shared, such as cursor positions or peer online/offline status.
They allow temporary state to be shared, such as cursor positions or peer online/offline status.

@@ -18,2 +20,3 @@ Ephemeral messages are replicated between peers, but not saved to the Automerge doc, and are used for temporary updates that will be discarded.

#### [useRepo/RepoContext](./src/useRepo.ts)
Use RepoContext to set up react context for an Automerge repo.

@@ -24,5 +27,7 @@ Use useRepo to lookup the repo from context.

#### [useDocument](./src/useDocument.ts)
Return a document & updater fn, by ID.
#### [useHandle](./src/useHandle.ts)
Return a handle, by ID.

@@ -53,5 +58,3 @@

return await Repo({
network: [
new BroadcastChannelNetworkAdapter(),
],
network: [new BroadcastChannelNetworkAdapter()],
sharePolicy: peerId => peerId.includes("shared-worker"),

@@ -58,0 +61,0 @@ })

@@ -19,3 +19,2 @@ import {

export function useDocument<T>(id?: AnyDocumentId) {
const [doc, setDoc] = useState<Doc<T>>()
const repo = useRepo()

@@ -26,7 +25,11 @@

const [doc, setDoc] = useState<Doc<T> | undefined>(() => handle?.docSync())
useEffect(() => {
// When the handle has changed, reset the doc to an empty state.
// When the handle has changed, reset the doc to the current value of docSync().
// For already-loaded documents this will be the last known value, for unloaded documents
// this will be undefined.
// This ensures that if loading the doc takes a long time, the UI
// shows a loading state during that time rather than a stale doc.
setDoc(undefined)
setDoc(handle?.docSync())

@@ -49,4 +52,7 @@ if (!handle) return

handle.on("change", onChange)
const onDelete = () => setDoc(undefined)
handle.on("delete", onDelete)
const cleanup = () => {
handle.removeListener("change", onChange)
handle.removeListener("delete", onDelete)
}

@@ -53,0 +59,0 @@

@@ -5,2 +5,3 @@ import {

DocHandleChangePayload,
DocHandleDeletePayload,
DocumentId,

@@ -17,3 +18,3 @@ } from "@automerge/automerge-repo"

const [documents, setDocuments] = useState({} as Record<DocId, T>)
const [listeners, setListeners] = useState({} as Record<DocId, Listener<T>>)
const [listeners, setListeners] = useState({} as Record<DocId, Listeners<T>>)
const repo = useRepo()

@@ -26,2 +27,10 @@

}
const updateDocumentDeleted = (id: DocId) => {
// (don't remove listeners)
// remove the document from the document map
setDocuments(docs => {
const { [id]: _removedDoc, ...remainingDocs } = docs
return remainingDocs
})
}

@@ -32,7 +41,11 @@ const addListener = (handle: DocHandle<T>) => {

// whenever a document changes, update our map
const listener: Listener<T> = ({ doc }) => updateDocument(id, doc)
handle.on("change", listener)
const listeners: Listeners<T> = {
change: ({ doc }) => updateDocument(id, doc),
delete: () => updateDocumentDeleted(id),
}
handle.on("change", listeners.change)
handle.on("delete", listeners.delete)
// store the listener so we can remove it later
setListeners(listeners => ({ ...listeners, [id]: listener }))
setListeners(listeners => ({ ...listeners, [id]: listeners }))
}

@@ -43,3 +56,4 @@

const handle = repo.find<T>(id)
handle.off("change", listeners[id])
handle.off("change", listeners[id].change)
handle.off("delete", listeners[id].delete)

@@ -59,8 +73,14 @@ // remove the document from the document map

// As each document loads, update our map
handle.doc().then(doc => {
updateDocument(id, doc)
addListener(handle)
}).catch(err => {
console.error(`Error loading document ${id} in useDocuments: `, err)
})
handle
.doc()
.then(doc => {
updateDocument(id, doc)
addListener(handle)
})
.catch(err => {
console.error(
`Error loading document ${id} in useDocuments: `,
err
)
})
})

@@ -77,5 +97,6 @@

const teardown = () => {
Object.entries(listeners).forEach(([id, listener]) => {
Object.entries(listeners).forEach(([id, listeners]) => {
const handle = repo.find<T>(id as DocId)
handle.off("change", listener)
handle.off("change", listeners.change)
handle.off("delete", listeners.delete)
})

@@ -93,2 +114,4 @@ }

type DocId = DocumentId | AutomergeUrl
type Listener<T> = (p: DocHandleChangePayload<T>) => void
type ChangeListener<T> = (p: DocHandleChangePayload<T>) => void
type DeleteListener<T> = (p: DocHandleDeletePayload<T>) => void
type Listeners<T> = { change: ChangeListener<T>, delete: DeleteListener<T> }

@@ -0,0 +0,0 @@ import { useEffect } from "react"

@@ -15,5 +15,3 @@ {

},
"include": [
"src/**/*.ts"
]
}
"include": ["src/**/*.ts"]
}

@@ -21,15 +21,15 @@ import { defineConfig } from "vitest/config"

lib: {
entry: resolve(__dirname, 'src/index.ts'),
formats: ['es'],
fileName: 'index',
entry: resolve(__dirname, "src/index.ts"),
formats: ["es"],
fileName: "index",
},
rollupOptions: {
external: ['react', 'react/jsx-runtime', 'react-dom', 'tailwindcss'],
external: ["react", "react/jsx-runtime", "react-dom", "tailwindcss"],
output: {
globals: {
react: 'React',
'react/jsx-runtime': 'react/jsx-runtime',
'react-dom': 'ReactDOM',
}
}
react: "React",
"react/jsx-runtime": "react/jsx-runtime",
"react-dom": "ReactDOM",
},
},
},

@@ -39,3 +39,3 @@ },

plugins: [wasm(), topLevelAwait()],
}
},
})

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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