CRDT を採用した、型安全でリアルタイム協業をサポートするグラフデータベースです。

2026/04/21 19:33

CRDT を採用した、型安全でリアルタイム協業をサポートするグラフデータベースです。

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

このテキストでは、タブ間を同期する Yjs CRDT を使用してメモリ内グラフデータベースを構築するためのアルファ品質のソフトウェアである

@codemix/graph
および
@codemix/y-graph-storage
を紹介しています。インストールは
pnpm add @codemix/graph
を実行することで容易であり、ネイティブ依存関係は一切必要ありません。Node またはバンドラー内でも動作します。ユーザーは
GraphSchema
オブジェクトを使用してスキーマを定義し、プロパティタイプ(Zod、Valibot、ArkType、または独自定義をサポート)はクエリやメタテーションを通じて直接流れ、手動での型変換を必要としません。ハッシュ、B-tree、全文検索を含むスキーマインデックスはインラインで宣言され、遅やかに構築され、増分的に維持されます。

このライブラリは、顶点と辺の作成および読み取りを行うための型安全なインターフェースを提供します(例:

addVertex
addEdge
get
)。引数はコンパイル時およびランタイムの両方で検証されます。Gremlin 風のカバレッジ API(
GraphTraversal
)が提供されており、TypeScript がすべてのラベル、プロパティキー、ハップをスキーマに対してチェックします。フィルタリング機能には完全一致または述語(
hasLabel
where
を通じて)が含まれ、辺の移動は
OWNS
FOLLOWS
などの特定の関係に従います。

コラボレーションのため、

InMemoryGraphStorage
YGraph
に交換することでオフラインファースト同期が有効になり、
WebsocketProvider
などのプロバイダーを通じて自動的に無衝突な同期をサポートします。細かい粒度の変更購読(
graph.subscribe
)はローカルおよびリモートのメタテーションに対してイベントを発行し(例:顶点の追加、辺の削除)、ライブクエリはカバレッジをラップし、基盤となるデータが変更になると自動的に再発行されます。コラボレーティブなプロパティタイプには
ZodYText
および
ZodYArray
が使用され、値が自動的に変換されるため、ピアは衝突なしで更新を見ることができます。

さらに、このパッケージは

parseQueryToSteps
を介して Cypher 互換の文字列クエリをサポートします。この機能は現在、リードオンリーモードおよび API または LLM が MCP サーバーとして動作する際に適したパラメータ付きクエリを有効にしますが、このモードでの完全な書き込み操作はまだサポートされていません。ツールは MIT ライセンスで公開されており、元々は Charles Pick(codemix の創設者)による研究プロジェクトでした。Y.js へのサポートが含まれるように改修され、Opus 4.5 で Cypher 風の言語機能を追加しました。宣伝コンテンツでは、チャット、図表、共同編集を通じてコーディングエージェントを導くための製品進化のプラットフォームとして
codemix
を取り上げています。

本文

航空路線のデモンストレーション:大手航空会社の実際のネットワークを読み込み、TypeScript でクエリを実行するライブデモ。また、あなたの顔写真を壁に追加することも可能で、これは「@codemix/graph」と「@codemix/y-graph-storage」によって駆動されています。これらはリアルなグラフデータベースであり、開いているすべてのタブを通じて Yjs CRDT を介して同期されます。ご自身のプロフィールを追加し、人々の配置を再調整したり、つながりを描画したりできます。

インストール:

npm
からパッケージをインストールしてください。ネイティブ依存関係は不要で、Node.js やバンドラが動作するあらゆる環境で利用可能です。

$ pnpm add @codemix/graph

※注:本ソフトウェアはアルファ品質です。Codemix 内でのプロダクション使用や既存のユースケースでは順調に機能していますが、ご自身のデータと組み合わせる際には十分ご注意ください。

