Skip to content

Instantly share code, notes, and snippets.

@FreePhoenix888
Last active November 15, 2023 06:27
Show Gist options
  • Save FreePhoenix888/0156f84def301f8d3f4d12d973272ac2 to your computer and use it in GitHub Desktop.
Save FreePhoenix888/0156f84def301f8d3f4d12d973272ac2 to your computer and use it in GitHub Desktop.
Описание дипа

Краткое описание

Deep это:

  • Связи
  • Пакеты, содержащие связи (сам пакет это тоже связь)
  • Обработчики вставки/обновления/удаления в любой поддерживаемой среде
  • Материализованный путь связей, деревья

Связи

Описание

У каждой связи может быть:

  • id (число)
  • Тип (type) (число)
  • Начало (from) (число)
  • Конец (to) (число)
  • Значение (строковое/числовое/объектное)

И типом, и началом, и концом является связь. Связи указывают на связи. То есть любая связь может быть типом/началом/концом для другой связи.

  • Message type: Type (всегда есть в дипе, находится в пакете @deep-foundation/core) from: 0 to: 0
  • Conversation type: Type from: 0 to: 0
  • Reply type: Type from: Message to: Conversation
  • UrgentMessage type: Message from: 0 to: 0
  • UrgentReply type: Reply from: UrgentMessage to: Conversation

Пакеты

В Deep есть встроенный тип Contain, который указывает принадлежность. Чаще всего он используется для того, что бы пакет Containил (содержал) в себе определённые связи, нужные для его работы. Если пакету для работы нужна связь, которая содержится в другом пакете - не нужно её Contain'ить в этот пакет. Достаточно того, что бы связь из текущего пакета указывала на связь из другого пакета любой стороной (началом или концом) То есть, если пакет deep-memo при установке должен установить пакет capacitor-device и capacitor-geolocation, то должны быть связи, которые указывают на связи из этих двух пакетов. Например можно воспользоваться пакетом @freephoenix888/dependency, создав связь типа Dependency с началом и концом указывающим на связь из capacitor-device, аналогично с capacitor-geolocation

await deep.insert({
  type_id: await deep.id("@freephoenix888/dependency", "Dependency"),
  from_id: await deep.id("deep-memo"),
  to_id: await deep.id("capacitor-device"),
  in: {
    // Входящая связь, то есть связь, у которой to указывает на текущую, то есть на Dependency
    data: [
      {
        type_id: containTypeLinkId,
        from_id: dependantPackageLinkId,
        string: {
          data: {
            value: `MyDependency`,
          },
        },
      },
    ],
  },
});

Note: выше в запросе использовался in, помимо этого есть out, который означает "Исходящую" связь, то есть связь, у которой from это текущая связь. Rule of thumb: Исходящая/out-from, Входящая/in-to

Обработчики

Описание

Обработчики позволяют обрабатывать такие события у связей:

  • Вставка
  • Обновление
  • Удаление

Обработчики могут запускаться в разных средах. Одна из самых популярных - докер среда, которая использует определённый инструмент, допустим node, что бы запустить JavaScript код. Так же есть и синхронный хендлер, который принято называть plv8 хендлером, так как он использует plv8 для запуска JavaScript кода внутри PostgreSQL. Синхронный хендлер выполняется сразу же после события, и если хендлер выполнится не успешно, то ошибка выпадет, а операция не выполнится. Допустим ваш синхронный обработчик может валидировать данные в связях определённого типа, и если оне не валидны - выбрасывать ошибку, следовательно обновление связи не будет выполнено по этой причине

Пример

Рассмотрим простейший пример асинхронного обработчика:

  • Имеем связь Double (type: Type, from: 0, to: 0)
  • Имеем SyncTextFile содержащий такой код:
