0.2.6 • Published 4 months ago

identicons-esm v0.2.6

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months ago

Identicons

A rewrite of the Identicon module with ESM support.

Docs preview

  • Fully typed
  • Runtime agnostic: works in browser, workerd, node, bun...
  • About 2 times faster on startup and 5 times faster on re-rendering than previous version
  • Produces about 25% smaller SVG, thanks to svgo
  • Simplify bundling compare to previous version
  • No more promises!

Installation

npm install identicons-esm
import { createIdenticon } from 'identicons-esm'

const input = 'Your input here'
const svg = createIdenticon(input, { shouldValidateAddress: false }) // shouldValidateAddress is `true` by default

Identicons as <img>

import { createIdenticon } from 'identicons-esm'
import { formatIdenticonToBase64 } from 'identicons-esm/core'

const input = 'Your input here'
const imgSrc = await formatIdenticonToBase64(createIdenticon(input, { shouldValidateAddress: false }))
<img src="imgSrc" alt="Identicon" />

Identicons as Web Component

<nimiq-identicon input="Your input here" should-validate-address="false"></nimiq-identicon>
<nimiq-shiny-identicon input="Your input here" should-validate-address="false" material="gold"></nimiq-shiny-identicon>

Make sure to import the web components in your project before using them.

Web Components in Vue 3

<script setup lang="ts">
import type { IdenticonMaterial } from 'identicons-esm/types'
import 'identicons-esm/web-components'
import 'identicons-esm/shiny-web-components'

const input = 'Your input here'
const shouldValidateAddress = false
const material: IdenticonMaterial = 'gold'
</script>

<template>
  <nimiq-identicon :input="input" :should-validate-address="shouldValidateAddress" />
  <nimiq-shiny-identicon :input="input" :should-validate-address="shouldValidateAddress" :material="material" />
</template>

Vite warning

To avoid a warning in development mode, you have to let Vite know that the web component exists:

// vite.config.ts
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [vue({
    template: {
      compilerOptions: {
        isCustomElement: tag => ['nimiq-identicon', 'nimiq-shiny-identicon'].includes(tag),
      }
    }
  })],
})

!WARNING This is a PoC and the API might change

Getting just a specific color or section of the identicon

import { getIdenticonsParams } from 'identicons-esm/core'

const input = 'Your input here'
const { colors, sections } = getIdenticonsParams(input)

// colors.background -> '#0ab123'
// colors.main -> '#0ab123'
// colors.accent -> '#0ab123'
// sections.top -> Path to the SVG
// sections.bottom -> Path to the SVG
// sections.sides -> Path to the SVG
// sections.face -> Path to the SVG

Why not just use the V1 version?

We were having issues running the lib in workerd. That's it. But then, when I started looking into it, I discovered that we are there was space for improvements.

Bundling

While gulp is great and allows you to build the library, vite is the standard these days. With the old implementation, the library loaded all the features of svg into a single DOM element (using dom-parser) and from there, depending on the hash, it selected the features for the fiven hash. Then it ensabmages all the selected elements together with a predefined background and colors and runs an optimization process on each render.

With the new approach, we run svgo with some defined plugins in dev and write the optimized svg to the folder. Then at runtime we just assemble the selected optimized features and return the SVG. After the selected features have been retrieved, we just ensamlbe the SVG and return it. We don't use dom-parser and we don't need to optimize the SVG at runtime.

Performance Comparison

MetricV1 ImplementationCurrent Implementation
First Time Load~20ms~10ms
Already Loaded~6ms~1ms
Average Size Reduction-25% smaller

Migrate

Currently part of the implementation has been ported

Generate SVG string

Before

// @ts-ignore Types no implemented
import Identicons from '@nimiq/identicons/dist/identicons.min.js'
IdenticonsV1.svgPath = '@nimiq/identicons/dist/identicons.min.svg'

const input = 'Your input here'
const svg = await Identicons.svg(input)
//    ^ type any 😩

Now

import { createIdenticon } from 'identicons-esm'

const input = 'Your input here'
const svg = createIdenticon(input)
//    ^ type string

Generate Data URI

Before

// @ts-ignore Types no implemented
import Identicons from '@nimiq/identicons/dist/identicons.min.js'
IdenticonsV1.svgPath = '@nimiq/identicons/dist/identicons.min.svg'

const input = 'Your input here'
const svg = await Identicons.toDataUri(input)
//    ^ type any 😩

Now

import { createIdenticon } from 'identicons-esm'

const input = 'Your input here'
const svg = createIdenticon(input, { format: 'image/svg+xml' })
//    ^ type string

Discontiuned functions

There are functions in the original library that are not included in this implementation due to lack of use. These functions are:

  • makeLetterHash
  • wordsByEntropy
  • Identicons.render
  • Identicons.image
  • Identicons.placeholder

Development

git clone https://github.com/onmax/nimiq-identicons
pnpm install
pnpm dev
pnpm optimize-svg # Run just if you modify the content of the features
0.0.10

7 months ago

0.0.11

7 months ago

0.1.0

7 months ago

0.2.1

7 months ago

0.2.0

7 months ago

0.2.6

4 months ago

0.2.3

4 months ago

0.2.2

4 months ago

0.2.5

4 months ago

0.2.4

4 months ago

0.0.9

8 months ago

0.0.8

8 months ago

0.0.7

8 months ago

0.0.6

8 months ago

0.0.5

8 months ago

0.0.4

8 months ago

0.0.3

8 months ago

0.0.2

8 months ago

0.0.1

8 months ago

0.0.0

8 months ago