スキーマの定義: 頂点(vertices)、辺(edges)、インデックスを普通オブジェクトとして記述します。プロパティの型はすべてのクエリ、走査、および変異操作を通じて適用され、キャストやランタイムでの予期せぬ挙動はありません。

import { Graph, GraphSchema, InMemoryGraphStorage } from "@codemix/graph";
import { z } from "zod";

const schema = {
  vertices: {
    User: {
      properties: {
        email: { type: z.email(), index: { type: "hash", unique: true } },
        name:  { type: z.string() },
      },
    },
    Repo: {
      properties: {
        name:  { type: z.string() },
        stars: { type: z.number() },
      },
    },
  },
  edges: {
    OWNS:    { properties: {} },
    FOLLOWS: { properties: {} },
  },
} as const satisfies GraphSchema;

const graph = new Graph({ schema, storage: new InMemoryGraphStorage() });

→ 標準的なスキーマライブラリ(Zod、Valibot、ArkType、またはご自身のものであり)に対応可能です。 → すべての変異操作において型検証が実行され、

addVertex
addEdge
、および
updateProperty
でプロパティの正当性がチェックされます。 → インラインでインデックスを宣言可能で、遅延ビルドおよび段階的な維持が可能(ハッシュ、B ツリー、フルテキスト検索など)。

データの追加: 頂点と辺はグラフインスタンスを通じて追加されます。引数のプロパティには、コンパイル時かつランタイムの両方でスキーマに対する検証が適用されます。

// 頂点の追加 —— アーギュメントは各ラベルのプロパティスキーマに対して型付けされています
const alice  = graph.addVertex("User", { name: "Alice", email: "alice@example.com" });
const bob    = graph.addVertex("User", { name: "Bob",   email: "bob@example.com" });
const myRepo = graph.addVertex("Repo", { name: "my-repo", stars: 0 });

// 辺の追加
graph.addEdge(alice, "OWNS",    myRepo, {});
graph.addEdge(bob,   "FOLLOWS", alice,  {});

// プロパティの読み取り —— 型はスキーマから取得されます
alice.get("name");     // string
myRepo.get("stars");   // number

// インプレースでの更新
graph.updateProperty(myRepo, "stars", 42);
// または、要素自体を通じて
myRepo.set("stars", 42);

型安全なクエリの作成: Gremlin スタイルの走査 API を提供しており、馴染み深いステップ名を使用できますが、すべてのラベル、プロパティキー、およびホップについて TypeScript がスキーマに対してチェックを実行します。

走査の開始

import { GraphTraversal } from "@codemix/graph";

const g = new GraphTraversal(graph);

for (const path of g.V().hasLabel("User")) {
  path.value.get("name");   // string  ✓
  path.value.get("email");  // string  ✓
}

プロパティによるフィルタリング: 厳密な一致または予測器(predicate)を用いてフィルタリング可能です。

const [alice] = g.V()
  .hasLabel("User")
  .has("email", "alice@example.com");

const seniors = g.V()
  .hasLabel("User")
  .where((v) => v.get("name").startsWith("A"));

辺の走査: ユーザーからリポジトリへの「OWNS」边を追跡します。

for (const path of g.V()
  .hasLabel("User")
  .has("email", "alice@example.com")
  .out("OWNS").hasLabel("Repo")) {
  path.value.get("stars"); // number — Repo のスキーマから型付けされています
}

ラベル付けと選択: 複数のホップでの頂点をキャプチャし、それらを共通してプロジェクトします。

for (const { user, repo } of g.V()
  .hasLabel("User").as("user")
  .out("FOLLOWS")
  .out("OWNS").hasLabel("Repo").as("repo")
  .select("user", "repo")) {
  console.log(
    user.value.get("name"),   // string
    repo.value.get("stars"),  // number
  );
}

オフラインファーストの同期とリアルタイムなコラボレーション:

InMemoryGraphStorage
YGraph
に置き換えるだけで、グラフ全体は Yjs CRDT ドキュメントの中に存在します。すべての走査、Cypher クエリ、およびインデックスは変更されず、その上にコンフリクトのない同期が追加されます。

プロバイダーの接続

import * as Y from "yjs";
import { WebsocketProvider } from "y-websocket";
import { YGraph } from "@codemix/y-graph-storage";

const doc = new Y.Doc();
const graph = new YGraph({ schema, doc });

// 任意の Yjs プロバイダーをプラグイン —— 同期は自動で行われます。
// ルームに参加するすべてのピアは同じグラフを見ます。
const provider = new WebsocketProvider("wss://my-server", "graph-room", doc);

微細な変更への購読: ローカルおよびリモートの両方の変異についてイベントが発火します。

const unsubscribe = graph.subscribe({
  next(change) {
    // change.kind は次のいずれか:
    //   "vertex.added" | "vertex.deleted"
    //   "edge.added"   | "edge.deleted"
    //   "vertex.property.set" | "vertex.property.changed"
    console.log(change.kind, change.id);
  },
});

ライブクエリ: 走査をラップし、結果セットが変化する可能性があるたびに再発火します。

const topRepos = graph.query((g) =>
  g.V().hasLabel("Repo").order("stars", "desc").limit(10)
);

const unsubscribe = topRepos.subscribe({
  next() {
    for (const path of topRepos) {
      console.log(path.value.get("name"), path.value.get("stars"));
    }
  },
});

// どこかで(あるいはリモートピアからでも)Repo を追加または更新すると、
// サブスクライバーが自動的にトリガーされます。
graph.updateProperty(myRepo, "stars", 99);

コラボレーティブなプロパティ型

import { ZodYText, ZodYArray } from "@codemix/y-graph-storage";
import { z } from "zod";

// スキーマにおいて Y.Text / Y.Array / Y.Map プロパティを宣言します
const schema = {
  vertices: {
    Document: {
      properties: {
        title:   { type: ZodYText },          // コラボレーティブな文字列
        tags:    { type: ZodYArray(z.string()) }, // コラボレーティブな配列
      },
    },
  },
  edges: {},
} as const satisfies GraphSchema;

// 単なる値は自動的に変換されるため、Y.* を手動で構築する必要はありません
const doc = graph.addVertex("Document", { title: "Hello", tags: ["crdt"] });

// インプレースでの変異 —— すべてのピアが無衝突で変化を検知します
doc.get("title").insert(5, ", world");
doc.get("tags").push(["graph"]);

API および LLM 用の Cypher クエリ: 同じグラフは、Cypher 互換の文字列言語を通じてクエリ可能です。これは MCP サーバーを通じてデータを LLM に公開する場合や、トリバースルライブラリをバンドルせずに外部クライアントからアドホックなクエリを受け付ける場合に特に適しています。

解析と実行

import { parseQueryToSteps, createTraverser } from "@codemix/graph";

const { steps, postprocess } = parseQueryToSteps(`
  MATCH (u:User)-[:OWNS]->(r:Repo)
  WHERE r.stars > 100
  RETURN u.name, r.name
  ORDER BY r.stars DESC
  LIMIT 10
`);

const traverser = createTraverser(steps);
for (const row of traverser.traverse(graph, [])) {
  console.log(postprocess(row));
  // { u: { name: "Alice" }, r: { name: "my-repo" } }
}

パラメータ付きクエリ: 文字列_interpolation_ を避けるためにパラメータを渡します。

const { steps, postprocess } = parseQueryToSteps(`
  MATCH (u:User { email: $email })-[:OWNS]->(r:Repo)
  RETURN r.name, r.stars
`);

const traverser = createTraverser(steps);
const rows = Array.from(
  traverser.traverse(graph, [{ email: "alice@example.com" }])
).map(postprocess);

変異操作:

CREATE
MERGE
SET
DELETE
のすべてがサポートされています。

