Socket
Socket
Sign inDemoInstall

@chialab/backbone

Package Overview
Dependencies
8
Maintainers
2
Versions
25
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.5.4 to 2.5.5

4

dist/esm/backbone.js

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

var v=(e,r,t)=>{if(!r.has(e))throw TypeError("Cannot "+t)};var a=(e,r,t)=>(v(e,r,"read from private field"),t?t.call(e):r.get(e)),y=(e,r,t)=>{if(r.has(e))throw TypeError("Cannot add the same private member more than once");r instanceof WeakSet?r.add(e):r.set(e,t)},w=(e,r,t,n)=>(v(e,r,"write to private field"),n?n.call(e,t):r.set(e,t),t);import F from"ajv";import b from"ajv-formats";var z=new F({keywords:[{keyword:"__esModule"},{keyword:"formatOptions",valid:!0},{keyword:"form",metaSchema:{type:"object",properties:{type:{type:"string"}}}}],formats:{text:e=>typeof e=="string",html:e=>typeof e=="string",code:e=>typeof e=="string"},allowUnionTypes:!0,strictTypes:!1});b(z);function x(e,r=[]){return Array.isArray(e)?e.forEach(t=>x(t,r)):e.oneOf?x(e.oneOf,r):e.allOf?x(e.allOf,r):e.$ref&&r.push(e.$ref),r}var m=class{static register(r,t){if(this.registry.has(r))throw new Error(`Model "${r}" has already been registered.`);this.registry.set(r,t)}static has(r){return this.registry.has(r)}static get(r){if(!this.registry.has(r))throw new Error(`Model "${r}" is not registered.`);return this.registry.get(r)}static entries(){return this.registry.entries()}};m.registry=new Map;function D(e){return function(r){let t=r.setupSchema();t.$id=e,t.type="object",r.validator=z.addSchema(t,e).compile(t),m.register(e,r)}}function V(e){return function(r,t){r.constructor.setupProperty(t,{type:e})}}function j(e){return function(r,t){r.constructor.setupProperty(t,{anyOf:e.map(o=>typeof o=="string"?{type:o}:o)})}}function q(){return function(e,r){e.constructor.setupProperty(r,{readOnly:!0})}}function H(){return function(e,r){let n=e.constructor.setupSchema();(n.required=n.required||[]).push(r)}}function K(e,r={}){return function(t,n){t.constructor.setupProperty(n,{format:e,formatOptions:r})}}function L(e){return function(r,t){r.constructor.setupProperty(t,{default:e})}}function R(e){return function(r,t){r.constructor.setupProperty(t,{type:"string",enum:Array.isArray(e)?e:Object.values(e)})}}function B(e){return function(r,t){let n=r.constructor;e=e.filter(o=>o.schema),n.setupProperty(t,{type:"array",items:e.length>1?{allOf:e.map(o=>({$ref:o.schema.$id}))}:e.length===1?{$ref:e[0].schema.$id}:{}})}}function _(e){return function(r,t){let n=r.constructor,o=Array.isArray(e)?{oneOf:e.map(i=>typeof i=="string"?{type:i}:{$ref:i.schema.$id})}:{$ref:e.schema.$id};n.setupProperty(t,o)}}function G(e){return function(r,t){let n=r.constructor,o=(Array.isArray(e)?e:[e]).filter(i=>i.schema);n.setupProperty(t,{type:"array",uniqueItems:!0,items:o.length>1?{allOf:o.map(i=>({$ref:i.schema.$id}))}:o.length===1?{$ref:o[0].schema.$id}:{}})}}function Q(e){return function(r,t){r.constructor.setupProperty(t,{form:e})}}function W(e,r){return function(t,n){t.constructor.setupSerializer(n,{serialize:e,unserialize:r})}}var f,g=class{constructor(){y(this,f,{})}on(r,t){a(this,f)[r]=a(this,f)[r]||[],a(this,f)[r].push(t)}off(r,t){let n=a(this,f)[r];if(!n)return;let o=n.indexOf(t);o!==-1&&a(this,f)[r].splice(o,1)}trigger(r,t){let n=a(this,f)[r];!n||n.forEach(o=>o.call(this,t))}};f=new WeakMap;var c,T=class extends g{constructor(t=[]){super();y(this,c,void 0);w(this,c,t)}get length(){return a(this,c).length}add(...t){return t=t.filter(n=>!this.has(n)),a(this,c).push(...t),this.trigger("change",{added:t,removed:[],length:this.length}),this}insert(t,...n){return n.filter(o=>this.has(o)).forEach(o=>{a(this,c).splice(this.indexOf(o),1)}),a(this,c).splice(t,0,...n),this.trigger("change",{added:n,removed:[],length:this.length}),this}remove(...t){return t=t.filter(n=>this.has(n)),t.forEach(n=>{a(this,c).splice(this.indexOf(n),1)}),this.trigger("change",{added:[],removed:t,length:this.length}),this}indexOf(t){return a(this,c).indexOf(t)}item(t){return a(this,c)[t]||null}itemById(t){let n=a(this,c);for(let o=0,i=n.length;o<i;o++)if(n[o].getId()===t)return n[o];return null}has(t){return this.indexOf(t)!==-1}forEach(t){return a(this,c).forEach(t)}some(t){return a(this,c).some(t)}find(t){return a(this,c).find(t)}map(t){return a(this,c).map(t)}entries(){return a(this,c).entries()}filter(t){let n=this.constructor;return new n(a(this,c).filter(t))}reduce(t,n){return a(this,c).reduce(t,n)}get(){return a(this,c).slice(0)}clone(){return new T(this.get())}toJSON(){return this.get().map(t=>t.toJSON())}*[Symbol.iterator](){for(let t of a(this,c))yield t}},M=T;c=new WeakMap,M.className="Collection";function N(e,r,t,n=[],o=!1){let i={},u=r.schema,l=r.serializers||{};for(let s in e){if(u&&t&&!t(s,u.properties?.[s],u,e,r,n))continue;let p=e[s],h=l[s]?.serialize;h&&!o?i[s]=h(p,e,i,t,[...n,{model:r,object:e,key:s}]):i[s]=p}return i}function O(e,r,t,n=[],o=!1){if(e instanceof k||r){r=r||e.constructor;let i=N(e,r,t,n,o);for(let u in i)i[u]=O(i[u],void 0,t,[...n,{model:r,object:e,key:u}],o);return i}return Array.isArray(e)||e instanceof M?e.map(i=>O(i,void 0,t,n,o)):e}function nt(e,r,t={},n=[]){let o=r.schema,i=r.serializers||{},u=o.properties||{},l={};for(let s in e)if(u[s]){let h=i[s]?.unserialize,P=e[s];h?l[s]=h(P,e,t,n):l[s]=P}return new r(l,t)}var S,k=class extends g{constructor(t,n={}){super();y(this,S,[]);let o=this.constructor,i=o.setupSerializers();if(t){let l=this.getSchema().properties||{};for(let s in l){let p=l[s];if(s in t){let h=i[s]?.unserialize;t[s]=h?h(t[s],t,n):t[s]}else"default"in p&&(typeof p.default=="function"?t[s]=p.default(this,t):t[s]=p.default)}if(!n.skipValidation&&!n.editingMode){let s=o.validator;if(s&&!s(O(t,o)))throw new Error(`Invalid init properties.
var k=(e,r,t)=>{if(!r.has(e))throw TypeError("Cannot "+t)};var a=(e,r,t)=>(k(e,r,"read from private field"),t?t.call(e):r.get(e)),y=(e,r,t)=>{if(r.has(e))throw TypeError("Cannot add the same private member more than once");r instanceof WeakSet?r.add(e):r.set(e,t)},v=(e,r,t,n)=>(k(e,r,"write to private field"),n?n.call(e,t):r.set(e,t),t);import w from"ajv";import F from"ajv-formats";var x=new w({keywords:[{keyword:"__esModule"},{keyword:"formatOptions",valid:!0},{keyword:"form",metaSchema:{type:"object",properties:{type:{type:"string"}}}}],formats:{text:e=>typeof e=="string",html:e=>typeof e=="string",code:e=>typeof e=="string"},allowUnionTypes:!0,strictTypes:!1});F(x);function O(e,r=[]){return Array.isArray(e)?e.forEach(t=>O(t,r)):e.oneOf?O(e.oneOf,r):e.allOf?O(e.allOf,r):e.$ref&&r.push(e.$ref),r}var g=class{static register(r,t){if(this.registry.has(r))throw new Error(`Model "${r}" has already been registered.`);this.registry.set(r,t)}static has(r){return this.registry.has(r)}static get(r){if(!this.registry.has(r))throw new Error(`Model "${r}" is not registered.`);return this.registry.get(r)}static entries(){return this.registry.entries()}};g.registry=new Map;function D(e){return function(r){let t=r.setupSchema();t.$id=e,t.type="object",r.validator=x.addSchema(t,e).compile(t),g.register(e,r)}}function V(e){return function(r,t){r.constructor.setupProperty(t,{type:e})}}function j(e){return function(r,t){r.constructor.setupProperty(t,{anyOf:e.map(o=>typeof o=="string"?{type:o}:o)})}}function q(){return function(e,r){e.constructor.setupProperty(r,{readOnly:!0})}}function H(){return function(e,r){let n=e.constructor.setupSchema();(n.required=n.required||[]).push(r)}}function K(e,r={}){return function(t,n){t.constructor.setupProperty(n,{format:e,formatOptions:r})}}function L(e){return function(r,t){r.constructor.setupProperty(t,{default:e})}}function R(e){return function(r,t){r.constructor.setupProperty(t,{type:"string",enum:Array.isArray(e)?e:Object.values(e)})}}function B(e){return function(r,t){let n=r.constructor;e=e.filter(o=>o.schema),n.setupProperty(t,{type:"array",items:e.length>1?{allOf:e.map(o=>({$ref:o.schema.$id}))}:e.length===1?{$ref:e[0].schema.$id}:{}})}}function _(e){return function(r,t){let n=r.constructor,o=Array.isArray(e)?{oneOf:e.map(i=>typeof i=="string"?{type:i}:{$ref:i.schema.$id})}:{$ref:e.schema.$id};n.setupProperty(t,o)}}function G(e){return function(r,t){let n=r.constructor,o=(Array.isArray(e)?e:[e]).filter(i=>i.schema);n.setupProperty(t,{type:"array",uniqueItems:!0,items:o.length>1?{allOf:o.map(i=>({$ref:i.schema.$id}))}:o.length===1?{$ref:o[0].schema.$id}:{}})}}function Q(e){return function(r,t){r.constructor.setupProperty(t,{form:e})}}function W(e,r){return function(t,n){t.constructor.setupSerializer(n,{serialize:e,unserialize:r})}}var h,m=class{constructor(){y(this,h,{})}on(r,t){a(this,h)[r]=a(this,h)[r]||[],a(this,h)[r].push(t)}off(r,t){let n=a(this,h)[r];if(!n)return;let o=n.indexOf(t);o!==-1&&a(this,h)[r].splice(o,1)}trigger(r,t){let n=a(this,h)[r];!n||n.forEach(o=>o.call(this,t))}};h=new WeakMap;var c,T=class extends m{constructor(t=[]){super();y(this,c,void 0);v(this,c,t)}get length(){return a(this,c).length}add(...t){return t=t.filter(n=>!this.has(n)),a(this,c).push(...t),this.trigger("change",{added:t,removed:[],length:this.length}),this}insert(t,...n){return n.filter(o=>this.has(o)).forEach(o=>{a(this,c).splice(this.indexOf(o),1)}),a(this,c).splice(t,0,...n),this.trigger("change",{added:n,removed:[],length:this.length}),this}remove(...t){return t=t.filter(n=>this.has(n)),t.forEach(n=>{a(this,c).splice(this.indexOf(n),1)}),this.trigger("change",{added:[],removed:t,length:this.length}),this}indexOf(t){return a(this,c).indexOf(t)}item(t){return a(this,c)[t]||null}itemById(t){let n=a(this,c);for(let o=0,i=n.length;o<i;o++)if(n[o].getId()===t)return n[o];return null}has(t){return this.indexOf(t)!==-1}forEach(t){return a(this,c).forEach(t)}some(t){return a(this,c).some(t)}find(t){return a(this,c).find(t)}map(t){return a(this,c).map(t)}entries(){return a(this,c).entries()}filter(t){let n=this.constructor;return new n(a(this,c).filter(t))}reduce(t,n){return a(this,c).reduce(t,n)}get(){return a(this,c).slice(0)}clone(){return new T(this.get())}toJSON(){return this.get().map(t=>t.toJSON())}*[Symbol.iterator](){for(let t of a(this,c))yield t}},S=T;c=new WeakMap,S.className="Collection";function N(e,r,t,n=[],o=!1){let i={},u=r.schema,l=r.serializers||{};for(let s in e){if(u&&t&&!t(s,u.properties?.[s],u,e,r,n))continue;let p=e[s],d=l[s]?.serialize;d&&!o?i[s]=d(p,e,i,t,[...n,{model:r,object:e,key:s}]):i[s]=p}return i}function M(e,r,t,n=[],o=!1){if(e instanceof C||r){r=r||e.constructor;let i=N(e,r,t,n,o);for(let u in i)i[u]=M(i[u],void 0,t,[...n,{model:r,object:e,key:u}],o);return i}return Array.isArray(e)||e instanceof S?e.map(i=>M(i,void 0,t,n,o)):e}function nt(e,r,t={},n=[]){let o=r.schema,i=r.serializers||{},u=o.properties||{},l={};for(let s in e)if(u[s]){let d=i[s]?.unserialize,P=e[s];d?l[s]=d(P,e,t,n):l[s]=P}return new r(l,t)}var z,C=class extends m{constructor(t,n={}){super();y(this,z,[]);let o=this.constructor,i=o.setupSerializers();if(t){let l=this.getSchema().properties||{};for(let s in l){let p=l[s];if(s in t){let d=i[s]?.unserialize;t[s]=d?d(t[s],t,n):t[s]}else"default"in p&&(typeof p.default=="function"?t[s]=p.default(this,t):t[s]=p.default)}if(!n.skipValidation&&!n.editingMode){let s=o.validator;if(s&&!s(M(t,o)))throw new Error(`Invalid init properties.
${s.errors?.map(p=>JSON.stringify(p)).join(`
`)}`)}for(let s in t)this[s]=t[s]}}static setupSchema(){return Object.prototype.hasOwnProperty.call(this,"schema")?this.schema:this.schema=this.schema?JSON.parse(JSON.stringify(this.schema)):{}}static setupSerializers(){return Object.prototype.hasOwnProperty.call(this,"serializers")?this.serializers:this.serializers={...this.serializers||{}}}static setupProperty(t,n){let o=this.setupSchema(),i=o.properties=o.properties||{},u=i[t]=i[t]||{};return Object.assign(u,n),u}static setupSerializer(t,n){let o=this.setupSerializers();o[t]=n}isNew(){return!this.hasChanges()}getId(){}getDisplayName(){return this.getId()}getDisplayFields(){return[]}getSchema(){return this.constructor.schema||{}}getModelType(){return this.getSchema().$id}getPropertyFormat(t){let i=(this.getSchema().properties||{})[t];if(!!i)return i.format}get(t){return this[t]}set(t,n=!1){let o=this.toJSON(),i=!1;for(let u in t){let l=t[u];(l!==this[u]||n)&&(i=!0,this[u]=l)}i&&(a(this,S).push(o),this.trigger("change"))}hasChanges(){return!!a(this,S).length}validate(){let t=this.constructor,n=t.validator;return n(O(this,t,void 0,void 0,!0))}getErrors(){let n=this.constructor.validator;return this.validate()?[]:n.errors||[]}toJSON(t,n=[]){let o=this.constructor;return O(this,o,t,n)}};S=new WeakMap;var it={serialize:e=>e&&!isNaN(e.getTime())?e.toISOString():void 0,unserialize:e=>e?new Date(e):void 0};export{j as AnyOf,M as Collection,it as DateSerializer,L as Default,g as Emitter,R as Enum,Q as Form,K as Format,G as HasMany,_ as HasOne,B as Items,k as Model,q as ReadOnly,m as Registry,H as Required,D as Schema,W as Serialize,V as Type,x as collectReferences,z as schemaManager,O as serialize,nt as unserialize};
`)}`)}for(let s in t)this[s]=t[s]}}static setupSchema(){return Object.prototype.hasOwnProperty.call(this,"schema")?this.schema:this.schema=this.schema?JSON.parse(JSON.stringify(this.schema)):{}}static setupSerializers(){return Object.prototype.hasOwnProperty.call(this,"serializers")?this.serializers:this.serializers={...this.serializers||{}}}static setupProperty(t,n){let o=this.setupSchema(),i=o.properties=o.properties||{},u=i[t]=i[t]||{};return Object.assign(u,n),u}static setupSerializer(t,n){let o=this.setupSerializers();o[t]=n}isNew(){return!this.hasChanges()}getId(){}getDisplayName(){return this.getId()}getDisplayFields(){return[]}getSchema(){return this.constructor.schema||{}}getModelType(){return this.getSchema().$id}getPropertyFormat(t){let i=(this.getSchema().properties||{})[t];if(!!i)return i.format}get(t){return this[t]}set(t,n=!1){let o=this.toJSON(),i=!1;for(let u in t){let l=t[u];(l!==this[u]||n)&&(i=!0,this[u]=l)}i&&(a(this,z).push(o),this.trigger("change"))}hasChanges(){return!!a(this,z).length}validate(){let t=this.constructor,n=t.validator;return n(M(this,t,void 0,void 0,!0))}getErrors(){let n=this.constructor.validator;return this.validate()?[]:n.errors||[]}toJSON(t,n=[]){let o=this.constructor;return M(this,o,t,n)}};z=new WeakMap;var it={serialize:e=>e&&!isNaN(e.getTime())?e.toISOString():void 0,unserialize:e=>e?new Date(e):void 0};export{j as AnyOf,S as Collection,it as DateSerializer,L as Default,m as Emitter,R as Enum,Q as Form,K as Format,G as HasMany,_ as HasOne,B as Items,C as Model,q as ReadOnly,g as Registry,H as Required,D as Schema,W as Serialize,V as Type,O as collectReferences,x as schemaManager,M as serialize,nt as unserialize};
//# sourceMappingURL=/backbone.js.map
{
"name": "@chialab/backbone",
"version": "2.5.4",
"version": "2.5.5",
"description": "Models, Collections and Form helpers for JS apps.",

@@ -5,0 +5,0 @@ "type": "module",

import type { JSONSchema } from '../Lib/Schema';
import type { Props, Model, Serializer, Unserializer } from '../Models/Model';
import type { Props, Model, ModelConstructor, Serializer, Unserializer } from '../Models/Model';
declare type PlainTypes = 'number' | 'string' | 'boolean' | 'object' | 'array' | 'null';

@@ -8,3 +8,3 @@ /**

*/
export declare function Schema(type: string): (constructor: typeof Model) => void;
export declare function Schema(type: string): <T extends ModelConstructor<Props, Model<Props>>>(constructor: T) => void;
/**

@@ -72,3 +72,3 @@ * Decorate a class field with a JSON schema type.

*/
export declare function Items(models: typeof Model[]): (target: Model, propertyName: string) => void;
export declare function Items(models: ModelConstructor[]): (target: Model, propertyName: string) => void;
/**

@@ -81,3 +81,3 @@ * Create a reference field.

*/
export declare function HasOne(models: typeof Model | [typeof Model, 'null']): (target: Model, propertyName: string) => void;
export declare function HasOne(models: ModelConstructor | [ModelConstructor, 'null']): (target: Model, propertyName: string) => void;
/**

@@ -87,3 +87,3 @@ * Create a list of references.

*/
export declare function HasMany(models: typeof Model | typeof Model[]): (target: Model, propertyName: string) => void;
export declare function HasMany(models: ModelConstructor | ModelConstructor[]): (target: Model, propertyName: string) => void;
/**

@@ -90,0 +90,0 @@ * Options for field form.

import type { JSONSchema, ValidateFunction } from '../Lib/Schema';
import { Emitter } from './Emitter';
export declare type SchemaProperty = {
type: string;
[key: string]: unknown;
} | {
enum: string[];
[key: string]: unknown;
};
export interface ModelInitOptions {

@@ -8,3 +15,3 @@ skipValidation?: boolean;

export declare type SerializePath = {
model: typeof Model;
model: ModelConstructor;
object: Model;

@@ -18,5 +25,5 @@ key: string;

export declare type Unserializer<I = any, O = any> = (input: I, inputData: any, options?: ModelInitOptions, path?: SerializePath[]) => O;
export declare type SerializeFilter = (key: string, definition: any, schema: JSONSchema, object: Model, model: typeof Model, path: SerializePath[]) => boolean;
export declare function serialize(object: any, model?: typeof Model, filter?: SerializeFilter, path?: SerializePath[], skipSerializers?: boolean): any;
export declare function unserialize(inputData: any, model: typeof Model, options?: ModelInitOptions, path?: SerializePath[]): any;
export declare type SerializeFilter = (key: string, definition: any, schema: JSONSchema, object: Model, model: ModelConstructor, path: SerializePath[]) => boolean;
export declare function serialize(object: any, model?: ModelConstructor, filter?: SerializeFilter, path?: SerializePath[], skipSerializers?: boolean): any;
export declare function unserialize(inputData: any, model: ModelConstructor, options?: ModelInitOptions, path?: SerializePath[]): any;
/**

@@ -47,3 +54,3 @@ * The base JSON Schema class for models.

* @param constructor The model constructor.
* @return A shallow schema.
* @returns A shallow schema.
*/

@@ -53,3 +60,3 @@ static setupSchema(): any;

* Setup constructor serializers.
* @return A serializers set.
* @returns A serializers set.
*/

@@ -65,5 +72,5 @@ static setupSerializers(): {

* @param propertyName The name of the property to setup.
* @return A property of the schema.
* @returns A property of the schema.
*/
static setupProperty(propertyName: string, propertySchema: JSONSchema): any;
static setupProperty(propertyName: string, propertySchema: JSONSchema): SchemaProperty;
/**

@@ -93,1 +100,56 @@ * Setup a serializer for a given constructor.

}
/**
* Constructor type helper for Model.
*/
export declare type ModelConstructor<P extends Props = Props, T extends Model<P> = Model<P>> = {
/**
* The schema definition.
*/
schema: JSONSchema;
/**
* A validator function for entities.
*/
validator: ValidateFunction;
/**
* A model-to-schema mapping registry.
*/
serializers: {
[key: string]: {
serialize?: Serializer | null;
unserialize?: Unserializer | null;
};
};
/**
* Setup a schema object for a given constructor.
* @param constructor The model constructor.
* @returns A shallow schema.
*/
setupSchema(): JSONSchema;
/**
* Setup constructor serializers.
* @returns A serializers set.
*/
setupSerializers(): {
[key: string]: {
serialize?: Serializer | null;
unserialize?: Unserializer | null;
};
};
/**
* Setup a schema property object for a given constructor.
* @param propertyName The name of the property to setup.
* @returns A property of the schema.
*/
setupProperty(propertyName: string, propertySchema: JSONSchema): SchemaProperty;
/**
* Setup a serializer for a given constructor.
* @param propertyName The name of the property to setup.
* @param serializer The serializer object to set.
*/
setupSerializer(propertyName: string, serializer: {
serialize?: Serializer | null;
unserialize?: Unserializer | null;
}): void;
new (...args: any[]): T;
prototype: T;
};

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

import type { Model } from '../Models/Model';
import type { ModelConstructor } from '../Models/Model';
/**

@@ -11,3 +11,3 @@ * A model registry.

*/
static register(type: string, model: typeof Model): void;
static register<T extends ModelConstructor>(type: string, model: T): void;
/**

@@ -21,10 +21,10 @@ * Check if a model class has been registered.

* @param type The type/name of the requested model.
* @return The model class.
* @returns The model class.
* @throws If there is not a model registered for the given type.
*/
static get(type: string): typeof Model;
static get(type: string): ModelConstructor<import("../Models/Model").Props, import("../Models/Model").Model<import("../Models/Model").Props>>;
/**
* Get an iterator for registered models.
*/
static entries(): IterableIterator<[string, typeof Model]>;
static entries(): IterableIterator<[string, ModelConstructor<import("../Models/Model").Props, import("../Models/Model").Model<import("../Models/Model").Props>>]>;
}

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc