diff --git a/docs/README.md b/docs/README.md index 0be3f1b9..846bcb79 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,7 +9,7 @@ This website is built using [Docusaurus](https://docusaurus.io/), a modern stati Install all dependencies from the monorepo root: ``` -$ pnpm install +pnpm install ``` ### Local Development @@ -17,7 +17,7 @@ $ pnpm install Start the Docusaurus dev server for the docs site: ``` -$ pnpm --filter docs start +pnpm --filter docs start ``` This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. @@ -27,7 +27,7 @@ This command starts a local development server and opens up a browser window. Mo Build the static site: ``` -$ pnpm --filter docs build +pnpm --filter docs build ``` This command generates static content into the `build` directory and can be served using any static content hosting service. @@ -37,13 +37,13 @@ This command generates static content into the `build` directory and can be serv Using SSH: ``` -$ USE_SSH=true pnpm --filter docs deploy +USE_SSH=true pnpm --filter docs deploy ``` Not using SSH: ``` -$ GIT_USER= pnpm --filter docs deploy +GIT_USER= pnpm --filter docs deploy ``` If you are using GitHub Pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/docs/blog/2019-05-28-first-blog-post.md b/docs/blog/2019-05-28-first-blog-post.md deleted file mode 100644 index d3032efb..00000000 --- a/docs/blog/2019-05-28-first-blog-post.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -slug: first-blog-post -title: First Blog Post -authors: [slorber, yangshun] -tags: [hola, docusaurus] ---- - -Lorem ipsum dolor sit amet... - - - -...consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/docs/blog/2019-05-29-long-blog-post.md b/docs/blog/2019-05-29-long-blog-post.md deleted file mode 100644 index eb4435de..00000000 --- a/docs/blog/2019-05-29-long-blog-post.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -slug: long-blog-post -title: Long Blog Post -authors: yangshun -tags: [hello, docusaurus] ---- - -This is the summary of a very long blog post, - -Use a `` comment to limit blog post size in the list view. - - - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/docs/blog/2021-08-01-mdx-blog-post.mdx b/docs/blog/2021-08-01-mdx-blog-post.mdx deleted file mode 100644 index 0c4b4a48..00000000 --- a/docs/blog/2021-08-01-mdx-blog-post.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -slug: mdx-blog-post -title: MDX Blog Post -authors: [slorber] -tags: [docusaurus] ---- - -Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/). - -:::tip - -Use the power of React to create interactive blog posts. - -::: - -{/* truncate */} - -For example, use JSX to create an interactive button: - -```js - -``` - - diff --git a/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg b/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg deleted file mode 100644 index 11bda092..00000000 Binary files a/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg and /dev/null differ diff --git a/docs/blog/2021-08-26-welcome/index.md b/docs/blog/2021-08-26-welcome/index.md deleted file mode 100644 index 349ea075..00000000 --- a/docs/blog/2021-08-26-welcome/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -slug: welcome -title: Welcome -authors: [slorber, yangshun] -tags: [facebook, hello, docusaurus] ---- - -[Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog). - -Here are a few tips you might find useful. - - - -Simply add Markdown files (or folders) to the `blog` directory. - -Regular blog authors can be added to `authors.yml`. - -The blog post date can be extracted from filenames, such as: - -- `2019-05-30-welcome.md` -- `2019-05-30-welcome/index.md` - -A blog post folder can be convenient to co-locate blog post images: - -![Docusaurus Plushie](./docusaurus-plushie-banner.jpeg) - -The blog supports tags as well! - -**And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config. diff --git a/docs/blog/2025-06-11-hypergraph-alpha-released.md b/docs/blog/2025-06-11-hypergraph-alpha-released.md new file mode 100644 index 00000000..6c70074d --- /dev/null +++ b/docs/blog/2025-06-11-hypergraph-alpha-released.md @@ -0,0 +1,63 @@ +--- +slug: hypergraph-alpha-released +title: Announcing Hypergraph - A New Chapter in Web Development +date: 2025-06-11 +authors: [nik, pablo] +tags: [release, alpha, hypergraph] +--- + +After months of development and countless conversations with developers like you, **we're thrilled to unveil the Alpha version of Hypergraph**. This is more than just another data layer—it's a fundamental rethinking of how we build collaborative, secure, and offline-first Web3 applications. + + + +## Why We Built Hypergraph + +The challenges of modern app development are clear: users expect real-time collaboration, bulletproof security, and apps that work flawlessly even when offline. Traditional architectures force uncomfortable trade-offs between these needs. We knew there had to be a better way. + +Enter Hypergraph, built on two core innovations: a local-first architecture that puts your data where it belongs—on the client—and our implementation of the GRC-20 standard for truly composable knowledge graphs. + + + +## What Makes Hypergraph Different + +At its heart, Hypergraph is local-first. Every piece of data is stored on the client, making reads and writes instant—no waiting for server responses. When you're online, our CRDT-based sync ensures your data flows seamlessly between devices and collaborators. When you're offline? Everything just works. + +Security isn't an afterthought—it's built into our foundation. With end-to-end encryption, your data is only readable by those you explicitly trust. No intermediaries, no compromises. + +The real magic happens with our GRC-20 Knowledge Graph. It's not just a data format; it's a new way of thinking about how information connects and flows through your applications. Every mutation, whether it's adding a note or updating a relationship, becomes part of a larger, interoperable knowledge network. + + + +## Looking Ahead + +We're launching this alpha today, June 10, 2025, and we're targeting a beta release in August. Our roadmap to a stable release in Q4 2025 is ambitious but achievable with your help. The beta will bring enhanced stability, an expanded API surface, and comprehensive documentation based on your feedback. + +## Join the Alpha Today + +Getting started is simple. Install our SDK: + +```bash +# TODO: ADD INSTALLER TO NPM npm install @hypergraph/sdk-alpha +``` + +Head to our [Quickstart guide](/docs/quickstart) to build your first Hypergraph app, or dive deep into our [API Reference](/docs/api-reference) to explore the possibilities. We support Node.js and modern browsers, with React hooks that make integration a breeze. + +## A Note on What to Expect + +Let's be transparent: this is an alpha release. You'll see rapid changes as we iterate based on your feedback. Some features are still experimental, and you might encounter sync delays with larger graphs or limited support on mobile browsers. But that's exactly why we need you—every bug report, feature request, and question helps shape Hypergraph's future. + +## Let's Build Together + +Your voice matters in this journey. Share your experiences, report issues, or just chat with us: + +- Found a bug? [Open an issue on GitHub](https://github.com/graphprotocol/hypergraph/issues) + +- Want to chat? Find us on [Discord](https://discord.gg/graphprotocol) + +We read every message and your feedback directly shapes our roadmap. + +## Ready to Shape the Future? + +This is just the beginning. Hypergraph represents our vision for the future of Web3 development, but it's your creativity and feedback that will help us realize its full potential. [Get started with the Quickstart](/docs/quickstart), and explore our [API Reference](/docs/api-reference), and join us in building the next generation of collaborative, decentralized applications. + +We can't wait to see what you'll create. diff --git a/docs/blog/authors.yml b/docs/blog/authors.yml index 8bfa5c7c..a5d701b2 100644 --- a/docs/blog/authors.yml +++ b/docs/blog/authors.yml @@ -1,23 +1,23 @@ -yangshun: - name: Yangshun Tay - title: Front End Engineer @ Facebook - url: https://github.com/yangshun - image_url: https://github.com/yangshun.png +pablo: + name: Pablo Carranza Velez + title: Engineering Manager @ Edge & Node + url: https://github.com/pcarranzav + image_url: https://avatars.githubusercontent.com/u/2223590?v=4 + permalink: /all-pablo-articles page: true socials: - x: yangshunz - github: yangshun + x: https://x.com/pcarranzav + github: https://github.com/pcarranzav -slorber: - name: Sébastien Lorber - title: Docusaurus maintainer - url: https://sebastienlorber.com - image_url: https://github.com/slorber.png +nik: + name: Nik + title: Hypergraph Lead Engineer @ Geo + # url: + image_url: https://ca.slack-edge.com/T047DS7N1PE-U07PPQ3GN7Q-gafcee4ad6e3-512 page: - # customize the url of the author page at /blog/authors/ - permalink: '/all-sebastien-lorber-articles' - socials: - x: sebastienlorber - linkedin: sebastienlorber - github: slorber - newsletter: https://thisweekinreact.com + permalink: /all-nik-articles + # socials: + # x: + # linkedin: + # github: + # newsletter: https://thisweekinreact.com diff --git a/docs/blog/tags.yml b/docs/blog/tags.yml index bfaa778f..e2eee19e 100644 --- a/docs/blog/tags.yml +++ b/docs/blog/tags.yml @@ -1,19 +1,40 @@ -facebook: - label: Facebook - permalink: /facebook - description: Facebook tag description - -hello: - label: Hello - permalink: /hello - description: Hello tag description - docusaurus: label: Docusaurus permalink: /docusaurus description: Docusaurus tag description -hola: - label: Hola - permalink: /hola - description: Hola tag description +release: + label: Release + permalink: /release + description: Release announcements and updates + +alpha: + label: Alpha + permalink: /alpha + description: Alpha version releases and features + +hypergraph: + label: Hypergraph + permalink: /hypergraph + description: Posts about Hypergraph features and updates + +knowledge-graphs: + label: Knowledge Graphs + permalink: /knowledge-graphs + description: Articles about knowledge graph concepts, best practices, and implementation + +education: + label: Education + permalink: /education + description: Educational content and tutorials + +best-practices: + label: Best Practices + permalink: /best-practices + description: Guidelines, conventions, and recommended practices + +grc20: + label: GRC-20 + permalink: /grc20 + description: Content related to the GRC-20 knowledge graph specification + diff --git a/docs/docs/core-concepts.md b/docs/docs/core-concepts.md index 8896c19e..b3837040 100644 --- a/docs/docs/core-concepts.md +++ b/docs/docs/core-concepts.md @@ -11,14 +11,245 @@ Hypergraph re-imagines traditional client–server apps as **local-first**, **pe ## Table of Contents +- [Knowledge Graphs and GRC-20](#knowledge-graphs-and-grc-20) - [Spaces](#spaces) - [Identities](#identities) - [Inboxes](#inboxes) -- [Knowledge Graph](#knowledge-graph) - [Events & CRDTs](#events--crdts) - [Security Model](#security-model) --- +## Knowledge Graphs and GRC-20 + +Hypergraph adopts **GRC-20** as its canonical data format. Every mutation you perform through the Hypergraph SDK—whether it's adding a note, uploading a photo, or inviting a collaborator—ultimately becomes a set of GRC-20 values bundled into an edit. Once the edit is posted, it becomes part of the global knowledge graph—instantly connecting your data to a world of interoperable apps, spaces, and users. From that moment the edit is immutable and immediately queryable via Hypergraph's hooks and GraphQL APIs. + +### 1. The GRC-20 Standard +The GRC-20 standard defines how knowledge is structured, shared, and connected in a decentralized, composable way—enabling interoperability across web3 applications. It specifies the core building blocks: entities, types, properties, relations, and values. Read the [GRC-20 spec on GitHub](https://github.com/graphprotocol/graph-improvement-proposals/blob/main/grcs/0020-knowledge-graph.md). + +### 2. Core Data Model Concepts + +To illustrate the core pieces of a knowledge graph, we'll break down a single sentence: + +> **"Teresa, a photographer, owns a Fujifilm camera."** + +#### The Value Model +In GRC-20, each **entity** is a node in the graph with a list of **values**. Each value attaches a **property** (by ID) and a literal value (plus options). Properties define the data type and constraints for their values. **Relations** are first-class objects that connect entities and can have their own properties and metadata. + +**Example property definition:** +```json +{ + "id": "PROFESSION_ATTR_ID", + "data_type": "TEXT" +} +``` + +**Example entity with values:** +```json +{ + "id": "Teresa_ID", + "values": [ + { "property": "PROFESSION_ATTR_ID", "value": "photographer" } + ] +} +``` + +**Example in code:** +```ts +Graph.createEntity({ + name: 'Teresa', + types: [PERSON_TYPE_ID], + values: [ + { property: PROFESSION_ATTR_ID, value: 'photographer' } + ] +}); +``` + +#### IDs: Where Do They Come From? +Every entity, attribute, and relation has a unique ID (usually a string, e.g. `PERSON_TYPE_ID`). These are generated per your schema or space, and are required for all operations. + +#### Entities & Types +**Entity:** A unique thing in the graph (e.g., `Teresa`, `Camera`). +**Type:** A category for entities (e.g., `Person`, `Device`). + +```ts +const PERSON_TYPE_ID = 'PERSON_TYPE_ID'; +const DEVICE_TYPE_ID = 'DEVICE_TYPE_ID'; +const PROFESSION_ATTR_ID = 'PROFESSION_ATTR_ID'; +const BRAND_ATTR_ID = 'BRAND_ATTR_ID'; + +const { id: cameraId, ops: cameraOps } = Graph.createEntity({ + name: 'Camera', + types: [DEVICE_TYPE_ID], + values: [ + { property: BRAND_ATTR_ID, value: 'Fujifilm' }, + ], +}); + +const { id: teresaId, ops: teresaOps } = Graph.createEntity({ + name: 'Teresa', + types: [PERSON_TYPE_ID], + values: [ + { property: PROFESSION_ATTR_ID, value: 'photographer' }, + ], +}); +``` + +#### Properties vs. Relations +- **Property:** Attaches data to a single entity (e.g., `Camera` → `brand` → `Fujifilm`). +- **Relation:** Connects two entities (e.g., `Teresa` → `owns` → `Camera`). Relations are themselves entities and can have their own properties (e.g., `date_acquired`). + +```ts +const OWNS_REL_TYPE_ID = 'OWNS_REL_TYPE_ID'; +const DATE_ACQUIRED_ATTR_ID = 'DATE_ACQUIRED_ATTR_ID'; + +import { getEntityRelations } from '@graphprotocol/grc-20'; + +// 1️⃣ Fetch existing owns relations for Teresa +const existingOwns = getEntityRelations(teresaId, PersonSchema, doc).owns; + +// 2️⃣ Only create if none exists pointing to this camera +if (!existingOwns.find(rel => rel.id === cameraId)) { + const { ops: ownsOps } = Graph.createRelation({ + fromEntity: teresaId, + toEntity: cameraId, + relationType: OWNS_REL_TYPE_ID, + values: [ + { property: DATE_ACQUIRED_ATTR_ID, value: Graph.serializeDate(new Date('2020-03-15')) }, + ], + }); + // add ownsOps to your edit batch… +} +``` + +**Relation JSON example:** +```json +{ + "id": "OwnsRelation_ID", + "type": "OWNS_REL_TYPE_ID", + "from_entity": "Teresa_ID", + "to_entity": "Camera_ID", + "entity": "OwnsRelationEntity_ID", // rich relation entity UUID (optional) + "position": "a", + "verified": false +} +``` + +#### Searching and Idempotency +The SDK generates a new ID for every entity or relation you create—even if an identical relation already exists. To avoid duplicates: + +- **Query existing relations** via your GraphQL endpoint with a filter on `from`, `relationType`, and `to`. +- **Use** `getEntityRelations` (from `@graphprotocol/grc-20`) on a local handle to list current relations for an entity: + +```ts +import { getEntityRelations } from '@graphprotocol/grc-20'; + +// Returns all non-deleted owns relations from Teresa +const relations = getEntityRelations(teresaId, PersonSchema, doc).owns; +``` + +- **Check** if a relation linking the same entities already exists before calling `Graph.createRelation`. + +If you call `createRelation` without checking, you'll end up with multiple relation entities of the same type between the same entities. Deduplication is the responsibility of your application or schema governance. + +#### Minimal Edit Example +Bundle all operations into an edit: +```ts +const ops = [...cameraOps, ...teresaOps, ...ownsOps]; +// Publish ops as an edit (see SDK docs for publishing) +``` + +Let's bring together everything we've learned above—including our example sentence—into a complete GRC-20–compliant TypeScript example that is fully composable with Hypergraph. + +```ts title="example.ts" +// Example: "Teresa, a photographer, owns a Fujifilm camera." +// This script uses the @graphprotocol/grc-20 SDK to: +// 1. Create a Camera entity with a brand property +// 2. Create a Teresa entity with a profession property +// 3. Check for an existing 'owns' relation from Teresa to the Camera +// 4. If none exists, create the 'owns' relation entity +// 5. Bundle all operations into a single edit (ops array) + +import { Graph, getEntityRelations } from '@graphprotocol/grc-20'; + +// Replace these with actual IDs from your schema/space +const PERSON_TYPE_ID = 'PERSON_TYPE_ID'; +const DEVICE_TYPE_ID = 'DEVICE_TYPE_ID'; +const PROFESSION_ATTR_ID = 'PROFESSION_ATTR_ID'; +const BRAND_ATTR_ID = 'BRAND_ATTR_ID'; +const OWNS_REL_TYPE_ID = 'OWNS_REL_TYPE_ID'; +const DATE_ACQUIRED_ATTR_ID = 'DATE_ACQUIRED_ATTR_ID'; + +// 1️⃣ Create the Camera entity with a brand property +const { id: cameraId, ops: cameraOps } = Graph.createEntity({ + name: 'Fujifilm camera', + types: [DEVICE_TYPE_ID], + values: [ + { property: BRAND_ATTR_ID, value: 'Fujifilm' }, + ], +}); + +// 2️⃣ Create the Teresa entity with a profession property +const { id: teresaId, ops: teresaOps } = Graph.createEntity({ + name: 'Teresa', + types: [PERSON_TYPE_ID], + values: [ + { property: PROFESSION_ATTR_ID, value: 'photographer' }, + ], +}); + +// 3️⃣ Fetch existing 'owns' relations for Teresa +const existingOwns = getEntityRelations(teresaId, PersonSchema, doc).owns; + +// 4️⃣ Only create if none exists pointing to this camera +let ownsOps = []; +if (!existingOwns.find(rel => rel.id === cameraId)) { + const { ops } = Graph.createRelation({ + fromEntity: teresaId, + toEntity: cameraId, + relationType: OWNS_REL_TYPE_ID, + values: [ + { property: DATE_ACQUIRED_ATTR_ID, value: Graph.serializeDate(new Date('2020-03-15')) }, + ], + }); + ownsOps = ops; +} + +// 5️⃣ Combine all ops into a single edit +const ops = [...cameraOps, ...teresaOps, ...ownsOps]; +console.log('Ops ready for publishing:', ops); + +// (Optional) Publish the edit +// Graph.publishEdit({ ops }); +``` +--- + +#### Mental Model Recap +- **Entities** are things. +- **Properties** are facts about things, and define the data type. +- **Relations** connect things (and can have their own properties). +- **Values** are atomic facts (entity, property, value). +- **Edits** are batches of changes. + +#### Cheat Sheet Table +| Concept | Example in Sentence | GRC-20 Term | Code Snippet | +|----------|---------------------|-------------|--------------| +| Entity | Teresa, Camera | Entity | `{ id, name }` | +| Type | Person, Device | Type | `types: [PERSON_TYPE_ID]` | +| Property | profession, brand | Property | `{ id: BRAND_ATTR_ID, data_type: 'TEXT' }` | +| Relation | owns | Relation | `{ from_entity, to_entity, type }` | +| Value | `Teresa → profession → photographer` | Value | `{ property: PROFESSION_ATTR_ID, value: 'photographer' }` | +| Edit | batch of all values | Edit | `ops: [...]` | + +--- + +_All of the above is not just theory—Hypergraph puts it to work for you._ **When you call the SDK or its React hooks, Hypergraph turns your mutations into values, bundles them into edits, encrypts them (if the Space is private), and syncs them peer-to-peer or anchors them on-chain if the data is public.** As a developer you think in entities and hooks; behind the scenes Hypergraph speaks pure GRC-20. + +--- + +All of these building blocks are specified by the GRC-20 standard and created in code with the GRC-20 SDK. + +### 3. The GRC-20 SDK +The [`@graphprotocol/grc-20`](https://www.npmjs.com/package/@graphprotocol/grc-20) SDK is a toolkit for building, reading, and writing GRC-20-compliant knowledge graphs. It provides APIs for creating entities, types, properties, and relations, and handles serialization, publishing to IPFS, and onchain anchoring—making it easy to implement the GRC-20 standard in your apps. ## Spaces @@ -63,17 +294,6 @@ Inboxes can be **public** (anyone can read) or **private** (E2EE). Auth policies type InboxSenderAuthPolicy = 'any' | 'members' | 'admins'; ``` -## Knowledge Graph - -Public data isn't shoved into a siloed SQL DB. Instead, Hypergraph publishes JSON-LD to a decentralized Knowledge Graph (IPFS + Polygon Amoy smart contracts). - -Benefits: - -* **Composability** — one app's `City` objects can be queried by another app. -* **Network effects** — each new Space or entity enriches the shared graph. - -A TypeScript codegen tool (see the _TypeSync app_ in `/apps/typesync`) maps your domain models to on-chain schemas so you can query them like regular React hooks. - ## Events & CRDTs 1. A client mutates the Automerge document (`doc.put(…​)`). @@ -97,4 +317,17 @@ When the event log grows large, a peer may emit `sendCompactedUpdate`—a snapsh ### Edit on GitHub -[✏️ Suggest changes](https://github.com/graphprotocol/hypergraph/edit/main/docs/docs/core-concepts.md) \ No newline at end of file +[✏️ Suggest changes](https://github.com/graphprotocol/hypergraph/edit/main/docs/docs/core-concepts.md) + +:::tip Best Practice +**Always check for an existing relation (by `from`, `to`, and `relationType`) before creating a new one.** + +This prevents duplicate relations, keeps your data model clean, and avoids ambiguity in queries and UI. The GRC-20 SDK will create a new relation entity every time unless you check first. +::: + +:::info Terminology Update +In the latest GRC-20 spec, what were previously called "triples" are now called "values." The "value type" is now called "data type," and data types are defined on the property, not the value. This change makes the model simpler and validation more robust. +::: + +**Note:** The data service validates that each value matches the property's data type. + diff --git a/docs/docs/key-features.md b/docs/docs/key-features.md index 62a39a05..e92f1241 100644 --- a/docs/docs/key-features.md +++ b/docs/docs/key-features.md @@ -13,6 +13,7 @@ Hypergraph is **more than a database**—it's a complete data layer for building - [Local-first by design](#local-first-by-design) - [End-to-end encryption](#end-to-end-encryption) +- [Knowledge Graph SDK](#knowledge-graph-sdk) - [Graph-based data model](#graph-based-data-model) - [Conflict-free sync (CRDTs)](#conflict-free-sync-crdts) - [Spaces & fine-grained auth](#spaces--fine-grained-auth) @@ -38,9 +39,13 @@ Every update is encrypted **on the client** using XChaCha20-Poly1305. Only membe * **Automatic key rotation** when members join/leave. * **Multi-device**: each device holds its own key pair. +## Knowledge Graph SDK + +Build, link, and publish knowledge as entities and relations using the [`@graphprotocol/grc-20`](https://www.npmjs.com/package/@graphprotocol/grc-20) Knowledge Graph SDK. It makes it easy to organize data into spaces, anchor edits onchain, and work with The Graph's knowledge graph standard. + ## Graph-based data model -Under the hood, Hypergraph stores JSON-LD triples that map nicely to **knowledge graphs**. This makes it trivial to expose public data on-chain or query it with SPARQL later. +Under the hood, Hypergraph stores JSON-LD values that map nicely to **knowledge graphs**. This makes it trivial to expose public data on-chain or query it with SPARQL later. ## Conflict-free sync (CRDTs) diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 68174b36..467eddd1 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -49,6 +49,7 @@ const config = { }, blog: { showReadingTime: true, + blogSidebarCount: 'ALL', feedOptions: { type: ['rss', 'atom'], xslt: true, @@ -71,6 +72,7 @@ const config = { themeConfig: /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ ({ + colorMode: { defaultMode: 'dark', disableSwitch: true }, // Replace with your project's social card image: 'img/docusaurus-social-card.jpg', navbar: { diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index 38591401..a6d82f9d 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -1,3 +1,6 @@ +/* Import Google font Poppins as fallback (free) – Euclid is paid */ +@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"); + /** * Any CSS included here will be global. The classic template * bundles Infima by default. Infima is a CSS framework designed to @@ -6,25 +9,156 @@ /* You can override the default Infima variables here. */ :root { - --ifm-color-primary: #2e8555; - --ifm-color-primary-dark: #29784c; - --ifm-color-primary-darker: #277148; - --ifm-color-primary-darkest: #205d3b; - --ifm-color-primary-light: #33925d; - --ifm-color-primary-lighter: #359962; - --ifm-color-primary-lightest: #3cad6e; - --ifm-code-font-size: 95%; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); -} - -/* For readability concerns, you should choose a lighter palette in dark mode. */ + /* Brand Colors – "The Graph" palette */ + --graph-purple: #6f4cff; + --astro-blue: #4c66ff; + --galactic-aqua: #66dbff; + --starfield-green: #4bca81; + --nebula-pink: #ff79c6; + --solar-yellow: #ffa801; + + /* Override Infima variables with our palette */ + --ifm-color-primary: var(--graph-purple); + --ifm-color-primary-light: #8069ff; + --ifm-color-primary-lighter: #8f79ff; + --ifm-color-primary-lightest: #a999ff; + --ifm-color-primary-dark: #6544f0; + --ifm-color-primary-darker: #5c3fe4; + --ifm-color-primary-darkest: #4d34c4; + + /* Typography */ + --ifm-font-family-base: "Euclid Circular A", "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, + Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; + --ifm-heading-font-weight: 700; + --ifm-font-weight-bold: 600; + + /* Layout tweaks */ + --ifm-spacing-horizontal: 1.2rem; + --ifm-page-width: 85rem; + + /* Code blocks */ + --docusaurus-highlighted-code-line-bg: rgba(255, 255, 255, 0.05); +} + [data-theme="dark"] { - --ifm-color-primary: #25c2a0; - --ifm-color-primary-dark: #21af90; - --ifm-color-primary-darker: #1fa588; - --ifm-color-primary-darkest: #1a8870; - --ifm-color-primary-light: #29d5b0; - --ifm-color-primary-lighter: #32d8b4; - --ifm-color-primary-lightest: #4fddbf; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); + /* Dark theme overrides keeping brand palette vibrant */ + --ifm-color-primary: var(--graph-purple); + --ifm-background-color: #0b0b13; + --ifm-background-surface-color: #0b0b13; + --ifm-navbar-background-color: rgba(11, 11, 19, 0.9); + --ifm-footer-background-color: #0b0b13; + --ifm-toc-border-color: rgba(255, 255, 255, 0.08); + --docusaurus-highlighted-code-line-bg: rgba(255, 255, 255, 0.05); +} + +/* ---------- Global enhancements inspired by design ---------- */ + +html { + scroll-behavior: smooth; +} + +body { + background: #0b0b13; + color: var(--ifm-font-color-base); +} + +/* Smooth transition for theme switch & interactive elements */ +* { + transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease; +} + +/* Custom scrollbar – slim & subtle */ +::-webkit-scrollbar { + width: 6px; + height: 6px; +} +::-webkit-scrollbar-track { + background: transparent; +} +::-webkit-scrollbar-thumb { + background: hsla(0, 0%, 100%, 0.12); + border-radius: 3px; +} +::-webkit-scrollbar-thumb:hover { + background: hsla(0, 0%, 100%, 0.25); +} + +/* Links */ +:root a { + text-decoration-color: rgba(111, 76, 255, 0.4); + text-underline-offset: 2px; +} +:root a:hover { + text-decoration-color: currentColor; +} + +/* Buttons (using Infima classes) */ +.button--primary { + background: linear-gradient(135deg, var(--astro-blue) 0%, var(--graph-purple) 100%); + color: #fff; + border: none; +} +.button--primary:hover { + background: linear-gradient(135deg, var(--astro-blue) -20%, var(--graph-purple) 120%); +} + +/* Navbar translucency & blur */ +.navbar { + backdrop-filter: blur(12px); + background-color: var(--ifm-navbar-background-color); + border-bottom: 1px solid rgba(255, 255, 255, 0.05); +} + +/* Shadow & border for code blocks */ +.theme-code-block { + border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 0.75rem; + overflow: hidden; +} + +/* Card-like appearance for admonitions */ +.alert { + border-radius: 0.75rem; + box-shadow: 0 3px 10px rgba(0, 0, 0, 0.25); +} + +/* Table styling tweaks */ +.table { + border-collapse: collapse; +} +.table thead th { + font-weight: 600; +} +.table th, +.table td { + border-bottom: 1px solid rgba(255, 255, 255, 0.08); + padding: 0.75rem 1rem; +} + +/* Adjust sidebar width and typography */ +@media (min-width: 997px) { + .theme-doc-sidebar-container { + width: 16rem; + } + .theme-doc-sidebar-container .menu__link { + font-size: 0.95rem; + } +} + +/* Breadcrumb subtlety */ +.breadcrumbs__item:not(.breadcrumbs__item--active) a { + color: rgba(255, 255, 255, 0.7); +} + +/* End of custom aesthetic overrides */ + +/* Make docs wrapper background match inspected color */ +.docs-wrapper, +.plugin-docs.plugin-id-default.docs-version-current.docs-doc-page { + background: #0b0b13 !important; +} + +.blog-wrapper, +.plugin-blog.plugin-id-default.docs-version-current.docs-blog-page { + background: #0b0b13 !important; }