const { steps } = parseQueryToSteps(`
  MATCH (r:Repo { name: $name })
  SET r.stars = r.stars + 1
`);

createTraverser(steps).traverse(graph, [{ name: "my-repo" }]);

// 読み取り専用を強制 —— 書き込み節句がある場合に `ReadonlyGraphError` を投げる
const { steps: safeSteps } = parseQueryToSteps(query, { readonly: true });

ライセンスと履歴: このパッケージは MIT ライセンスの下で利用可能です。元々は codemix の創業者であり、著名な

ts-sql
デモの著者である Charles Pick による研究プロジェクトとして書かれました。その後、codemix の構築中に構造化された知識グラフが必要となり、コードを適応させ Y.js サポートを追加し、さらに Opus 4.5 では Cypher リックなクエリ言語を導入しました。

GitHub でスターを付ける 「ここにいる間」に、製品の単一の真実のソースを持ってみましょう。人間と AI のためです。codemix は、あなたが実際に意味するもの(ビジネスドメイン、ユーザーフロー、概念、制約など)を捉え、コードベースと自動的に同期を保ち続けます。チャット、図、または共同編集を通じて製品を変えていきましょう。開発およびレビューにおいてコーディングエージェントを導き、真の理解を持ってコードを検証しましょう。あなたのチーム内のすべてのエージェントが同じコンテキストを共有します。全く新しいものを創造するか、既存のコードベースをインポートして開始してください。

何か全く新しいものを作りましょう codemix を無料でお試しください。クレジットカードは不要です。

同じ日のほかのニュース

一覧に戻る →

2026/04/22 2:14

Vercel の侵害事件:OAuth 攻撃によるプラットフォーム環境変数のリスク浮上

## Japanese Translation: 最も重要な教訓は、攻撃者がサードパーティの OAuth の侵害を利用して、2024 年 6 月頃に始まり公開された 2026 年 4 月 19 日まで約 22 カ月到達した間、Vercel の内部システムへの侵入を成し遂げたという点です。この期間中、敵対者は顧客の機密情報や従業員のデータ、OpenAI のようなサービスにリンクされた認証情報を盗みました。この侵害は Vercel の環境変数モデルによって拡大されました:「sensitive」と明示的にマークされていない変数は静態で暗号化されて保存されていたため、内部へのアクセスが得られた時点で読み取ることができました。これにより、侵害された OAuth アプリケーションから従業員の Google Workspace アカウントへ、さらに非機密の環境変数の列挙および下流の認証情報の悪用への横移動が可能になりました。 Vercel の CEO ガビエル・ロイシュは、攻撃者の驚くべき速度と Vercel に対する深い理解を AI の拡張作用に帰因しました。地下フォーラムで ShinyHunters と関連するハッカー集団が従業員のレコード約 580 件、トークン、および API キーの保有を主張していますが、公式な確認が出るまでこれらの主張は検証されていません。この出来事は、LiteLLM(2024 年 3 月 24 日)、Axios(2024 年 3 月 31 日)、Codecov(2021 年)、CircleCI(2023 年)、Snowflake(2024 年)などの主要ソフトウェア提供者を標的とするサプライチェーン攻撃のより広範な 2026 年の傾向を反映しています。 即時の是正策として、すべての非機密 Vercel 環境変数を再設定し、アプリケーションを再起動する必要があります。パスワードのみの再設定では、すでに古い認証情報を既に使用していた以前のデプロイメントが無効化できないためです。調査は困難に直面しており、デフォルトの Google Workspace ログがわずか 6 ヶ月間のみ保持されるため、正確なエントリーポイントや最も早期の侵害活動が隠れてしまう可能性があります。究極的には、セキュリティ環境は、現代のサプライチェーン構成において「非機密」というラベルが静的な未暗号化データを保護することを失敗するという危険なギャップを開示しています。

2026/04/22 0:29

CrabTrap:実環境におけるエージェントを保護するための、LLM を採用した「審査官」として機能する HTTP プロキシ

