object-subscriptions

1.0.3 • Public • Published

object-subscriptions

Nested object with mutations and subscribers

Examples

Calculate and Subscribe

import {NestedObjectWithSubscriptions} from "object-subscriptions";

const obj = new NestedObjectWithSubscriptions();

obj.set("aa.bb", 123);
obj.set("cc.dd", 123);

obj.calculate(["aa.bb", "cc.dd"], (a, b) => {
    return a + b;
}, "ee.ff")

obj.subscribe("ee.ff", (value) => {
    console.log("VAL!", value);
});

Custom Separator and Traversal

import {NestedObjectWithSubscriptions} from "object-subscriptions";

const obj = new NestedObjectWithSubscriptions({}, {separator: '/'});

obj.set("aa/bb", 123);
obj.set("cc/dd", 123);

obj.calculate(["aa/bb", "cc/dd"], (a, b) => {
    return a + b;
}, "ee/ff")

obj.subscribe("ee/ff", (value) => {
    console.log("VAL!", value);
});


for(let [pathParts, value] of obj.entries({pathParts: true})) {
    console.log(pathParts, value);
}

Defer execution

import {NestedObjectWithSubscriptions} from "object-subscriptions";

const obj = new NestedObjectWithSubscriptions({}, {separator: '/'});

obj.set("aa/bb", 123);
obj.set("cc/dd", 123);

obj.calculate(["aa/bb", "cc/dd"], (a, b) => {
    return a + b;
}, "ee/ff", {defer: true})

obj.subscribe("ee/ff", (value) => {
    console.log("VAL!", value);
});

for(let [pathParts, value] of obj.entries({pathParts: true})) {
    console.log(pathParts, value);
}

Debounced calculation

import {NestedObjectWithSubscriptions} from "object-subscriptions";

const obj = new NestedObjectWithSubscriptions({}, {separator: '/'});

obj.set("aa/bb", 123);
obj.set("cc/dd", 123);

obj.calculate(["aa/bb", "cc/dd"], (a, b) => {
    return a + b;
}, "ee/ff", {debounce: 100, immediate: false})

obj.subscribe("ee/ff", (value) => {
    console.log("VAL!", value);
});

for(let [pathParts, value] of obj.entries({pathParts: true})) {
    console.log(pathParts, value);
}

Take a slice

import {NestedObjectWithSubscriptions} from "object-subscriptions";

const obj = new NestedObjectWithSubscriptions({}, {separator: '/'});

obj.set("aa/bb", 123);

const child = obj.child("aa");

console.log("VAL!", child.get([]));

Two-way sync

const obj1 = new NestedObjectWithSubscriptions({}, {separator: '/'});
const obj2 = new NestedObjectWithSubscriptions({}, {separator: '/'});

const obj1Tag = Symbol("obj1");
const obj2Tag = Symbol("obj2");

const obj1PathParts = ['sync'];
const obj2PathParts = ['aa', 'bb'];

// Sync from obj1 to obj2
obj1.subscribe(obj1PathParts, (value, metadata) => {
// Only sync if the change didn't originate from obj2
if (metadata.syncTag !== obj2Tag) {
    const targetPathParts = [...obj2PathParts, ...metadata.mutatedPathParts.slice(obj1PathParts.length)];

        if (metadata.mutation === NestedObjectWithSubscriptions.MUTATIONS.SET) {
            // For SET operations, use the specific path that was mutated
            obj2.set(targetPathParts, metadata.mutatedValue, {
                syncTag: obj1Tag,
                tag: metadata.options?.tag
            });
        }
        else if (metadata.mutation === NestedObjectWithSubscriptions.MUTATIONS.DELETE) {
            // For DELETE operations, delete the specific path
            obj2.delete(targetPathParts, {
                syncTag: obj1Tag,
                tag: metadata.options?.tag
            });
        }
    }
}, {fetch: false});

// Sync from obj2 to obj1
obj2.subscribe(obj2PathParts, (value, metadata) => {
// Only sync if the change didn't originate from obj1
if (metadata.syncTag !== obj1Tag) {
const targetPathParts = [...obj1PathParts, ...metadata.mutatedPathParts.slice(obj2PathParts.length)];

        if (metadata.mutation === NestedObjectWithSubscriptions.MUTATIONS.SET) {
            // For SET operations, use the specific path that was mutated
            obj1.set(targetPathParts, metadata.mutatedValue, {
                syncTag: obj2Tag,
                tag: metadata.options?.tag
            });
        }
        else if (metadata.mutation === NestedObjectWithSubscriptions.MUTATIONS.DELETE) {
            // For DELETE operations, delete the specific path
            obj1.delete(targetPathParts, {
                syncTag: obj2Tag,
                tag: metadata.options?.tag
            });
        }
    }
}, {fetch: false});



// Test the sync
obj1.set(['sync', 'xx'], 123); // This will sync to obj2
obj2.set(['aa', 'bb', 'cc'], 456); // This will sync to obj1

obj2.delete(['aa', 'bb', 'cc']); // This will sync to obj1

Readme

Keywords

none

Package Sidebar

Install

npm i object-subscriptions

Weekly Downloads

12

Version

1.0.3

License

none

Unpacked Size

31.6 kB

Total Files

10

Last publish

Collaborators

  • johnvmt