JSPM

@dieugene/users-graph

1.1.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 5
  • Score
    100M100P100Q26296F
  • License MIT

Модуль для фиксации связей между пользователями с использованием YDB

Package Exports

  • @dieugene/users-graph
  • @dieugene/users-graph/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@dieugene/users-graph) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@dieugene/users-graph

Модуль для фиксации связей между пользователями с использованием YDB (Yandex Database).

Описание

Данный модуль предназначен для управления графом связей между пользователями. Он позволяет сохранять информацию о связях между пользователями в базе данных YDB, включая дополнительные метаданные.

Структура таблицы

Модуль работает с таблицей users_graph в YDB со следующей структурой:

CREATE TABLE users_graph
(
    `id` BigSerial NOT NULL,
    `from_uuid` Utf8,
    `to_uuid` Utf8,
    `data` Json,
    `created_on` Uint64,
    INDEX `from_index` GLOBAL ON (`from_uuid`),
    INDEX `from_to_index` GLOBAL ON (`from_uuid`, `to_uuid`),
    INDEX `to_index` GLOBAL ON (`to_uuid`),
    PRIMARY KEY (`id`)
)
WITH (
    AUTO_PARTITIONING_BY_SIZE = ENABLED,
    AUTO_PARTITIONING_BY_LOAD = DISABLED,
    AUTO_PARTITIONING_PARTITION_SIZE_MB = 2048,
    AUTO_PARTITIONING_MIN_PARTITIONS_COUNT = 1,
    KEY_BLOOM_FILTER = DISABLED
);

Поля таблицы

  • id - Уникальный идентификатор записи (автоинкремент)
  • from_uuid - UUID пользователя-источника связи
  • to_uuid - UUID пользователя-цели связи
  • data - JSON объект с дополнительными данными о связи
  • created_on - Временная метка создания записи (Unix timestamp)

Установка

npm install @dieugene/users-graph

Зависимости

  • @dieugene/ydb-serverless - для работы с YDB
  • @dieugene/utils - вспомогательные утилиты
  • @dieugene/key-value-db - для работы с базой данных ключ-значение

Использование

const usersGraph = require('@dieugene/users-graph');

// Создание связи между пользователями
await usersGraph.set(
    'user-uuid-1',        // from_uuid
    'user-uuid-2',        // to_uuid
    {                     // data (дополнительная информация)
        type: 'friend',
        strength: 0.8,
        note: 'Добавлен как друг'
    }
);

// Получение исходящих связей пользователя
const userConnections = await usersGraph.get('user-uuid-1');
console.log('Исходящие связи пользователя:', userConnections);

// Получение входящих связей пользователя
const incomingConnections = await usersGraph.get_incoming('user-uuid-1');
console.log('Входящие связи пользователя:', incomingConnections);

// Проверка существования конкретной связи
const specificConnection = await usersGraph.get('user-uuid-1', 'user-uuid-2');
console.log('Связь между пользователями:', specificConnection);

// Быстрая проверка наличия связи
const connectionExists = await usersGraph.exists('user-uuid-1', 'user-uuid-2');
console.log('Связь существует:', connectionExists); // true/false

// Очистка всех данных (только для тестов!)
// await usersGraph.clear(); // ОСТОРОЖНО: удаляет ВСЕ связи!

API

set(from_uuid, to_uuid, data)

Создает или обновляет связь между пользователями.

Важно: Функция автоматически предотвращает дублирование связей. При создании новой связи между теми же пользователями, предыдущая связь будет удалена и заменена новой.

Параметры:

  • from_uuid (string) - UUID пользователя-источника
  • to_uuid (string) - UUID пользователя-цели
  • data (object) - JSON объект с дополнительными данными о связи

Возвращает: Promise

Пример:

await usersGraph.set('123e4567-e89b-12d3-a456-426614174000', '987fcdeb-51a2-43d1-b567-123456789abc', {
    relationship_type: 'follower',
    created_by: 'system',
    metadata: {
        source: 'mobile_app',
        version: '1.2.3'
    }
});

get(from_uuid, to_uuid)

Получает связи пользователя из таблицы users_graph.

Параметры:

  • from_uuid (string) - UUID пользователя-источника связи
  • to_uuid (string, опционально) - UUID пользователя-цели связи

Возвращает: Promise - массив найденных связей

Поведение:

  • Если указан только from_uuid - возвращает все исходящие связи пользователя
  • Если указаны оба параметра - возвращает конкретную связь между двумя пользователями
  • Поле data в результатах автоматически парсится из JSON

Примеры:

// Получить все исходящие связи пользователя
const allConnections = await usersGraph.get('user-1-uuid');
console.log(allConnections);
// Результат: массив всех связей пользователя

// Получить конкретную связь между двумя пользователями  
const specificConnection = await usersGraph.get('user-1-uuid', 'user-2-uuid');
console.log(specificConnection);
// Результат: массив с одной связью (или пустой массив)

// Пример структуры результата:
// [
//   {
//     id: 1,
//     from_uuid: 'user-1-uuid', 
//     to_uuid: 'user-2-uuid',
//     data: { type: 'friendship', mutual: true },
//     created_on: 1704067200
//   }
// ]

exists(from_uuid, to_uuid)

Проверяет наличие связи между пользователями.

Параметры:

  • from_uuid (string) - UUID пользователя-источника связи
  • to_uuid (string) - UUID пользователя-цели связи

Возвращает: Promise - true если связь существует, false если нет

Описание: Быстрая проверка существования связи между двумя пользователями. Использует COUNT для оптимальной производительности без загрузки данных.

Примеры:

// Проверить, подписан ли пользователь на другого
const isSubscribed = await usersGraph.exists('follower-uuid', 'influencer-uuid');
if (isSubscribed) {
    console.log('Пользователь уже подписан');
} else {
    console.log('Пользователь не подписан');
}

// Проверить наличие дружбы
const areFriends = await usersGraph.exists('user-1-uuid', 'user-2-uuid');
console.log('Друзья:', areFriends); // true или false

// Условное создание связи
const alreadyConnected = await usersGraph.exists('user1', 'user2');
if (!alreadyConnected) {
    await usersGraph.set('user1', 'user2', { type: 'new_connection' });
}

clear()

Удаляет все записи из таблицы users_graph.

Параметры: Нет

Возвращает: Promise

Описание: ⚠️ ВНИМАНИЕ: Эта функция удаляет ВСЕ связи из таблицы users_graph. Операция необратима. Используйте с осторожностью! Рекомендуется для использования в тестовых средах или при полном сбросе системы.

Примеры:

// Очистка всех данных (ОСТОРОЖНО!)
await usersGraph.clear();
console.log('Все связи удалены');

// Проверка перед очисткой
const confirm = await getUserConfirmation('Удалить все связи?');
if (confirm) {
    await usersGraph.clear();
    console.log('База данных очищена');
}

// Использование в тестах
describe('Users Graph Tests', () => {
    beforeEach(async () => {
        await usersGraph.clear(); // Очистка перед каждым тестом
    });
    
    it('should create new connection', async () => {
        // тест логики...
    });
});

get_incoming(to_uuid)

Получает входящие связи пользователя из таблицы users_graph.

Параметры:

  • to_uuid (string) - UUID пользователя-цели связи

Возвращает: Promise - массив найденных входящих связей

Описание: Возвращает все входящие связи для указанного пользователя (где он является целью связи). Использует индекс to_index для оптимизации производительности. Поле data в результатах автоматически парсится из JSON.

Примеры:

// Получить всех подписчиков пользователя
const followers = await usersGraph.get_incoming('influencer-uuid');
console.log('Подписчики:', followers);

// Получить входящие запросы дружбы
const friendRequests = await usersGraph.get_incoming('user-uuid');
const pendingRequests = friendRequests.filter(req => req.data.status === 'pending');
console.log('Запросы дружбы:', pendingRequests);

// Анализ популярности пользователя
const incomingConnections = await usersGraph.get_incoming('popular-user-uuid');
const connectionTypes = incomingConnections.reduce((acc, conn) => {
    acc[conn.data.type] = (acc[conn.data.type] || 0) + 1;
    return acc;
}, {});
console.log('Типы входящих связей:', connectionTypes);

// Пример результата:
// [
//   {
//     id: 1,
//     from_uuid: 'follower-uuid',
//     to_uuid: 'influencer-uuid', 
//     data: { type: 'subscription', active: true },
//     created_on: 1704067200
//   }
// ]

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

Создание связи "дружба"

await usersGraph.set(
    'alice-uuid', 
    'bob-uuid', 
    { 
        type: 'friendship',
        mutual: true,
        since: '2024-01-15'
    }
);

Создание связи "подписка"

await usersGraph.set(
    'follower-uuid', 
    'influencer-uuid', 
    { 
        type: 'subscription',
        notification_enabled: true,
        subscription_level: 'premium'
    }
);

Создание связи с метаданными

await usersGraph.set(
    'user1-uuid', 
    'user2-uuid', 
    { 
        type: 'business_connection',
        company: 'Example Corp',
        role: 'partner',
        contract_id: 'CONT-2024-001',
        priority: 'high'
    }
);

Индексы

Таблица имеет следующие глобальные индексы:

  • from_index по полю from_uuid - обеспечивает быстрый поиск всех исходящих связей для конкретного пользователя
  • from_to_index по полям (from_uuid, to_uuid) - обеспечивает быстрый поиск конкретной связи между двумя пользователями и проверку существования связи
  • to_index по полю to_uuid - обеспечивает быстрый поиск всех входящих связей для конкретного пользователя

Требования

  • Node.js >= 14.0.0
  • Доступ к YDB (Yandex Database)
  • Настроенные переменные окружения для подключения к YDB

Лицензия

MIT