## Japanese Translation: Capital One の完全子会社であり、米国ユタ州ソルトレイクシティ 650 S 500W スイート 300 に本社を置く Brex LLC は、コア・バンキングサービスにおいて関係ないパートナー銀行を利用する金融プラットフォームとして運営されています。支払いサービスは Brex Payments LLC(免許を受けた資金送金業者)が管理しており、Vault fonds には即座に FDIC の保険が付与され、Treasury fonds はパートナー・プログラム銀行へ転送される際に FDIC 資格を取得します。証券は Brex Treasury LLC を通じて提供され、同社は各株式で $1.00 の価値を維持することを目的とするファンドへの投資を行うが、これは保証されておらず、収益は市場状況によって変動し、元本損失の可能性もあることに注意すべきです。クレジットカードは製品により異なります:Brex Mastercard® Corporate は Emigrant Bank、Fifth Third Bank N.A.、または Airwallex(オランダ)B.V. が発行し、Brex Commercial Card は Visa ライセンスの下で Sutton Bank が発行します。現在、ATM アクセスは利用できませんが、すべてのローンには承認が必要です。また、Brex LLC は法的、税務、直接的投資アドバイスを提供しません。料金プランはユーザー 1 人あたり月 $0 から開始し、高度な機能を必要とする場合はユーザー 1 人あたり月 $12 です。資金を投入する前に、これらの構造的ニュアンス、パートナー依存関係、および本質的な市場リスクを考慮する必要があります。

2026/04/18 19:53

スティーブンのソーセージロールは、今なお最も影響力の大きいパズルゲームの一つとして確立されている。

## Japanese Translation: この原稿は『Stephen's Sausage Roll』の 10 周年を祝い、パズルゲームの定義を継続的に確立し続けてきたタイムレスな傑作として位置づけています。2016 年 4 月に PC でリリースされ、ゲームプレイについてほとんど何も明らかにしない予告編と共に登場したこの oversized fork-based ソコバンタイトル(プレイヤーがブロック、ラダー、フォークを使用して肉を焼くためにソーセージを押す)は、細心の注意を払った設計、深いパズル層、そして公平だが困難な難易度を通じて直ちにプレイヤーを魅了しました。ゲームは Stephen Lavelle 氏(Increpare Games)によってデザインされており、ソコバンの設計を探求するグリッドベースのパズルの作成を可能にする PuzzleScript も以前にリリースしています。開発者は『Stephen's Sausage Roll』を「削ぎ落とされた純粋さ」の傑作として評価し、「ソーセージのような」ゲームや新しい世代のソコバンタイトルを鼓舞していると述べています。Alan Hazelden 氏(*A Monster's Expedition*)はそれを「少ないもので多くのことを成し遂げるためのマスタークラス」と呼び、Patrick Traynor 氏(*Patrick's Parabox*)はそれが純粋なパズルデザインを追求するようそしてタイトルに自分の名前を含めるよう刺激したと述べています。Gwen Frey 氏(*Kine*, *Lab Rat*)はそれを「ソコバンへのゲートウェイ薬物」と呼び、彼女のキャリアを変えたと言っています。Corey Martin 氏(*Bonfire Peaks*)はその純粋さを「1976 年の Ramones」に例え、Joseph Mansfield 氏(Thinky Games)はそれが手慣れた古典的なソコバンから深みのある焦点を当てた設計への転換を標記していると指摘しています。Thinky Games は開発者の証言をフィーチャーした 10 歳の誕生日祭りを開催しており、これにより『Stephen's Sausage Roll』がどのようにジャンルを形成し続けているかが強調され、その遺産がリソースに制約のある志の高い創作者のための成功したブループリントとして検証され、新しい世代のパズル愛好家に enduring するために確保されています。

CRDT を採用した、型安全でリアルタイム協業をサポートするグラフデータベースです。 | そっか~ニュース