Aller au contenu

@platform/doc

Location: modules/platform/doc/
Dependencies: @platform/core, @platform/socket, @platform/schema

Overview

@platform/doc is the reactive document store of the platform. It abstracts MongoDB operations behind a clean, schema-driven API and propagates changes to all connected clients in real time through the socket layer.

Key responsibilities: - CRUD operations — create, read, update, and delete documents in MongoDB. - Reactive subscriptions — clients subscribe to queries; the server pushes live updates via @platform/schema's pub/sub layer. - Schema integration — every collection is defined with a DSchema (Zod-based schema with doc metadata) from @platform/schema. - React hooksuseDoc and useDocs provide ergonomic reactive data access in components. - Crud routesdocCrudRoute generates a full React Router route tree (browser + form + editor) for a collection.

Contexts

Context Entry point Contents
client src/client/index.ts React hooks, context providers, display components, layout, crud route
server src/server/index.ts ServerDocService, ServerCrudService, ServerMongoService, Cursor
common src/common/index.ts Doc, DSchema, PRef, interfaces, publications, CommonDocService

Common API

import { Doc, DocSchema, DSchema, PRef, CommonDocService } from '@platform/doc/common'
Export Description
Doc Base document type — { _id: string }
DocSchema Zod schema for the base Doc{ _id: PString() } with namespace 'doc'
TDoc TypeScript type alias for typeof DocSchema
DSchema(shape, meta) Creates a Zod schema extending DocSchema and registers it with CommonDocService. Use for all document schemas.
PRef(schema, options?) Creates a property whose value is a reference (string _id) to another document schema
CommonDocService Shared utilities for document manipulation, schema registry
interfaces TypeScript interfaces for CRUD and subscription contracts
publications Named publication definitions

Defining a Document Schema

import { DSchema } from '@platform/doc/common'
import { PString, PNumber } from '@platform/schema/common'

export const NoteSchema = DSchema(
  {
    title: PString(),
    content: PString({ optional: true }),
    order: PNumber({ optional: true })
  },
  {
    namespace: 'notes',
    name: 'Note',
    render: (note) => note.title
  }
)

export type Note = z.infer<typeof NoteSchema>

Document References

import { PRef } from '@platform/doc/common'
import { UserSchema } from '@platform/security/common'

const CommentSchema = DSchema(
  {
    text: PString(),
    author: PRef(UserSchema)  // stores the user's _id
  },
  { namespace: 'comments', name: 'Comment', render: (c) => c.text }
)

Server API

import {
  ServerDocService,
  ServerCrudService,
  ServerMongoService,
  Cursor
} from '@platform/doc/server'
Export Description
ServerMongoService Manages the MongoDB connection and exposes the native Db object
ServerDocService High-level document service — wraps ServerMongoService with schema-aware helpers
ServerCrudService Generic CRUD service base class — extend it to expose create/read/update/delete operations for a collection
Cursor MongoDB cursor wrapper with pagination and filtering utilities

Defining a Collection Service

import { ServerCrudService } from '@platform/doc/server'
import { NoteSchema } from './NoteSchema'

export class NoteService extends ServerCrudService<typeof NoteSchema> {
  collectionName = 'notes'
  schema = NoteSchema
}

Client API

Hooks

import { useDoc, useDocs, useDocSubscription, useDocAutocomplete, useSubscriptionDocs } from '@platform/doc/client'
Export Description
useDoc(type, id) Subscribes to a single document by type and _id; returns the live document or undefined
useDocs(type, query?) Subscribes to a collection query; returns a live array of matching documents
useDocSubscription(publication, params) Low-level hook for custom publication subscriptions
useDocAutocomplete(schema, query) Returns a filtered list of documents for use in autocomplete controls
useSubscriptionDocs(publication, params) Subscribes to a publication that returns a list of documents

Context Providers

Export Description
DocContext React context that must wrap the component tree; connects to the server doc subscription
useDocContext Hook to access the DocContext state and actions
useDocDataState Internal hook for raw document data state
useDocSubscriptionState Internal hook for subscription lifecycle state

Display Components

import { DocDisplayValue, DocSchemaTable } from '@platform/doc/client'
Export Description
DocDisplayValue Renders a document field value using schema-derived formatting
DocSchemaTable Renders a property table for a document based on its schema

Form Components

Export Description
DocRefStringControl Form control for selecting a referenced document by _id
DocSchemaControl Schema-aware form control bound to a document field
DocControl General-purpose document form control

Layouts

Export Description
DocForm Full form layout for a document, combining EntityEditor + SchemaForm

Crud Route Factory

import { docCrudRoute } from '@platform/doc/client'

docCrudRoute(path, schema, publication) generates a complete React Router RouteObject tree for a collection:

/<path>              → DocBrowserRoute  (list + search)
/<path>/:id          → DocFormRoute     (load doc into form context)
/<path>/:id/         → DocEditorRoute   (entity editor with tabs)
/<path>/:id/         → EntityForm       (index: main fields)
/<path>/:id/<child>  → child routes     (one route per nested object field)
import { docCrudRoute } from '@platform/doc/client'
import { NoteSchema } from '@platform/notes/common'
import { NotesPublication } from '@platform/notes/common'

const notesRoute = docCrudRoute('/notes', NoteSchema, NotesPublication)

Route Utilities

Export Description
AppRoute Route wrapper type helpers (AppRouteParams, ModelComponentProps, RouteToModel, ModelToView)

Usage Example

// Common — define a document schema
import { DSchema } from '@platform/doc/common'
import { PString } from '@platform/schema/common'

export const NoteSchema = DSchema(
  { title: PString() },
  { namespace: 'notes', name: 'Note', render: (n) => n.title }
)

// Server — expose a CRUD service
import { ServerCrudService } from '@platform/doc/server'

export class NoteService extends ServerCrudService<typeof NoteSchema> {
  collectionName = 'notes'
  schema = NoteSchema
}

// Client — consume live data
import { useDocs } from '@platform/doc/client'

function NoteList() {
  const notes = useDocs('Note')
  return <ul>{notes.map(n => <li key={n._id}>{n.title}</li>)}</ul>
}