Socket
Socket
Sign inDemoInstall

letsfreezethat

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

letsfreezethat - npm Package Compare versions

Comparing version 3.0.1 to 3.0.2

30

lib/main.js

@@ -32,6 +32,7 @@ (function() {

while (k--) {
if (!(((v = d[k]) != null) && ((typeof v) === 'object'))) {
continue;
if (((v = d[k]) != null) && ((typeof v) === 'object')) {
R[k] = deep_copy(v);
} else {
R[k] = v;
}
R[k] = deep_copy(v);
}

@@ -43,6 +44,7 @@ return R;

v = d[k];
if (!((v != null) && ((typeof v) === 'object'))) {
continue;
if ((v != null) && ((typeof v) === 'object')) {
R[k] = deep_copy(v);
} else {
R[k] = v;
}
R[k] = deep_copy(v);
}

@@ -67,6 +69,7 @@ return R;

while (k--) {
if (!(((v = d[k]) != null) && ((typeof v) === 'object'))) {
continue;
if (((v = d[k]) != null) && ((typeof v) === 'object')) {
d[k] = deep_freeze(v);
} else {
d[k] = v;
}
d[k] = deep_freeze(v);
}

@@ -77,6 +80,7 @@ return shallow_freeze(d);

v = d[k];
if (!((v != null) && ((typeof v) === 'object'))) {
continue;
if ((v != null) && ((typeof v) === 'object')) {
d[k] = deep_freeze(v);
} else {
d[k] = v;
}
d[k] = deep_freeze(v);
}

@@ -129,3 +133,3 @@ return shallow_freeze(d);

//-----------------------------------------------------------------------------------------------------------
nofreeze_lets = function(original, modifier = null) {
lets.nofreeze = nofreeze_lets = function(original, modifier = null) {
var draft;

@@ -132,0 +136,0 @@ draft = nofreeze_lets.thaw(original);

{
"name": "letsfreezethat",
"version": "3.0.1",
"version": "3.0.2",
"description": "An utterly minimal immutability library in the spirit of immer",

@@ -5,0 +5,0 @@ "main": "./freeze.js",

@@ -23,5 +23,3 @@

- [Benchmarks](#benchmarks)
- [Other Libraries, or: Should I COW?](#other-libraries-or-should-i-cow)
- [`klona`, `deepfreeze`, `deepfreezer`, `fast-copy`](#klona-deepfreeze-deepfreezer-fast-copy)
- [Should I COW?](#should-i-cow)
- [Other Libraries](#other-libraries)
- [To Do](#to-do)

@@ -122,2 +120,4 @@

The `nofreeze` flavor is around 3 to 4 times faster on `freeze()`.
The `lets()` method has a number of attributes which are callable by themselves (no JS tear-off /

@@ -129,28 +129,21 @@ `this`-juggling here):

* **`freeze = ( d ) ->`**—deep-freeze in-place; a no-op with `nofreeze`.
* **`thaw = ( d ) ->`**—thaw a deep copy (in the `freeze` flavor) of `d` and return it;
* **`get = ( d, key ) ->`**—return value of an attribute of `d`.
* **`set = ( d, key, value ) ->`**—set an attribute of a copy of d, return the copy.
* **`thaw = ( d ) ->`**—return a deep copy of `d` (thereby un-freezing it).
* **`get = ( d, key ) ->`**—return value of an attribute of `d`. Equivalent to `d[ key ]` and just there
to complement `set()`.
* **`set = ( d, key, value ) ->`**—make a deep copy of `d`, set attribute `key` to `value`, and return
the (frozen or unfrozen depending on flavor) copy. Prefer to use `assign()`, `thaw()`/`freeze()`, or
`lets()` whenever you want to modify more than a single attribute as `set()` will deep-copy and
deep-freeze# on each call.
## Notes
* LFT does not copy objects on explicit or implicit `freeze()`. That should be fine for most use cases since
what one usually wants to do is either create or thaw a given value (which implies making a copy),
manipulate (i.e. mutate) it, and then freeze it prior to passing it on. As long as manipulations are local
to a not-too-long single function, chances of screwing up are limited, so we can safely forgo the added
* LetsFreezeThat does not copy objects on explicit or implicit `freeze()`. That should be fine for most use
cases since what one usually wants to do is either create or thaw a given value (which implies making a
copy), manipulate (i.e. mutate) it, and then freeze it prior to passing it on. As long as manipulations
are local to a single function, chances of screwing up are limited, so we can safely forgo the added
overhead of making an additional copy when either `freeze()` is called or a call to `lets d, ( d ) -> ...`
has finished.
has finished. Observe that when being given a value `d` it is not necessarily safe to `freeze()` it since
another party may still hold a reference to `d` and assume mutability. When in doubt, use `freeze thaw d`
to freeze a deep copy of `d`.
* The idea is that you can switch to the more performant `nofreeze` flavor in production:
```coffee
if running_in_dev_mode then { lets, freeze, thaw } = require 'letsfreezethat'
else { lets, freeze, thaw } = ( require 'letsfreezethat' ).nofreeze
```
once you have made it sufficiently plausible that no part of your code performs unintended mutation of
values chalked up as immutable. Yes, it's all about probabilities rather than proof of correctness.
* The non-freezing configuration is a tad faster on `thaw()` and ≈5 times faster on `freeze()`.
* Observe that the `thaw()` method will always make a copy even with the `nofreeze` flavor;

@@ -164,2 +157,3 @@ otherwise it is hardly conceivable how an application could switch from the slower `{ freeze: true, }`

## Implementation

@@ -286,15 +280,12 @@

## Other Libraries, or: Should I COW?
## Other Libraries
During the implementation of LetsFreezeThat I realized there's quite a few packages available that do
immutability in JavaScript, e.g.
Libraries that do deep freezing and/or deep copying and/or provide copy-on-write semantics that are
available on [npm](http://npmjs.org) include [`immer`](https://immerjs.github.io/immer/docs/introduction),
[`HAMT`](https://github.com/mattbierner/hamt), [`mori`](https://swannodette.github.io/mori/),
[`immutable.js`](https://immutable-js.github.io/immutable-js/),
[`fast-copy`](https://github.com/planttheidea/fast-copy),
[`deepfreeze`](https://github.com/serapath/deepfreeze), and [`deepfreezer` (a.k.a.
DeepFreezerJS)](https://github.com/TOGoS/DeepFreezerJS).
* [`HAMT`](https://github.com/mattbierner/hamt)
* [`mori`](https://swannodette.github.io/mori/)
* [`immutable.js`](https://immutable-js.github.io/immutable-js/)
and, last but not least,
* [`immer`](https://immerjs.github.io/immer/docs/introduction).
**`immer` provided the inspiration**—The key idea of `immer` is that in order to achieve immutability in

@@ -316,5 +307,2 @@ JavaScript, instead of inventing one's own data structures and APIs, it is much simpler to just recursively

### `klona`, `deepfreeze`, `deepfreezer`, `fast-copy`
**most deep-copy algos too slow**—In search for a fast solution that would only provide deep-copying (i.e.

@@ -326,3 +314,3 @@ no copy-on-write / structural sharing) and/or deep-freezing capabilities I found

that only `klona` was likely to bring speedups to the next version of LetsFreezeThat so I did not consider
the rest any more. Deep-freezing nested compound values in-situ is almost exactly the same as deep-copying
the rest any more. Deep-freezing nested compound values in-place is almost exactly the same as deep-copying
nested compound values so I used `klona`'s approach for both chores. Be it said though that I did not

@@ -333,12 +321,10 @@ evaluate other possibly interesting aspects of any of these packages, so if your use cases involves copying

### Should I COW?
**Should I COW?**—Copy-On-Write is a technique to eschew 'speculative', avoidable memory consumption. Phil
Bagwell suggested how to efficiently leverage structural sharing for trees of data in [a paper titled *Ideal
Hash Trees* (Lausanne, 2000)](http://infoscience.epfl.ch/record/64398/files/idealhashtrees.pdf);
subsequentially, his approach was implemented by the [Clojure](https://clojure.org/) community to get more
memory-efficient and performant COW semantics into the language. Alas, according to my benchmarks HAMT is
still not fast enough in JS to justify the effort when your data items are small as you'll only get 5%—25%
of the performance that you'd get with naive copying.
**HAMT a solution for COW, *but***—Copy-On-Write is a (not new) technique to eschew 'speculative', avoidable
memory consumption. One Phil Bagwell proposed a technique how to do that efficiently for trees of data in [a
paper titled *Ideal Hash Trees* (Lausanne,
2000)](http://infoscience.epfl.ch/record/64398/files/idealhashtrees.pdf); subsequentially, his technique was
used by the [Clojure](https://clojure.org/) community to get more memory-efficient and performant COW
semantics into the language. **Q**: What's not to like?—**A**: It's *still* not as fast in JS to justify the
effort when your data items are small; again, see the [benchmarks](#benchmarks).
## To Do

@@ -351,2 +337,2 @@

case of immutable maps
* [ ] consider to optionally detect multiple object instances, circular references

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