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

oxilor-immutable-js

v1.0.4

Published

Immutable data for JavaScript

Downloads

8

Readme

oxilor-immutable-js

Данная библиотека разрабатывалась для работы с Redux (для изменения состояний в reducers), но также может использоваться и для других целей, где требуется неизменяемость данных.

Данные хранятся в виде простых типов JS. Поэтому не требуются какие-либо дополнительные преобразования перед сохранением новых состояний (например, при использовании redux-persist).

Установка

Используя Yarn:

yarn add oxilor-immutable-js

Используя npm:

npm install oxilor-immutable-js

Пример использования

import immutable from 'oxilor-immutable-js'

// Например, сейчас в state у нас хранится 2 пользователя
const state = {
    'id1': {
        name: 'Ilya',
        surname: 'Ordin',
        email: null
    },
    'id2': {
        name: 'John',
        surname: 'Smith',
        email: '[email protected]'
    }
}

// И нам нужно у пользователя Ilya Ordin поменять почту на [email protected]
const nextState = immutable(state)
    .with('id1')
    .set('email', '[email protected]')
    .getState()

immutable возвращает новый state с измененной почтой. Этот state можно использовать для следующего состояния Redux. Старый state не изменился.

Методы

При вызове immutable необходимо передать объект, который необходимо изменить. По умолчанию передаваемый объект полностью клонируется (создается новый объект, в котором будут производиться изменения).

Если во втором параметре withMutations передать true, то все изменения будут происходить непосредственно с передаваемым объектом.

const state = {
    email: null
}

// Возвращает новый объект state с измененным email. Старый state не изменился. 
const nextState = immutable(state)
    .set('email', '[email protected]')
    .getState()

// Возвращает тот же state (ссылку на него) с измененным email. Старый state изменился.
const nextState = immutable(state, true)
    .set('email', '[email protected]')
    .getState()

getState

Возвращает новый state в виде JS объекта. Игнорирует путь, выставленный в with (подробнее о методе with ниже).

with

Устанавливает путь до элемента, относительно которого будут производиться дальнейшие операции.

const state = {
    'id1': {
        email: null,
        stats: {
            taskCompleted: 10
        }
    },
    'id2': {
        email: null,
        stats: {
            taskCompleted: 0
        }
    }
}

// Возвращает новый state, в котором email у объекта id1 равен [email protected]
immutable(state)
    .with('id1')
    .set('email', '[email protected]')
    .getState()

// Возвращает новый state, в котором taskCompleted у объекта id1 равен 11
immutable(state)
    .with(['id1', 'stats'])
    .set('taskCompleted', 11)
    .getState()

По умолчанию with каждый раз выставляет путь до элемента относительно корня.

// Меняет email в объектах id1 и id2. Возвращает новый state.
immutable(state)
    .with('id1').set('email', '[email protected]')
    .with('id2').set('email', '[email protected]')
    .getState()

Если необходимо добавить путь к заданному ранее, необходимо во втором параметре savePrevPath передать true.

// Меняет taskCompleted в объекте id1. Возвращает новый state.
immutable(state)
    .with('id1')
    .with('stats', true)
    .set('taskCompleted', 11)
    .getState()

// Аналог
immutable(state)
    .with(['id1', 'stats'])
    .set('taskCompleted', 11)
    .getState()

unwith

Сбрасывает путь до выбранного элемента.

const state = {
    'id1': {
        email: null
    },
    'id2': {
        email: null
    }
}

// Возвращает state, в котором email у объекта id1 равен [email protected] и в state установлен параметр sort = asc
immutable(state)
    .with('id1').set('email', '[email protected]')
    .unwith()
    .set('sort', 'asc')
    .getState()

get

Возвращает элемент по заданному пути. Если элемент не существует, возвращает undefined.

const state = {
    'id1': {
        email: null,
        stats: {
            taskCompleted: 10
        }
    }
}

// Три варианта получения email
immutable(state).with('id1').get('email')
immutable(state).with(['id1', 'email']).get()
immutable(state).get(['id1', 'email'])

set

Создает или изменяет элемент по заданному пути.

const state = {
    'id1': {
        email: null,
        stats: {
            taskCompleted: 10
        }
    }
}

// Два варианта замены email, используя set. Возвращает новый state.
immutable(state).with('id1').set('email', '[email protected]').getState()
immutable(state).set(['id1', 'email'], '[email protected]').getState()

// Добавление объекта id2, который равен null. Возвращает новый state.
immutable(state).set('id2', null).getState()

update

Изменяет элемент по заданному пути. В отличии от set, если элемент не существует, state не меняется.

const state = {
    'id1': {
        email: null
    }
}

// Два варианта замены email, используя update. Возвращает новый state.
immutable(state).with('id1').update('email', '[email protected]').getState()
immutable(state).update(['id1', 'email'], '[email protected]').getState()

// Пытаемся обновить несуществующий объект с id2. Возвращает тот же state.
immutable(state).update('id2', null).getState()

