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

partial.lenses

Package Overview
Dependencies
Maintainers
1
Versions
180
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

partial.lenses - npm Package Compare versions

Comparing version 3.3.0 to 3.3.1

.nyc_output/4764.json

6

package.json
{
"name": "partial.lenses",
"version": "3.3.0",
"version": "3.3.1",
"description": "Partial lenses",

@@ -36,6 +36,6 @@ "main": "lib/partial.lenses.js",

"babel-preset-stage-2": "^6.5.0",
"eslint": "^2.7.0",
"eslint": "^2.8.0",
"mocha": "^2.4.5",
"nyc": "^6.2.1"
"nyc": "^6.4.0"
}
}

@@ -13,5 +13,4 @@ [ [Tutorial](#tutorial) | [Reference](#reference) | [Background](#background) ]

inserts the new part. Setting an existing part to `undefined` removes it.
Partial lenses are defined in such a way that operations
[`compose`](#lcomposels) and one can conveniently and robustly operate on deeply
nested data structures.
Partial lenses are defined in such a way that operations [`compose`](#compose)
and one can conveniently and robustly operate on deeply nested data structures.

@@ -50,4 +49,4 @@ [![npm version](https://badge.fury.io/js/partial.lenses.svg)](http://badge.fury.io/js/partial.lenses) [![Build Status](https://travis-ci.org/calmm-js/partial.lenses.svg?branch=master)](https://travis-ci.org/calmm-js/partial.lenses) [![](https://david-dm.org/calmm-js/partial.lenses.svg)](https://david-dm.org/calmm-js/partial.lenses) [![](https://david-dm.org/calmm-js/partial.lenses/dev-status.svg)](https://david-dm.org/calmm-js/partial.lenses#info=devDependencies) [![Gitter](https://img.shields.io/gitter/room/calmm-js/chat.js.svg?style=flat-square)](https://gitter.im/calmm-js/chat)

Take a moment to read through the above definition line by line. Each line has
a specific purpose. The purpose of the [`L.prop(...)`](#lpropstring) lines is
probably obvious. The other lines we will mention below.
a specific purpose. The purpose of the [`L.prop(...)`](#prop) lines is probably
obvious. The other lines we will mention below.

@@ -57,4 +56,4 @@ ### Querying data

Thanks to the parameterized search part,
[`L.find(R.whereEq({language}))`](#lfindpredicate), of the lens composition, we
can use it to query texts:
[`L.find(R.whereEq({language}))`](#find), of the lens composition, we can use it
to query texts:

@@ -77,4 +76,4 @@ ```js

We get this default, rather than undefined, thanks to the last part,
[`L.defaults("")`](#ldefaultsout), of our lens composition. We get the default
even if we query from `undefined`:
[`L.defaults("")`](#defaults), of our lens composition. We get the default even
if we query from `undefined`:

@@ -111,4 +110,3 @@ ```js

kept sorted thanks to the
[`L.normalize(R.sortBy(R.prop("language")))`](#lnormalizevalue--value) part of
our lens.
[`L.normalize(R.sortBy(R.prop("language")))`](#normalize) part of our lens.

@@ -126,4 +124,4 @@ ### Removing data

whole object vanish, rather than just the `text` property, is the
[`L.defaults({language})`](#ldefaultsout) part of our lens composition. A
[`L.defaults(value)`](#ldefaultsout) lens works *symmetrically*. When set with
[`L.defaults({language})`](#defaults) part of our lens composition. A
[`L.defaults(value)`](#defaults) lens works *symmetrically*. When set with
`value`, the result is `undefined`, which means that the focus of the lens is to

@@ -141,6 +139,6 @@ be removed.

The `contents` property is not removed thanks to the
[`L.required([])`](#lrequiredinn) part of our lens composition.
[`L.required`](#lrequiredinn) is the dual of [`L.defaults`](#ldefaultsout).
[`L.defaults`](#ldefaultsout) replaces undefined values when viewed and
[`L.required`](#lrequiredinn) replaces undefined values when set.
[`L.required([])`](#required) part of our lens composition.
[`L.required`](#required) is the dual of [`L.defaults`](#defaults).
[`L.defaults`](#defaults) replaces undefined values when viewed and
[`L.required`](#required) replaces undefined values when set.

@@ -152,7 +150,7 @@ Note that unless defaults and required values are explicitly specified as part

Take out one (or more) [`L.required(...)`](#lrequiredinn),
[`L.normalize(...)`](#lnormalizevalue--value) or
[`L.defaults(...)`](#ldefaultsout) part(s) from the lens composition and try to
predict what happens when you rerun the examples with the modified lens
composition. Verify your reasoning by actually rerunning the examples.
Take out one (or more) [`L.required(...)`](#required),
[`L.normalize(...)`](#normalize) or [`L.defaults(...)`](#defaults) part(s) from
the lens composition and try to predict what happens when you rerun the examples
with the modified lens composition. Verify your reasoning by actually rerunning
the examples.

@@ -163,8 +161,7 @@ ### Shorthands

library supports. In particular,
* [`L.compose(...)`](#lcomposels) can be abbreviated to use the default import,
e.g. [`P(...)`](#lcomposels),
* [`L.prop(string)`](#lpropstring) can be abbreviated as
[`string`](#lpropstring), and
* [`L.set(l, undefined, s)`](#lsetl-x-s) can be abbreviated as
[`L.remove(l, s)`](#lremovel-s).
* [`L.compose(...)`](#compose) can be abbreviated to use the default import,
e.g. [`P(...)`](#compose),
* [`L.prop(string)`](#prop) can be abbreviated as [`string`](#prop), and
* [`L.set(l, undefined, s)`](#set) can be abbreviated as
[`L.remove(l, s)`](#remove).

@@ -274,8 +271,7 @@ ### Systematic decomposition

partial lens. But could we leverage lens combinators to build a BST lens more
directly? We can. The [`L.choose`](#lchoosemaybevalue--plens) combinator
allows for dynamic construction of lenses based on examining the data structure
being manipulated. Inside [`L.choose`](#lchoosemaybevalue--plens) we can write
the ordinary BST logic to pick the correct branch based on the key in the
currently examined node and the key that we are looking for. So, here is our
first attempt at a BST lens:
directly? We can. The [`L.choose`](#choose) combinator allows for dynamic
construction of lenses based on examining the data structure being manipulated.
Inside [`L.choose`](#choose) we can write the ordinary BST logic to pick the
correct branch based on the key in the currently examined node and the key that
we are looking for. So, here is our first attempt at a BST lens:

@@ -320,4 +316,4 @@ ```js

How do we fix this? We could check and transform the data structure to a BST
after changes. The [`L.normalize`](#lnormalizevalue--value) combinator can be
used for that purpose. Here is the updated `search` definition:
after changes. The [`L.normalize`](#normalize) combinator can be used for that
purpose. Here is the updated `search` definition:

@@ -364,4 +360,4 @@ ```js

Use of the default import, [`P`](#lcomposels), is optional and is an alias for
[`L.compose`](#lcomposels).
Use of the default import, [`P`](#compose), is optional and is an alias for
[`L.compose`](#compose).

@@ -372,3 +368,3 @@ ### Operations on lenses

#### [`L.get(l, s)`](#lgetl-s "L.get :: PLens s a -> Maybe s -> Maybe a")
#### <a name="get"></a>[`L.get(l, s)`](#get "L.get :: PLens s a -> Maybe s -> Maybe a")

@@ -384,3 +380,3 @@ `L.get(l, s)` returns the focused element from a data structure.

#### [`L.modify(l, x2x, s)`](#lmodifyl-x2x-s "L.modify :: PLens s a -> (Maybe a -> Maybe a) -> Maybe s -> Maybe s")
#### <a name="modify"></a>[`L.modify(l, x2x, s)`](#modify "L.modify :: PLens s a -> (Maybe a -> Maybe a) -> Maybe s -> Maybe s")

@@ -397,5 +393,5 @@ `L.modify(l, x2x, s)` allows one to map over the focused element of a data

#### [`L.remove(l, s)`](#lremovel-s "L.remove :: PLens s a -> Maybe s -> Maybe s")
#### <a name="remove"></a>[`L.remove(l, s)`](#remove "L.remove :: PLens s a -> Maybe s -> Maybe s")
`L.remove(l, s)` is equivalent to [`L.set(l, undefined, s)`](#lsetl-x-s). With
`L.remove(l, s)` is equivalent to [`L.set(l, undefined, s)`](#set). With
partial lenses, setting to undefined typically has the effect of removing the

@@ -411,3 +407,3 @@ focused element.

#### [`L.removeAll(l, s)`](#lremovealll-s "L.removeAll :: PLens s a -> Maybe s -> Maybe s")
#### <a name="removeAll"></a>[`L.removeAll(l, s)`](#removeAll "L.removeAll :: PLens s a -> Maybe s -> Maybe s")

@@ -429,5 +425,5 @@ **`L.removeAll` is deprecated and will be removed. Use a different

#### [`L.set(l, x, s)`](#lsetl-x-s "L.set :: PLens s a -> Maybe a -> Maybe s -> Maybe s")
#### <a name="set"></a>[`L.set(l, x, s)`](#set "L.set :: PLens s a -> Maybe a -> Maybe s -> Maybe s")
`L.set(l, x, s)` is equivalent to [`L.modify(l, () => x, s)`](#lmodifyl-x2x-s).
`L.set(l, x, s)` is equivalent to [`L.modify(l, () => x, s)`](#modify).

@@ -445,3 +441,3 @@ For example:

#### [`L.append`](#lappend "L.append :: PLens [a] a")
#### <a name="append"></a>[`L.append`](#append "L.append :: PLens [a] a")

@@ -460,3 +456,3 @@ `L.append` is a special semi-degenerate lens that operates on arrays. The view

#### [`L.augment({prop: obj => val, ...props})`](#laugmentprop-obj--val-props "L.augment :: {p1 :: o -> a1, ...ps} -> PLens {...o} {...o, p1 :: a1, ...ps}")
#### <a name="augment"></a>[`L.augment({prop: obj => val, ...props})`](#augment "L.augment :: {p1 :: o -> a1, ...ps} -> PLens {...o} {...o, p1 :: a1, ...ps}")

@@ -476,3 +472,3 @@ `L.augment({prop: obj => val, ...props})` is given a template of functions to

#### [`L.chain(a2bPLens, aPLens)`](#lchaina2bplens-aplens "L.chain :: (a -> PLens s b) -> PLens s a -> PLens s b")
#### <a name="chain"></a>[`L.chain(a2bPLens, aPLens)`](#chain "L.chain :: (a -> PLens s b) -> PLens s a -> PLens s b")

@@ -488,9 +484,9 @@ `L.chain(a2bPLens, aPLens)` is equivalent to

With the [`L.just`](#ljustvalue), `L.chain`, [`L.choice`](#lchoicels) and
[`L.nothing`](#lnothing) combinators, one can view partial lenses as subsuming
With the [`L.just`](#just), `L.chain`, [`L.choice`](#choice) and
[`L.nothing`](#nothing) combinators, one can view partial lenses as subsuming
the maybe monad. Of course, the whole point of lenses is that they are
bidirectional and the special lenses [`L.just`](#ljustvalue) and
[`L.nothing`](#lnothing) are essentially degenerate.
bidirectional and the special lenses [`L.just`](#just) and
[`L.nothing`](#nothing) are essentially degenerate.
#### [`L.choose(maybeValue => PLens)`](#lchoosemaybevalue--plens "L.choose :: (Maybe s -> PLens s a) -> PLens s a")
#### <a name="choose"></a>[`L.choose(maybeValue => PLens)`](#choose "L.choose :: (Maybe s -> PLens s a) -> PLens s a")

@@ -520,3 +516,3 @@ `L.choose(maybeValue => PLens)` creates a lens whose operation is determined by

#### [`L.choice(...ls)`](#lchoicels "L.choice :: (...PLens s a) -> PLens s a")
#### <a name="choice"></a>[`L.choice(...ls)`](#choice "L.choice :: (...PLens s a) -> PLens s a")

@@ -526,5 +522,5 @@ `L.choice(...ls)` returns a partial lens that acts like the first of the given

of all of the given lenses are undefined, the returned lens acts like
[`L.nothing`](#lnothing), which is the identity element of `L.choice`.
[`L.nothing`](#nothing), which is the identity element of `L.choice`.
#### [`L.compose(...ls)`](#lcomposels "L.compose :: (PLens s s1, ...PLens sN a) -> PLens s a")
#### <a name="compose"></a>[`L.compose(...ls)`](#compose "L.compose :: (PLens s s1, ...PLens sN a) -> PLens s a")

@@ -549,8 +545,8 @@ The default import `P` and `L.compose` refer to the one and same function, which

#### [`L.defaults(out)`](#ldefaultsout "L.defaults :: s -> PLens s s")
#### <a name="defaults"></a>[`L.defaults(out)`](#defaults "L.defaults :: s -> PLens s s")
`L.defaults(out)` is the same as
[`L.replace(undefined, out)`](#lreplaceinn-out). `L.defaults` is used to
specify a default value for an element in case it is missing. This can be
useful to avoid having to check for and provide default behavior elsewhere.
`L.defaults(out)` is the same as [`L.replace(undefined, out)`](#replace).
`L.defaults` is used to specify a default value for an element in case it is
missing. This can be useful to avoid having to check for and provide default
behavior elsewhere.

@@ -566,3 +562,3 @@ For example:

#### [`L.define(value)`](#ldefinevalue "L.define :: s -> PLens s s")
#### <a name="define"></a>[`L.define(value)`](#define "L.define :: s -> PLens s s")

@@ -573,3 +569,3 @@ `L.define(value)` is the same as `P(L.required(value), L.defaults(value))`.

#### [`L.filter(predicate)`](#lfilterpredicate "L.filter :: (a -> Boolean) -> PLens [a] [a]")
#### <a name="filter"></a>[`L.filter(predicate)`](#filter "L.filter :: (a -> Boolean) -> PLens [a] [a]")

@@ -594,10 +590,10 @@ `L.filter(predicate)` operates on arrays. When viewed, only elements matching

implement, it doesn't seem to make sense, because in most cases use of
[`L.normalize`](#lnormalizevalue--value) would be preferable.
[`L.normalize`](#normalize) would be preferable.
#### [`L.find(predicate)`](#lfindpredicate "L.find :: (a -> Boolean) -> PLens [a] a")
#### <a name="find"></a>[`L.find(predicate)`](#find "L.find :: (a -> Boolean) -> PLens [a] a")
`L.find(predicate)` operates on arrays like [`L.index`](#lindexinteger), but the
index to be viewed is determined by finding the first element from the input
array that matches the given predicate. When no matching element is found the
effect is same as with [`L.append`](#lappend).
`L.find(predicate)` operates on arrays like [`L.index`](#index), but the index
to be viewed is determined by finding the first element from the input array
that matches the given predicate. When no matching element is found the effect
is same as with [`L.append`](#append).

@@ -609,7 +605,7 @@ ```js

#### [`L.findWith(...ls)`](#lfindwithls "L.findWith :: (PLens s s1, ...PLens sN a) -> PLens [s] a")
#### <a name="findWith"></a>[`L.findWith(...ls)`](#findWith "L.findWith :: (PLens s s1, ...PLens sN a) -> PLens [s] a")
`L.findWith(...ls)` chooses an index from an array through which the given lens,
[`P(...ls)`](#lcomposels), focuses on a defined item and then returns a lens
that focuses on that item.
[`P(...ls)`](#compose), focuses on a defined item and then returns a lens that
focuses on that item.

@@ -625,3 +621,3 @@ For example:

#### [`L.identity`](#lidentity "L.identity :: PLens s s")
#### <a name="identity"></a>[`L.identity`](#identity "L.identity :: PLens s s")

@@ -638,3 +634,3 @@ `L.identity` is the identity element of lens composition. The following

#### [`L.index(integer)`](#lindexinteger "L.index :: Integer -> PLens [a] a")
#### <a name="index"></a>[`L.index(integer)`](#index "L.index :: Integer -> PLens [a] a")

@@ -654,4 +650,4 @@ `L.index(integer)` or `integer` focuses on the specified array index.

an array must not remove the array itself. In such cases you want to use
[`L.required([])`](#lrequiredinn) to access the array. Consider the following
examples without [`L.required([])`](#lrequiredinn):
[`L.required([])`](#required) to access the array. Consider the following
examples without [`L.required([])`](#required):

@@ -667,3 +663,3 @@ ```js

Then consider the same examples with [`L.required([])`](#lrequiredinn):
Then consider the same examples with [`L.required([])`](#required):

@@ -679,3 +675,3 @@ ```js

#### [`L.just(value)`](#ljustvalue "L.just :: a -> PLens s a")
#### <a name="just"></a>[`L.just(value)`](#just "L.just :: a -> PLens s a")

@@ -692,5 +688,5 @@ `L.just(x)` is equivalent to `L.compose(L.nothing, L.defaults(x))` and is a

`L.just` can be seen as the unit function of the monad formed with
[`L.chain`](#lchaina2bplens-aplens).
[`L.chain`](#chain).
#### [`L.lens(get, set)`](#llensget-set "L.lens :: (Maybe s -> Maybe a) -> (Maybe a -> Maybe s -> Maybe s) -> PLens s a")
#### <a name="lens"></a>[`L.lens(get, set)`](#lens "L.lens :: (Maybe s -> Maybe a) -> (Maybe a -> Maybe s -> Maybe s) -> PLens s a")

@@ -727,8 +723,8 @@ `L.lens(get, set)` creates a new primitive lens. One should think twice before

When composed with [`L.pick`](#lpickp1-l1-pls), to flexibly pick the `start` and
`end` times, the above can be adapted to work in a wide variety of cases.
However, the above lens will never be added to this library, because it would
require adding dependency to [Moment.js](http://momentjs.com/).
When composed with [`L.pick`](#pick), to flexibly pick the `start` and `end`
times, the above can be adapted to work in a wide variety of cases. However,
the above lens will never be added to this library, because it would require
adding dependency to [Moment.js](http://momentjs.com/).
#### [`L.normalize(value => value)`](#lnormalizevalue--value "L.normalize :: (s -> s) -> PLens s s")
#### <a name="normalize"></a>[`L.normalize(value => value)`](#normalize "L.normalize :: (s -> s) -> PLens s s")

@@ -742,3 +738,3 @@ `L.normalize(value => value)` maps the value with same given transform when

#### [`L.nothing`](#lnothing "L.nothing :: PLens s s")
#### <a name="nothing"></a>[`L.nothing`](#nothing "L.nothing :: PLens s s")

@@ -753,5 +749,5 @@ `L.nothing` is a special degenerate lens whose view is always undefined and

`L.nothing` is the identity element of [`L.choice`](#lchoicels).
`L.nothing` is the identity element of [`L.choice`](#choice).
#### [`L.orElse(backup, primary)`](#lorelsebackup-primary "L.orElse :: (PLens s a, PLens s a) -> PLens s a")
#### <a name="orElse"></a>[`L.orElse(backup, primary)`](#orElse "L.orElse :: (PLens s a, PLens s a) -> PLens s a")

@@ -763,5 +759,5 @@ `L.orElse(backup, primary)` acts like `primary` when its view is not undefined

choice over lenses or use `L.orElse` to specify a default or backup lens for
[`L.choice`](#lchoicels), for example.
[`L.choice`](#choice), for example.
#### [`L.pick({p1: l1, ...pls})`](#lpickp1-l1-pls "L.pick :: {p1 :: PLens s a1, ...pls} -> PLens s {p1 :: a1, ...pls}")
#### <a name="pick"></a>[`L.pick({p1: l1, ...pls})`](#pick "L.pick :: {p1 :: PLens s a1, ...pls} -> PLens s {p1 :: a1, ...pls}")

@@ -815,3 +811,3 @@ `L.pick({p1: l1, ...pls})` creates a lens out of the given object template of

#### [`L.prop(string)`](#lpropstring "L.prop :: (p :: a) -> PLens {p :: a, ...ps} a")
#### <a name="prop"></a>[`L.prop(string)`](#prop "L.prop :: (p :: a) -> PLens {p :: a, ...ps} a")

@@ -825,6 +821,6 @@ `L.prop(string)` or `string` focuses on the specified object property.

#### [`L.props(...strings)`](#lpropsstrings "L.props :: (p1 :: a1, ...ps) -> PLens {p1 :: a1, ...ps, ...o} {p1 :: a1, ...ps}")
#### <a name="props"></a>[`L.props(...strings)`](#props "L.props :: (p1 :: a1, ...ps) -> PLens {p1 :: a1, ...ps, ...o} {p1 :: a1, ...ps}")
`L.props(k1, ..., kN)` is equivalent to [`L.pick({[k1]: k1, ..., [kN]:
kN})`](#lpickp1-l1-pls) and focuses on a subset of properties of an object,
kN})`](#pick) and focuses on a subset of properties of an object,
allowing one to treat the subset of properties as a unit. The view of `L.props`

@@ -842,3 +838,3 @@ is undefined when none of the properties is defined. Otherwise the view is an

#### [`L.replace(inn, out)`](#lreplaceinn-out "L.replace :: Maybe s -> Maybe s -> PLens s s")
#### <a name="replace"></a>[`L.replace(inn, out)`](#replace "L.replace :: Maybe s -> Maybe s -> PLens s s")

@@ -862,8 +858,7 @@ `L.replace(inn, out)`, when viewed, replaces the value `inn` with `out` and vice

#### [`L.required(inn)`](#lrequiredinn "L.required :: s -> PLens s s")
#### <a name="required"></a>[`L.required(inn)`](#required "L.required :: s -> PLens s s")
`L.required(inn)` is the same as
[`L.replace(inn, undefined)`](#lreplaceinn-out). `L.required` is used to
specify that an element is not to be removed; in case it is removed, the given
value will be substituted instead.
`L.required(inn)` is the same as [`L.replace(inn, undefined)`](#replace).
`L.required` is used to specify that an element is not to be removed; in case it
is removed, the given value will be substituted instead.

@@ -885,3 +880,3 @@ For example:

#### [`L.fromRamda(lens)`](#lfromramdalens "L.fromRamda :: Lens s a -> PLens s a")
#### <a name="fromRamda"></a>[`L.fromRamda(lens)`](#fromRamda "L.fromRamda :: Lens s a -> PLens s a")

@@ -891,3 +886,3 @@ `L.fromRamda(lens)` converts the given Ramda lens to a partial lens. Note that

#### [`L.toRamda(plens)`](#ltoramdaplens "L.toRamda :: PLens s a -> Lens s a")
#### <a name="toRamda"></a>[`L.toRamda(plens)`](#toRamda "L.toRamda :: PLens s a -> Lens s a")

@@ -899,3 +894,3 @@ `L.toRamda(plens)` converts the given partial lens to a Ramda lens. Note that

#### [`L.log(...labels)`](#lloglabels "L.log :: (...Any) -> Lens s s")
#### <a name="log"></a>[`L.log(...labels)`](#log "L.log :: (...Any) -> Lens s s")

@@ -929,13 +924,13 @@ `L.log(...labels)` is an identity lens that outputs

As said in the first sentence of this document, lenses are convenient for
performing updates on "individual elements". Having the ability to flexibly
search, filter and restructure data using lenses makes the notion of an
individual element quite flexible, which makes it all the more important to
understand that lenses are just one of many functional abstractions for working
with data structures.
performing updates on "individual elements". Having abilities such as
[searching](#find), [filtering](#filter) and [restructuring](#pick) data using
lenses makes the notion of an individual element quite flexible and makes it all
the more important to understand that lenses are just one of many functional
abstractions for working with data structures.
One type of use case which we've ran into multiple times and falls out of the
sweet spot of lenses is performing uniform transforms over data structures. For
example, we've run into the following uses cases:
example, we've run into the following use cases:
* Eliminate all reference to an object with a particular id.
* Eliminate all references to an object with a particular id.
* Transform all instances of certain objects over many paths.

@@ -1041,4 +1036,4 @@ * Filter out extra fields from objects of varying shapes and paths.

using the same operations as with ordinary lenses. However, primitive partial
lenses (e.g. [`L.prop`](#lpropstring)) are not necessarily the same as primitive
lenses (e.g. [`L.prop`](#prop)) are not necessarily the same as primitive
ordinary lenses (e.g. Ramda's
[`R.lensProp`](http://ramdajs.com/0.21.0/docs/#lensProp)).

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