
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Dytracker is simple library ment to enable diff of objects using a provided blueprint
Dy(namic) tracker is simple library ment to enable diff of objects using a provided blueprint
import { Dytracker } from 'dytracker'
const tracker = new Dytracker({
name: true,
email: true,
permission: {
id: true,
},
posts: {
keyname: 'id', // To enable tracking of lists, array elements will need an unique identifier
tracking: {
title: true,
},
},
})
const user = {
id: 1, // It is required that the top level object have an unique identifier
name: 'Jane Doe',
email: 'jane@example.com',
permission: {
id: 1,
name: 'Admin', // Properties not in the blueprint will simply be ignored
},
posts: [
{
id: 1,
title: 'Hi there',
},
],
}
tracker.track(user)
// now lets change `user`
user.name = 'Jane Smith'
user.permission.id = 2
user.posts.push({ id: 2, title: 'Follow me at github!' })
tracker.diff(user)
/*
{
name: 'Jane Smith',
permission: { id: 2 },
posts: {
added: [ { id: 2, title: 'Follow me at github!' } ],
removed: [],
updated: []
}
}
*/
// Stop tracking user
tracker.flush(user.id)
Dytracker was written in typescript so it has first class support for types. The same example above can be written as:
import { Dytracker } from 'dytracker'
interface User {
id: number
name: string
email: string
permission: {
id: number
name: string
}
posts: Array<{
id: number
title: string
}>
}
/* Providing a generic will enable suggestions for the blueprint object */
const tracker = new Dytracker<User>({
name: true,
email: true,
permission: {
id: true,
},
posts: {
keyname: 'id',
tracking: {
title: true,
},
},
})
const user: User = {
id: 1,
name: 'Jane Doe',
email: 'jane@example.com',
permission: {
id: 1,
name: 'Admin',
},
posts: [
{
id: 1,
title: 'Hi there',
},
],
}
tracker.track(user)
user.name = 'Jane Smith'
user.permission.id = 2
user.posts.push({ id: 2, title: 'Follow me at github!' })
/*
The type of the diff return will basically be a Partial of the generic you provided
with the exception of arrays, which will be objects like { added: T[], updated: T[], removed: T[] }
*/
tracker.diff(user)
/*
{
name: 'Jane Smith',
permission: { id: 2 },
posts: {
added: [ { id: 2, title: 'Follow me at github!' } ],
removed: [],
updated: []
}
}
*/
// Stop tracking user
tracker.flush(user.id)
Dytracker enables you to monitor changes to any property of an object using the basic, nested or list interfaces. The top level object can have the folowing options:
_keyname: keyof TBy default the top level object is tracked using the id property. _keyname allows you to change the property used to track the object.
interface Obj {
key: string
foo: number
}
const tracker = new Dytracker<Obj>({
_keyname: 'key',
foo: true,
})
This is the first building block of Dytracker, it makes all properties that map to primitives selectable with a boolean.
There are no other options to the basic interface
interface Obj {
id: number
foo: number
}
const tracker = new Dytracker<Obj>({
foo: true,
})
When you need to track an object nested inside your top level object you will need to use the nested interface, which is a recursive interface that enables basic and nested types to an object. Therefore you can select properties of a nested object with a boolean and nested objects with the same API.
interface User {
id: number
name: string
permission: {
id: number
name: string
}
}
const tracker = new Dytracker<User>({
name: true,
permission: {
id: true,
name: true,
},
})
_predicate: (a: T, b: T) => booleanSomethimes you don't need to monitor properties of a nested object, especially for value objects. In that case you can use _predicate to dictate how dytracker will check for equality of that object.
structuredClone_predicate is provided all other options will be ignored e.g. you cannot watch nested properties of an object you will compare manually.interface Obj {
id: number
createdAt: Date
}
const tracker = new Dytracker<Obj>({
createdAt: {
_predicate: (a, b) => a.getTime() === b.getTime(),
},
})
Dytracker makes it easy to keep track of what was added, updated and removed from a list, this is especially usefull when you have 1-N relationship mapped into your object. To do that, your array needs to consist of objects with a unique identifier property, usually id, if you have that, you can make use the list API to track elements of an array and even choose what you want to track in each element.
number or stringinterface Post {
id: number
title: string
}
interface Obj {
id: number
posts: Post[]
}
const tracker = new Dytracker<Obj>({
posts: {
keyname: 'id',
tracking: {
title: true,
},
},
})
FAQs
Dytracker is simple library ment to enable diff of objects using a provided blueprint
We found that dytracker demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.