npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

weaken-it

v1.1.5

Published

WeakMap utility functions and related patterns

Downloads

16

Readme

weaken-it

minzipped typescript

Lightweight tree-shakeable WeakMap utility functions and related patterns, with typescript support.

Every weakness contains within itself a strength Shūsaku Endō

Dandelion by Herbert Goetsch Photo by Herbert Goetsch on Unsplash


:man_technologist: Installation

Npm

npm i weaken-it

CDN

<script type="module">
const { wit } = await import("https://cdn.jsdelivr.net/npm/weaken-it@latest")

// store to context
wit(SomeReference, ContextNamespace, AnyValue)

// retrieve
wit(SomeReference, ContextNamespace)

</script>

:wrench: How it works

At its core it's just a temporary namespaced key-value store built on top of native js WeakMap and Map, using a set of personal conventions enforced by weakenIt() function. Both WeakMap and Map were chosen over plain objects for their advantages in terms of r/w speed and key flexibility.

  • Creates a WeakMap, wStore
  • WeakMap ensures that each instance is stored once and its associated context expires with it
  • weakenIt ensures that each Map context is stored / recreated only once and always reused
  • Then weakenIt, or even shorter wit, stores / gets any key-value from the related context
  • When reference is lost or wStore.prototype.deleted || wDel, its context gets garbage-collected

:thinking: Why

I was very excited about WeakRef and FinalizationRegistry coming to javascript but both their behaviours are not yet guaranteed, making them very hard to reason about, at least for me.

:ring_buoy: WeakMap and WeakSet to the rescue!

  • They ensure stored data will expire after the bound instance, or will always be available as long the associated reference exists
  • They enable patterns I reach for when I need to extend libraries, js natives, work with dom, store temporary data or when I'm generally concerned about potential memory leaks
  • It can safely bridge context data inside closures or where unreachable
  • They're fast, native, memory-efficient by nature, fully supported and reliable
  • They give me peace of mind :relieved:

:muscle: Usage

For more examples, please refer to tests folder.

import { weakenIt } from 'weaken-it'

// augment an external library or native
class Example extends SomeLibraryOrNative {

  constructor(extraData, ...libraryRequired) {
    super(...libraryRequired)

    // extraData never outlives the instance
    weakenIt(this, 'temp', extraData + 'Example constructor')
  }

  overridden(...methodArgs) {
    // bridged inside
    const extraData = weakenIt(this, 'temp')    
    doSomethingWith(temp)

    // still works without modifying the original implementation
    return SomeLibraryOrNative.prototype.overridden.apply(this, methodArgs)
  }
}

let exampleInstance = new Example(
  'extra data from: ',
  'library needed data'
)

function useExtraData() {
  console.log(weakenIt(example, 'temp'))
}

useExtraData()
// extra data from: Example constructor

example = null 
useExtraData()
// undefined (gc'ed)

:toolbox: Available exports

Core

  • weakenIt, core function to interact with contexts
  • wStore, stores all contexts

Shortcuts

  • wit, alias to weakenIt
  • wDel, hard reset context
  • wCtx, gets the entire context
  • wCast, casts a copy of the context as object
  • wSure, upsert if stored is nullish
  • wMap, new Map(), dirt-cheap iterable WeakMap
  • wSet, new Set(), dirt-cheap iterable WeakSet
  • wKV, creates a Object.create(null)
  • wArr, creates []
  • wObj, creates {}

Utils

  • wMemo, memoized fn
  • wCount, global counter

:ballot_box_with_check: TODO

[x] Import and standardize other patterns [x] Randomize tests [x] Documentation

Disclaimer

This library is very opinionated, mainly bult for reusability between personal projects. It encapsulates and summarizes some of my most recurring personal approaches involving native WeakMap, which I really :heart: