1.0.7 • Published 5 months ago

proxymapper v1.0.7

Weekly downloads
-
License
MIT
Repository
-
Last release
5 months ago

ProxyMapper

Uma biblioteca para criar proxies dinâmicos em objetos JavaScript e TypeScript, com suporte para Vue e React.

npm version License Downloads


📌 Descrição

O proxymapper é uma biblioteca leve e eficiente para criar proxies dinâmicos em objetos JavaScript e TypeScript, permitindo a interceptação de acessos a propriedades e a vinculação de dados de forma inteligente.

  • Compatível com JavaScript e TypeScript
  • Compatível com Vue.js e React (suporte para ref e useRef)
  • Leve e sem dependências externas
  • Ideal para estruturação dinâmica de dados
  • Facilita o mapeamento de identificadores para objetos alvo

🚀 Instalação

Instale via NPM ou Yarn:

npm install proxymapper

ou

yarn add proxymapper

🔧 Uso

O proxymapper fornece duas funções principais:

1️⃣ setProxyTree

Permite definir proxies em um objeto com base em um caminho específico.

Exemplo de Uso com Vue 3

<script setup>
import { ref } from "vue";
import { setProxyTree } from "proxymapper";

const users = ref([{ id: 1, email: "john@example.com" }]);

const data = {
  user: { userId: 1, name: "John Doe" }
};

setProxyTree(data, "user", [
  { keyId: "userId", keyTarget: "userProxy", targetObj: users, keyObserved: "id" }
]);

console.log(data.user.userProxy.email); // "john@example.com"
</script>

Exemplo de Uso com React

import { useRef } from "react";
import { setProxyTree } from "proxymapper";

const users = useRef([{ id: 1, email: "john@example.com" }]);

const data = {
  user: { userId: 1, name: "John Doe" }
};

setProxyTree(data, "user", [
  { keyId: "userId", keyTarget: "userProxy", targetObj: users, keyObserved: "id" }
]);

console.log(data.user.userProxy.email); // "john@example.com"

2️⃣ setMultiProxies

Permite definir múltiplos proxies ao mesmo tempo.

Exemplo de Uso

const { setMultiProxies } = require("proxymapper");

const data = {
  user: { userId: 1, name: "John Doe" },
  product: { productId: 42, title: "Gadget" }
};

const users = [{ id: 1, email: "john@example.com" }];
const products = { 42: { price: 99.99 } };

setMultiProxies(data, [
  {
    path: "user",
    definitions: [
      { keyId: "userId", keyTarget: "userProxy", targetObj: users, keyObserved: "id" }
    ]
  },
  {
    path: "product",
    definitions: [
      { keyId: "productId", keyTarget: "productProxy", targetObj: products, keyObserved: "id" }
    ]
  }
]);

console.log(data.user.userProxy.email); // "john@example.com"
console.log(data.product.productProxy.price); // 99.99

3️⃣ setCollectionProxy

Cria uma relação inversa entre um conjunto de elementos e suas referências, permitindo que um objeto contenha uma coleção de elementos relacionados.

Exemplo de Uso no Vue 3

setCollectionProxy

Exemplo de Uso com React

import { useRef, useEffect } from "react";

type Person = { id: number; name: string };
type User = { id: number; username: string; person_id: number };

const people = useRef<Person[]>([
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" }
]);

const users = useRef<User[]>([
  { id: 101, username: "alice123", person_id: 1 },
  { id: 102, username: "bob_87", person_id: 2 }
]);

useEffect(() => {
  setCollectionProxy(people.current, users, { source: "people", target: "users" });

  console.log(people.current[0].users);
  console.log(users.current[0].person);
}, []);

3️⃣ setAggregatedProxy

A função setAggregatedProxy cria um atributo proxy que retorna uma coleção agregada a partir dos elementos filhos.
Permite operações como:

  • Soma (sum) → Acumula valores numéricos dos filhos.
  • Concatenação (concat) → Junta arrays de filhos, com opção de remover duplicatas (unique).
  • Contagem (count) → Retorna o número total de filhos.

Agora suporta Vue (ref().value) e React (useRef().current) automaticamente.


🚀 Implementação

export const setAggregatedProxy = <T>(
  targetArray: T[] | { value?: T[] } | { current?: T[] },
  childrenKey: keyof T,
  aggregatedKey: string,
  operation: "sum" | "concat" | "count",
  observedKey?: string,
  unique: boolean = false
): void => {
  resolveRefArray(targetArray).forEach((target) => {
    Object.defineProperty(target, aggregatedKey, {
      get: () => {
        const children = (target[childrenKey] as unknown as T[]) || [];

        if (operation === "sum") {
          const sumObjectsRecursively = (acc: any, obj: any): any => {
            Object.keys(obj).forEach((key) => {
              if (typeof obj[key] === "object" && obj[key] !== null) {
                acc[key] = sumObjectsRecursively(acc[key] || {}, obj[key]);
              } else {
                acc[key] = (acc[key] || 0) + obj[key];
              }
            });
            return acc;
          };

          return children.reduce((acc, child) => {
            const childData = (child as any)[aggregatedKey] || {};
            return sumObjectsRecursively(acc, childData);
          }, {});
        }

        if (operation === "concat") {
          let allValues: any[] = [];
          children.forEach((child) => {
            const childValues = (child as any)[aggregatedKey]?.[observedKey!] || [];
            allValues = [...allValues, ...childValues];
          });

          return unique ? [...new Set(allValues)] : allValues;
        }

        if (operation === "count") {
          return children.length;
        }

        return undefined;
      },
      enumerable: true,
    });
  });
};

🔹 Parâmetros

ParâmetroTipoDescrição
targetArrayT[] | { value?: T[] } | { current?: T[] }O array pai onde o proxy será aplicado. Suporta Vue ref() e React useRef().
childrenKeykeyof TO atributo que contém os filhos.
aggregatedKeystringO nome do atributo proxy a ser criado no pai.
operation"sum" | "concat" | "count"Define o tipo de agregação.
observedKeystring (opcional)No modo "concat", indica qual chave dentro dos filhos será concatenada.
uniqueboolean (opcional, padrão: false)No modo "concat", define se os valores devem ser únicos.

🔹 Exemplo de Uso

📌 Somando Valores (sum)

const acoes = [
  {
    contratos: [
      { financeiro: { all: { empenhado: 10, pago: 10 } } },
      { financeiro: { all: { empenhado: 20, pago: 20 } } }
    ]
  }
];

setAggregatedProxy(acoes, "contratos", "financeiro", "sum");

console.log(acoes[0].financeiro);
// { all: { empenhado: 30, pago: 30 } }

📌 Concatenando Arrays (concat)

const acoes = [
  {
    contratos: [
      { financeiro: { processos: ["A", "B"] } },
      { financeiro: { processos: ["B", "C"] } }
    ]
  }
];

setAggregatedProxy(acoes, "contratos", "financeiro", "concat", "processos", true);

console.log(acoes[0].financeiro.processos);
// ["A", "B", "C"] (Unique)

📌 Contando Elementos (count)

const acoes = [
  { contratos: [{ id: 1 }, { id: 2 }] },
  { contratos: [{ id: 3 }] }
];

setAggregatedProxy(acoes, "contratos", "total_contratos", "count");

console.log(acoes[0].total_contratos); // 2
console.log(acoes[1].total_contratos); // 1

🔥 Suporte para Vue e React

O proxymapper agora suporta refs do Vue (ref()) e React (useRef()), tornando a biblioteca multiplataforma.

🔹 No Vue 3, refs são verificadas através de __v_isRef e acessadas via .value.
🔹 No React, useRef é detectado pelo campo current.

Isso significa que você pode usar proxymapper diretamente em projetos Vue ou React sem precisar adaptar o código! 🚀


📌 Compatibilidade

✅ Funciona com Node.js
✅ Pode ser usado em projetos JavaScript puro ou TypeScript
✅ Compatível com Vue 3 e React 16+
✅ Suporte a CommonJS (require) e ES Modules (import)


🚀 Contribuindo

Contribuições são bem-vindas! Se você deseja melhorar esta biblioteca, siga os passos:

  1. Clone o repositório
    git clone https://github.com/andersonbr/proxymapper.git
    cd proxymapper
  2. Instale as dependências
    npm install
  3. Faça suas alterações e crie um PR!

📜 Licença

Este projeto está licenciado sob a MIT License. Consulte o arquivo LICENSE para mais detalhes.


Apoie o Projeto

Se esta biblioteca foi útil para você, deixe uma estrela ⭐ no GitHub para ajudar mais desenvolvedores a descobri-la! 😊

1.0.7

5 months ago

1.0.6

5 months ago

1.0.5

5 months ago

1.0.4

5 months ago

1.0.3

5 months ago

1.0.2

5 months ago

1.0.1

5 months ago

1.0.0

5 months ago