async ({ data: { newLink: doubleLink } }) => {
  const value = doubleLink.value?.value;
  if (!value) {
    throw new Error(`Link ${doubleLink.id} has not value`);
  }
  return value * 2;
};
  • Имеем Handler (from: dockerSupportsJs (из @deep-foundation/core), to: наш SyncTextFile)
  • Имеем HandleUpdate (from: тип Double, to: наш Handler) Note: HandleUpdate имеет начало в виде ТИПА Double, а не конкретного Double (экземпляра), то есть "Тип Double обрабатывается хендлером"
  • Вставляем связь Double
  • Обновляем связь Double (присваиваем ей значение)
  • Видим результат асинхронного хендлера в виде связей: При успешном выполнении: Наша связь --Then-> Promise --Resolved-> PromiseResult (с object value) При ошибке: Наша связь --Then-> Promise --Rejected-> PromiseResult (с object value)

Note: не обязательно полагаться на результат в PromiseResult. Вы можете сделать так, что бы ваш обработчик не возвращал ничего, но вставлял определённые связи как результат. Например, если вы хотите, что бы при вставке связи Double вставлялась связь DoubleResult с результатом умножения на 2, то вы можете это сделать, воспользовавшись Дип Клиентом, который так же пробрасывается в ваш хендлер

Таблицы

  • links
  • strings
  • numbers
  • objects (на самом деле JSON, следовательно можно вставить число/строку в таблицу objects, а не только объект)
  • selectors

Дип клиент

Вставка

Примеры

Вставка связи с типом 1

await deep.insert({
  type_id: 1,
});

Вставка связи с типом Type из пакета @deep-foundation/core

await deep.insert({
  type_id: await deep.id("@deep-foundation/core", "Type"),
});

Вставка связи с типом Reply из пакета messenger

await deep.insert({
  type_id: await deep.id("messenger", "Reply"),
  from_id: await deep.id(deep.linkId, "Моё сообщение"),
  to_id: await deep.id(deep.linkId, "Мой диалог"),
});

Вставка строкового значения для связи 100

await deep.insert(
  {
    link_id: 100,
    value: "Моё значение",
  },
  {
    table: "strings",
  }
);

Получение

Примеры

Получение связи с типом 1

await deep.select({
  type_id: 1,
});

Получение связи с типом Type из пакета @deep-foundation/core

await deep.select({
  type_id: await deep.id("@deep-foundation/core", "Type"),
});

Получение связи с типом Reply из пакета messenger

await deep.select({
  type_id: await deep.id("messenger", "Reply"),
  from_id: await deep.id(deep.linkId, "Моё сообщение"),
  to_id: await deep.id(deep.linkId, "Мой диалог"),
});

Получение строкового значения для связи 100

await deep.select(
  {
    link_id: 100,
    value: "Моё значение",
  },
  {
    table: "strings",
  }
);

Обновление

Note: Прошу обратить внимание, что в примерах для упрощения используется {id: 1} в качестве ограничения, но использовать можно любое другое ограничение, например {from: 100, to: 150}

Примеры

Обновление начала

await deep.update(
  {
    id: 1,
  },
  {
    from_id: 5,
  }
);

Обновление строкового значения

await deep.update(
  {
    link_id: 1,
  },
  {
    value: "Моё новое значение",
  },
  {
    table: "strings",
  }
);

Удаление

Примеры

Удаление связи с типом 1

await deep.delete({
  type_id: 1,
});

Удаление связи с типом Type из пакета @deep-foundation/core

await deep.delete({
  type_id: await deep.id("@deep-foundation/core", "Type"),
});

Удаление связи с типом Reply из пакета messenger

await deep.delete({
  type_id: await deep.id("messenger", "Reply"),
  from_id: await deep.id(deep.linkId, "Моё сообщение"),
  to_id: await deep.id(deep.linkId, "Мой диалог"),
});

Удаление строкового значения для связи 100

await deep.delete(
  {
    link_id: 100,
    value: "Моё значение",
  },
  {
    table: "strings",
  }
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment