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

@verygoodgraphics/vgg-wasm

Package Overview
Dependencies
Maintainers
3
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@verygoodgraphics/vgg-wasm - npm Package Compare versions

Comparing version 0.1.20 to 0.1.21

2

dist/index.d.ts

@@ -134,2 +134,3 @@ declare type CallbackHandlers = {

get currentFrameId(): string | undefined;
getFontsInUse(): any;
}

@@ -188,2 +189,3 @@

currentFrameId(): string;
requiredFonts(): string;
setFitToViewportEnabled(enabled: boolean): void;

@@ -190,0 +192,0 @@ setContentMode(mode: "topLeft" | "scaleAspectFill" | "scaleAspectFit" | "scaleAspectFillTopCenter"): void;

4

dist/vgg-wasm.iife.js

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

var vggWasm=function(d){"use strict";var b=Object.defineProperty;var k=(d,o,c)=>o in d?b(d,o,{enumerable:!0,configurable:!0,writable:!0,value:c}):d[o]=c;var a=(d,o,c)=>(k(d,typeof o!="symbol"?o+"":o,c),c);var o=(r=>(r.Load="load",r.FirstRender="firstrender",r.LoadError="loaderror",r.StateChange="statechange",r.Click="click",r))(o||{}),c=(r=>(r.Loading="loading",r.Ready="ready",r.Rendered="rendered",r.Error="error",r.Destroyed="destroyed",r))(c||{}),h=(r=>(r.StartLoading="Start loading",r.DownloadVGGRuntimeJS="Download VGG Runtime JS",r.CreateVGGWasmInstance="Create VGG Wasm Instance",r.VGGWasmInstanceReady="VGG Wasm Instance Ready",r.DownloadSourceFile="Download Source File",r.LoadSourceFile="Load Source File",r))(h||{});class v{constructor(e=[]){this.listeners=e}getListeners(e){return this.listeners.filter(t=>t.type===e)}add(e){this.listeners.includes(e)||this.listeners.push(e)}remove(e){for(let t=0;t<this.listeners.length;t++){const s=this.listeners[t];if(s.type===e.type&&s.callback===e.callback){this.listeners.splice(t,1);break}}}removeAll(e){e?this.listeners.filter(t=>t.type===e).forEach(t=>this.remove(t)):this.listeners.splice(0,this.listeners.length)}fire(e,t){this.getListeners(e.type).forEach(n=>n.callback(e,t))}}const w=(r=21)=>crypto.getRandomValues(new Uint8Array(r)).reduce((e,t)=>e+=(t&=63)<36?t.toString(36):t<62?(t-26).toString(36).toUpperCase():t>62?"-":"_","");class S{constructor(e,t){a(this,"selector");a(this,"vggSdk");this.selector=e,this.vggSdk=t}on(e,t){return this.addEventListener(this.selector,e,t),this}update(e){if(!this.vggSdk)throw new Error("VGG SDK not ready");this.vggSdk.updateElement(this.selector,e)}addEventListener(e,t,s){if(!this.vggSdk)throw new Error("VGG SDK not ready");const n=m=>s(this,m),i=w(7),l=`export default (event, opts) => {
var vggWasm=function(d){"use strict";var b=Object.defineProperty;var F=(d,o,c)=>o in d?b(d,o,{enumerable:!0,configurable:!0,writable:!0,value:c}):d[o]=c;var a=(d,o,c)=>(F(d,typeof o!="symbol"?o+"":o,c),c);var o=(r=>(r.Load="load",r.FirstRender="firstrender",r.LoadError="loaderror",r.StateChange="statechange",r.Click="click",r))(o||{}),c=(r=>(r.Loading="loading",r.Ready="ready",r.Rendered="rendered",r.Error="error",r.Destroyed="destroyed",r))(c||{}),h=(r=>(r.StartLoading="Start loading",r.DownloadVGGRuntimeJS="Download VGG Runtime JS",r.CreateVGGWasmInstance="Create VGG Wasm Instance",r.VGGWasmInstanceReady="VGG Wasm Instance Ready",r.DownloadSourceFile="Download Source File",r.LoadSourceFile="Load Source File",r))(h||{});class v{constructor(e=[]){this.listeners=e}getListeners(e){return this.listeners.filter(t=>t.type===e)}add(e){this.listeners.includes(e)||this.listeners.push(e)}remove(e){for(let t=0;t<this.listeners.length;t++){const s=this.listeners[t];if(s.type===e.type&&s.callback===e.callback){this.listeners.splice(t,1);break}}}removeAll(e){e?this.listeners.filter(t=>t.type===e).forEach(t=>this.remove(t)):this.listeners.splice(0,this.listeners.length)}fire(e,t){this.getListeners(e.type).forEach(n=>n.callback(e,t))}}const w=(r=21)=>crypto.getRandomValues(new Uint8Array(r)).reduce((e,t)=>e+=(t&=63)<36?t.toString(36):t<62?(t-26).toString(36).toUpperCase():t>62?"-":"_","");class S{constructor(e,t){a(this,"selector");a(this,"vggSdk");this.selector=e,this.vggSdk=t}on(e,t){return this.addEventListener(this.selector,e,t),this}update(e){if(!this.vggSdk)throw new Error("VGG SDK not ready");this.vggSdk.updateElement(this.selector,e)}addEventListener(e,t,s){if(!this.vggSdk)throw new Error("VGG SDK not ready");const n=m=>s(this,m),i=w(7),l=`export default (event, opts) => {
const sdk = new opts.instance.VggSdk()

@@ -25,2 +25,2 @@

}
}`;this.vggSdk.addEventListener(e,t,l);const g=globalThis.vggInstances[this.vggSdk.getEnv()];if(g)try{g.listeners.set(i,n)}catch(m){console.error(m)}return{selector:e,removeEventListener:()=>{this.vggSdk.removeEventListener(e,t,l),g.listeners.delete(i)}}}}class y{constructor(e){this.debug=e}logEvent(e){this.debug&&console.log(`%cVGGEvent::${e.type}`,"background: #f59e0b; color: #78350f; font-weight: bold; border-radius: 2px; padding: 0 2.5px;",e.id?`${e.id} → ${e.path}`:"")}logLifeCycle(e){this.debug&&console.log(`%cVGGLifeCycle::${e.phase}`,"background: #f59e0b; color: #78350f; font-weight: bold; border-radius: 2px; padding: 0 2.5px;",e.status)}}const f=class f{constructor(e){a(this,"props");a(this,"defaultRuntime","https://s5.vgg.cool/runtime/latest");a(this,"canvas");a(this,"width",0);a(this,"height",0);a(this,"editMode",!1);a(this,"disableLoader",!1);a(this,"verbose");a(this,"src");a(this,"runtime");a(this,"vggInstanceKey","");a(this,"eventManager");a(this,"state",c.Loading);a(this,"onLoadingStateUpdate");a(this,"vggWasmInstance",null);a(this,"vggSdk",null);a(this,"customFonts",[]);a(this,"observables",new Map);a(this,"checkStateFrame",0);a(this,"logger");var t,s;this.props=e,this.canvas=e.canvas,this.src=e.src,this.runtime=e.runtime||this.defaultRuntime,this.width=((t=this.canvas)==null?void 0:t.width)??0,this.height=((s=this.canvas)==null?void 0:s.height)??0,this.customFonts=e.customFonts??[],this.editMode=e.editMode??!1,this.verbose=e.verbose??!1,this.logger=new y(this.verbose),this.disableLoader=e.disableLoader??!1,this.onLoadingStateUpdate=e.onLoadingStateUpdate??(()=>{}),this.eventManager=new v,e.onLoad&&this.on("load",e.onLoad),e.onLoadError&&this.on("loaderror",e.onLoadError),e.onRendered&&this.on("firstrender",e.onRendered),e.onStateChange&&this.on("statechange",e.onStateChange),e.onSelect&&this.on("click",e.onSelect)}async load(){try{this.updateLoader(h.StartLoading),await this.init({...this.props})}catch(e){this.eventManager.fire({type:"loaderror",data:e.message})}}updateLoader(e){var t;this.disableLoader||(t=this.onLoadingStateUpdate)==null||t.call(this,e)}async init({src:e}){if(this.updateLoader(h.DownloadVGGRuntimeJS),this.src=e,Array.from(document.scripts).some(s=>s.src.includes("vgg_runtime.js"))||await this.loadScript(this.runtime+"/vgg_runtime.js"),await new Promise(s=>{const n=setInterval(()=>{window._vgg_createWasmInstance&&(clearInterval(n),s(!0))},100)}),!this.canvas)throw new Error("Canvas element required");if(!this.src)throw new Error(f.missingErrorMessage);await new Promise(t=>{this.checkStateFrame=requestAnimationFrame(()=>this.checkState(t))}),console.log("VGG SDK ready",this.vggSdk),await this.loadFonts(),this.logger.logLifeCycle({phase:"init",status:"end"})}async createVggWasmInstance(){const e=this.runtime;try{const t=setTimeout(()=>{throw new Error("VGG Wasm instance creation timeout")},3e4),s=await window._vgg_createWasmInstance({noInitialRun:!0,canvas:this.canvas,locateFile:function(n,i){return n.endsWith(".data")?e+"/"+n:i+n}});return clearTimeout(t),s}catch(t){return console.error(t),null}}async checkState(e){if(this.updateLoader(h.CreateVGGWasmInstance),window._vgg_createWasmInstance){const t=await this.createVggWasmInstance();if(t){this.vggWasmInstance=t;try{this.vggWasmInstance.ccall("emscripten_main","void",["number","number","boolean"],[this.width,this.height,this.editMode])}catch(n){console.error(n)}this.vggSdk=new t.VggSdk;const s=globalThis.vggInstances??{};this.vggInstanceKey=this.vggSdk.getEnv(),this.editMode?Object.assign(s,{[this.vggInstanceKey]:{instance:t,listener:n=>{try{const i=JSON.parse(n);this.logger.logEvent(i),i.type==="select"?this.eventManager.fire({type:o.Click,data:i}):i.type==="firstRender"&&(this.state=c.Rendered,this.eventManager.fire({type:o.FirstRender}))}catch(i){console.error(i)}}}}):Object.assign(s,{[this.vggInstanceKey]:{instance:t,listeners:new Map,listener:n=>{try{JSON.parse(n).type==="firstRender"&&(this.state=c.Rendered,this.eventManager.fire({type:o.FirstRender}))}catch(i){console.error(i)}}}}),globalThis.vggInstances=s,this.state=c.Ready,this.eventManager.fire({type:o.Load})}else this.state=c.Error,this.eventManager.fire({type:o.LoadError});cancelAnimationFrame(this.checkStateFrame),e(!0),this.updateLoader(h.VGGWasmInstanceReady)}else this.checkStateFrame=requestAnimationFrame(()=>this.checkState(e))}async loadScript(e){const t=document.createElement("script");return t.src=e,document.head.appendChild(t),new Promise(s=>{t.onload=()=>{s(!0)}})}async loadFonts(){const e=this.customFonts;for(const t of e)await fetch(t).then(s=>{if(s.ok)return s.arrayBuffer();throw new Error(s.statusText)}).then(s=>{var l;const n=new Uint8Array(s),i=((l=t.split("/").pop())==null?void 0:l.split(".")[0])??"";this.loadFontFile(n,i)}).catch(s=>{console.error(`Failed to add font: ${s.message}`)})}loadFontFile(e,t){if(!this.vggSdk)throw new Error("VGG SDK not ready");if(!this.vggSdk.addFont(e,t))throw new Error("add font failed!")}on(e,t){return this.eventManager.add({type:e,callback:t}),this}async render(e,t){if(this.width=(t==null?void 0:t.width)??this.width,this.height=(t==null?void 0:t.height)??this.height,this.editMode=(t==null?void 0:t.editMode)??this.editMode,!this.vggWasmInstance)throw new Error("VGG Wasm instance not ready");const s=e??this.src;let n;if(typeof s=="string"){this.updateLoader(h.DownloadSourceFile);const l=await fetch(s);if(!l.ok)throw new Error("Failed to fetch Daruma file");const g=await l.arrayBuffer();n=new Int8Array(g)}else if(s instanceof Int8Array)n=s;else throw new Error("Invalid source file");if(this.updateLoader(h.LoadSourceFile),!this.vggWasmInstance)return;if(!this.vggWasmInstance.ccall("load_file_from_mem","boolean",["string","array","number"],["name",n,n.length]))throw new Error("Failed to load Daruma file")}$(e){if(!this.vggSdk)throw new Error("VGG SDK not ready");const t=this.observables.get(e);if(!t){const s=new S(String(e),this.vggSdk);return this.observables.set(e,s),s}return t}destroy(){var t;try{(t=this.vggWasmInstance)==null||t._vggExit()}catch{}const e=globalThis.vggInstances??{};return delete e[this.vggInstanceKey],this.eventManager.removeAll(),this.vggWasmInstance=null,this.src="",this.vggSdk=null,this.state=c.Destroyed,this.logger.logLifeCycle({phase:"destroy",status:"end"}),this.observables.clear(),this}getTextContent(){var t;return((t=this.vggSdk)==null?void 0:t.texts())??[]}snapshot(e={type:"png",quality:100}){var s;return(s=this.vggSdk)==null?void 0:s.makeImageSnapshot(e)}setContentMode(e="fit"){if(!this.vggSdk)throw new Error("VGG SDK not ready");if(e==="original")this.vggSdk.setContentMode("topLeft");else if(e==="fit")this.vggSdk.setContentMode("scaleAspectFit");else if(e==="fill")this.vggSdk.setContentMode("scaleAspectFill");else if(e==="autoFill")this.vggSdk.setContentMode("scaleAspectFillTopCenter");else throw new Error("Invalid content mode")}setFitToViewportEnabled(e){var t;(t=this.vggSdk)==null||t.setFitToViewportEnabled(e)}getAllFrames(){var t;const e=(t=this.vggSdk)==null?void 0:t.getFramesInfo();return e?JSON.parse(e):[]}setCurrentFrame(e,t=!0){var s;(s=this.vggSdk)==null||s.setCurrentFrameById(e,t)}nextFrame(){const e=this.getAllFrames(),s=(e.findIndex(n=>n.id===this.currentFrameId)+1)%e.length;this.setCurrentFrame(e[s].id)}prevFrame(){const e=this.getAllFrames(),s=(e.findIndex(n=>n.id===this.currentFrameId)-1+e.length)%e.length;this.setCurrentFrame(e[s].id)}get currentFrameId(){var e;return(e=this.vggSdk)==null?void 0:e.currentFrameId()}};a(f,"missingErrorMessage","Daruma source file required");let u=f;return typeof globalThis<"u"&&(globalThis.VGG=u),d.EventType=o,d.State=c,d.VGG=u,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"}),d}({});
}`;this.vggSdk.addEventListener(e,t,l);const g=globalThis.vggInstances[this.vggSdk.getEnv()];if(g)try{g.listeners.set(i,n)}catch(m){console.error(m)}return{selector:e,removeEventListener:()=>{this.vggSdk.removeEventListener(e,t,l),g.listeners.delete(i)}}}}class y{constructor(e){this.debug=e}logEvent(e){this.debug&&console.log(`%cVGGEvent::${e.type}`,"background: #f59e0b; color: #78350f; font-weight: bold; border-radius: 2px; padding: 0 2.5px;",e.id?`${e.id} → ${e.path}`:"")}logLifeCycle(e){this.debug&&console.log(`%cVGGLifeCycle::${e.phase}`,"background: #f59e0b; color: #78350f; font-weight: bold; border-radius: 2px; padding: 0 2.5px;",e.status)}}const f=class f{constructor(e){a(this,"props");a(this,"defaultRuntime","https://s5.vgg.cool/runtime/latest");a(this,"canvas");a(this,"width",0);a(this,"height",0);a(this,"editMode",!1);a(this,"disableLoader",!1);a(this,"verbose");a(this,"src");a(this,"runtime");a(this,"vggInstanceKey","");a(this,"eventManager");a(this,"state",c.Loading);a(this,"onLoadingStateUpdate");a(this,"vggWasmInstance",null);a(this,"vggSdk",null);a(this,"customFonts",[]);a(this,"observables",new Map);a(this,"checkStateFrame",0);a(this,"logger");var t,s;this.props=e,this.canvas=e.canvas,this.src=e.src,this.runtime=e.runtime||this.defaultRuntime,this.width=((t=this.canvas)==null?void 0:t.width)??0,this.height=((s=this.canvas)==null?void 0:s.height)??0,this.customFonts=e.customFonts??[],this.editMode=e.editMode??!1,this.verbose=e.verbose??!1,this.logger=new y(this.verbose),this.disableLoader=e.disableLoader??!1,this.onLoadingStateUpdate=e.onLoadingStateUpdate??(()=>{}),this.eventManager=new v,e.onLoad&&this.on("load",e.onLoad),e.onLoadError&&this.on("loaderror",e.onLoadError),e.onRendered&&this.on("firstrender",e.onRendered),e.onStateChange&&this.on("statechange",e.onStateChange),e.onSelect&&this.on("click",e.onSelect)}async load(){try{this.updateLoader(h.StartLoading),await this.init({...this.props})}catch(e){this.eventManager.fire({type:"loaderror",data:e.message})}}updateLoader(e){var t;this.disableLoader||(t=this.onLoadingStateUpdate)==null||t.call(this,e)}async init({src:e}){if(this.updateLoader(h.DownloadVGGRuntimeJS),this.src=e,Array.from(document.scripts).some(s=>s.src.includes("vgg_runtime.js"))||await this.loadScript(this.runtime+"/vgg_runtime.js"),await new Promise(s=>{const n=setInterval(()=>{window._vgg_createWasmInstance&&(clearInterval(n),s(!0))},100)}),!this.canvas)throw new Error("Canvas element required");if(!this.src)throw new Error(f.missingErrorMessage);await new Promise(t=>{this.checkStateFrame=requestAnimationFrame(()=>this.checkState(t))}),console.log("VGG SDK ready",this.vggSdk),await this.loadFonts(),this.logger.logLifeCycle({phase:"init",status:"end"})}async createVggWasmInstance(){const e=this.runtime;try{const t=setTimeout(()=>{throw new Error("VGG Wasm instance creation timeout")},3e4),s=await window._vgg_createWasmInstance({noInitialRun:!0,canvas:this.canvas,locateFile:function(n,i){return n.endsWith(".data")?e+"/"+n:i+n}});return clearTimeout(t),s}catch(t){return console.error(t),null}}async checkState(e){if(this.updateLoader(h.CreateVGGWasmInstance),window._vgg_createWasmInstance){const t=await this.createVggWasmInstance();if(t){this.vggWasmInstance=t;try{this.vggWasmInstance.ccall("emscripten_main","void",["number","number","boolean"],[this.width,this.height,this.editMode])}catch(n){console.error(n)}this.vggSdk=new t.VggSdk;const s=globalThis.vggInstances??{};this.vggInstanceKey=this.vggSdk.getEnv(),this.editMode?Object.assign(s,{[this.vggInstanceKey]:{instance:t,listener:n=>{try{const i=JSON.parse(n);this.logger.logEvent(i),i.type==="select"?this.eventManager.fire({type:o.Click,data:i}):i.type==="firstRender"&&(this.state=c.Rendered,this.eventManager.fire({type:o.FirstRender}))}catch(i){console.error(i)}}}}):Object.assign(s,{[this.vggInstanceKey]:{instance:t,listeners:new Map,listener:n=>{try{JSON.parse(n).type==="firstRender"&&(this.state=c.Rendered,this.eventManager.fire({type:o.FirstRender}))}catch(i){console.error(i)}}}}),globalThis.vggInstances=s,this.state=c.Ready,this.eventManager.fire({type:o.Load})}else this.state=c.Error,this.eventManager.fire({type:o.LoadError});cancelAnimationFrame(this.checkStateFrame),e(!0),this.updateLoader(h.VGGWasmInstanceReady)}else this.checkStateFrame=requestAnimationFrame(()=>this.checkState(e))}async loadScript(e){const t=document.createElement("script");return t.src=e,document.head.appendChild(t),new Promise(s=>{t.onload=()=>{s(!0)}})}async loadFonts(){const e=this.customFonts;for(const t of e)await fetch(t).then(s=>{if(s.ok)return s.arrayBuffer();throw new Error(s.statusText)}).then(s=>{var l;const n=new Uint8Array(s),i=((l=t.split("/").pop())==null?void 0:l.split(".")[0])??"";this.loadFontFile(n,i)}).catch(s=>{console.error(`Failed to add font: ${s.message}`)})}loadFontFile(e,t){if(!this.vggSdk)throw new Error("VGG SDK not ready");if(!this.vggSdk.addFont(e,t))throw new Error("add font failed!")}on(e,t){return this.eventManager.add({type:e,callback:t}),this}async render(e,t){if(this.width=(t==null?void 0:t.width)??this.width,this.height=(t==null?void 0:t.height)??this.height,this.editMode=(t==null?void 0:t.editMode)??this.editMode,!this.vggWasmInstance)throw new Error("VGG Wasm instance not ready");const s=e??this.src;let n;if(typeof s=="string"){this.updateLoader(h.DownloadSourceFile);const l=await fetch(s);if(!l.ok)throw new Error("Failed to fetch Daruma file");const g=await l.arrayBuffer();n=new Int8Array(g)}else if(s instanceof Int8Array)n=s;else throw new Error("Invalid source file");if(this.updateLoader(h.LoadSourceFile),!this.vggWasmInstance)return;if(!this.vggWasmInstance.ccall("load_file_from_mem","boolean",["string","array","number"],["name",n,n.length]))throw new Error("Failed to load Daruma file")}$(e){if(!this.vggSdk)throw new Error("VGG SDK not ready");const t=this.observables.get(e);if(!t){const s=new S(String(e),this.vggSdk);return this.observables.set(e,s),s}return t}destroy(){var t;try{(t=this.vggWasmInstance)==null||t._vggExit()}catch{}const e=globalThis.vggInstances??{};return delete e[this.vggInstanceKey],this.eventManager.removeAll(),this.vggWasmInstance=null,this.src="",this.vggSdk=null,this.state=c.Destroyed,this.logger.logLifeCycle({phase:"destroy",status:"end"}),this.observables.clear(),this}getTextContent(){var t;return((t=this.vggSdk)==null?void 0:t.texts())??[]}snapshot(e={type:"png",quality:100}){var s;return(s=this.vggSdk)==null?void 0:s.makeImageSnapshot(e)}setContentMode(e="fit"){if(!this.vggSdk)throw new Error("VGG SDK not ready");if(e==="original")this.vggSdk.setContentMode("topLeft");else if(e==="fit")this.vggSdk.setContentMode("scaleAspectFit");else if(e==="fill")this.vggSdk.setContentMode("scaleAspectFill");else if(e==="autoFill")this.vggSdk.setContentMode("scaleAspectFillTopCenter");else throw new Error("Invalid content mode")}setFitToViewportEnabled(e){var t;(t=this.vggSdk)==null||t.setFitToViewportEnabled(e)}getAllFrames(){var t;const e=(t=this.vggSdk)==null?void 0:t.getFramesInfo();return e?JSON.parse(e):[]}setCurrentFrame(e,t=!0){var s;(s=this.vggSdk)==null||s.setCurrentFrameById(e,t)}nextFrame(){const e=this.getAllFrames(),s=(e.findIndex(n=>n.id===this.currentFrameId)+1)%e.length;this.setCurrentFrame(e[s].id)}prevFrame(){const e=this.getAllFrames(),s=(e.findIndex(n=>n.id===this.currentFrameId)-1+e.length)%e.length;this.setCurrentFrame(e[s].id)}get currentFrameId(){var e;return(e=this.vggSdk)==null?void 0:e.currentFrameId()}getFontsInUse(){var t;const e=(t=this.vggSdk)==null?void 0:t.requiredFonts();if(!e)return[];try{return JSON.parse(e)}catch(s){return console.error(s),[]}}};a(f,"missingErrorMessage","Daruma source file required");let u=f;return typeof globalThis<"u"&&(globalThis.VGG=u),d.EventType=o,d.State=c,d.VGG=u,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"}),d}({});

@@ -9,3 +9,3 @@ {

"license": "MIT",
"version": "0.1.20",
"version": "0.1.21",
"files": [

@@ -12,0 +12,0 @@ "dist"

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