updateBy

Обновляет элементы в объекте или массиве, используя callback для поиска элементов

const state = {
    'id1': {
        color: 'white'
    },
    'id2': {
        color: 'black'
    },
    'id3': {
        color: 'white'
    },
}

// Меняет color с white на red. Меняет все найденные объекты.
immutable(state).updateBy(item => item.color === 'white', { color: 'red' }).getState()

Если нужно изменить color только в первом найденном элементе, необходимо в третьем параметре onlyFirstFound передать true.

immutable(state).updateBy(item => item.color === 'white', { color: 'red' }, true).getState()

remove

Удаляет элемент по заданному пути.

const state = {
    'id1': {
        email: '[email protected]'
    },
    'id2': {
        email: '[email protected]'
    }
}

// Два варианта удаления email. Возвращает новый state.
immutable(state).with('id1').remove('email').getState()
immutable(state).remove(['id1', 'email']).getState()

// Удаление объекта id2. Возвращает новый state.
immutable(state).remove('id2').getState()

removeBy

Удаляет элементы в объекте или массиве, используя callback для поиска элементов.

const state = {
    'id1': {
        age: 15
    },
    'id2': {
        age: 16
    },
    'id3': {
        age: 26
    },
}

// Удаляет все объекты, в которых age < 18. Возвращает новый state.
immutable(state).removeBy(item => item.age < 18).getState()

Если нужно удалить только первый найденный объект, необходимо во втором параметре onlyFirstFound передать true.

immutable(state).removeBy(item => item.age < 18, true).getState()

updateKey

Обновляет ключ по заданному пути.

const state = {
    'id1': {
        email: '[email protected]'
    }
}

// Изменяем id1 на id2. Возвращает новый state.
immutable(state).updateKey('id1', 'id2').getState()

// Два варианта изменения email на second_email. Возвращает новый state.
immutable(state).with('id1').updateKey('email', 'second_email').getState()
immutable(state).updateKey(['id1', 'email'], 'second_email').getState()

merge

Объединяет элементы в объекте или массиве.

const state = {
    'id1': {
        name: 'Ilya',
        email: '[email protected]'
    }
}

const data = {
    name: 'Ilya',
    surname: 'Ordin'
}

// Добавляем в state параметр sort. Возвращает новый state.
immutable(state).merge({ 'sort': 'asc' }).getState()

// Два варианта объединения объекта id1 с data. Возвращает новый state.
immutable(state).with('id1').merge(data).getState()
immutable(state).merge(data, 'id1').getState() // Вторым параметром можно передавать путь до нужного объекта в виде массива

push

Добавляет новый элемент в массиве.

const state = {
    'id1': {
        email: '[email protected]',
        permissions: ['CAN_CHANGE_STATUS']
    }
}

// Добавляем в permissions CAN_CREATE_NEW_TASKS. Возвращает новый state.
immutable(state).with(['id1', 'permissions']).push('CAN_CREATE_NEW_TASKS').getState()

forEach

Аналог forEach по объекту или массиву по заданному пути. В forEach можно изменять элементы.

const state = {
    'id1': {
        age: 15,
        hasAccess: false
    },
    'id2': {
        age: 16,
        hasAccess: false
    },
    'id3': {
        age: 26,
        hasAccess: false
    },
}

// Изменяем hasAccess на true в тех объектах, в которых age >= 18. Возвращает новый state.
immutable(state).forEach(item => {
    if (item.age >= 18) {
        item.set('hasAccess', true)
    }
}).getState()

Во втором параметре можно передать путь до объекта, в котором необходимо применить forEach.

const state = {
    byId: {
        'id1': {
            age: 15,
            hasAccess: false
        },
        'id2': {
            age: 16,
            hasAccess: false
        },
        'id3': {
            age: 26,
            hasAccess: false
        },
    },
    ids: ['id1', 'id2']
}

immutable(state).forEach(item => {
    if (item.age >= 18) {
        item.set('hasAccess', true)
    }
}, 'byId').getState()

filter

Аналог filter по объекту или массиву по заданному пути.

const state = {
    'id1': {
        age: 15,
        hasAccess: false
    },
    'id2': {
        age: 16,
        hasAccess: false
    },
    'id3': {
        age: 26,
        hasAccess: true
    },
}

// Оставляем только те объекты, в которых hasAccess равен true. Возвращает новый state.
immutable(state).filter(item => item.hasAccess).getState()

По аналогии с forEach во втором параметре можно передать путь до объекта, в котором необходимо применить filter.

has

Проверяет существование элемента по заданному пути. Возвращает boolean.

const state = {
    'id1': {
        name: 'Ilya',
        surname: 'Ordin',
        email: '[email protected]'
    },
}

// Возвращает true
immutable(state).has('id1')
immutable(state).has(['id1', 'name'])
immutable(state).with('id1').has('name')

// Возвращает false
immutable(state).has('id2')
immutable(state).has(['id1', 'age'])
immutable(state).with('id1').has('age')