Skip to main content

@lexical/y/headless

Classes​

YHeadlessError​

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:131

Experimental

The error the headless helpers throw when they refuse.

Extends​

Constructors​

Constructor​

new YHeadlessError(code, message, warnings?): YHeadlessError

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:139

Experimental

Parameters​
code​

YHeadlessErrorCode

message​

string

warnings?​

readonly YWarning[] = []

Returns​

YHeadlessError

Overrides​

Error.constructor

Properties​

cause?​

optional cause?: unknown

Defined in: typescript/lib/lib.es2022.error.d.ts:24

Experimental

Inherited from​

Error.cause

code​

readonly code: YHeadlessErrorCode

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:132

Experimental

message​

message: string

Defined in: typescript/lib/lib.es5.d.ts:1075

Experimental

Inherited from​

Error.message

name​

name: string

Defined in: typescript/lib/lib.es5.d.ts:1074

Experimental

Inherited from​

Error.name

stack?​

optional stack?: string

Defined in: typescript/lib/lib.es5.d.ts:1076

Experimental

Inherited from​

Error.stack

warnings​

readonly warnings: readonly YWarning[]

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:138

Experimental

For 'read-only': the binding's warnings that say why, typed (narrow on code, then on data.reason), so an app can say why without parsing the message. Empty for the other codes.

stackTraceLimit​

static stackTraceLimit: number

Defined in: @types/node/globals.d.ts:67

Experimental

The Error.stackTraceLimit property specifies the number of stack frames collected by a stack trace (whether generated by new Error().stack or Error.captureStackTrace(obj)).

The default value is 10 but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed.

If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

Inherited from​

Error.stackTraceLimit

Methods​

captureStackTrace()​

static captureStackTrace(targetObject, constructorOpt?): void

Defined in: @types/node/globals.d.ts:51

Experimental

Creates a .stack property on targetObject, which when accessed returns a string representing the location in the code at which Error.captureStackTrace() was called.

const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack; // Similar to `new Error().stack`

The first line of the trace will be prefixed with ${myObject.name}: ${myObject.message}.

The optional constructorOpt argument accepts a function. If given, all frames above constructorOpt, including constructorOpt, will be omitted from the generated stack trace.

The constructorOpt argument is useful for hiding implementation details of error generation from the user. For instance:

function a() {
b();
}

function b() {
c();
}

function c() {
// Create an error without stack trace to avoid calculating the stack trace twice.
const { stackTraceLimit } = Error;
Error.stackTraceLimit = 0;
const error = new Error();
Error.stackTraceLimit = stackTraceLimit;

// Capture the stack trace above function b
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
throw error;
}

a();
Parameters​
targetObject​

object

constructorOpt?​

Function

Returns​

void

Inherited from​

Error.captureStackTrace

isError()​

static isError(error): error is Error

Defined in: typescript/lib/lib.esnext.error.d.ts:21

Experimental

Indicates whether the argument provided is a built-in Error instance or not.

Parameters​
error​

unknown

Returns​

error is Error

Inherited from​

Error.isError

prepareStackTrace()​

static prepareStackTrace(err, stackTraces): any

Defined in: @types/node/globals.d.ts:55

Experimental

Parameters​
err​

Error

stackTraces​

CallSite[]

Returns​

any

See​

https://v8.dev/docs/stack-trace-api#customizing-stack-traces

Inherited from​

Error.prepareStackTrace

Interfaces​

EditYStateOptions​

Defined in: packages/lexical-y/src/headless.ts:87

Experimental

Properties​

allowedRoots?​

optional allowedRoots?: Iterable<string, any, any>

Defined in: packages/lexical-y/src/headless.ts:113

Experimental

The shared roots the update may write to; anything else refuses the edit ('foreign-roots'). Default: the layout root only. The list replaces the default, so name the layout root in it too.

tag?​

optional tag?: string | string[]

Defined in: packages/lexical-y/src/headless.ts:129

Experimental

Update tag(s) of the edit's editor update. COLLABORATION_TAG and SKIP_COLLAB_TAG are refused ('ignored-tag'): the binding does not write an update that carries them, so the edit would be lost.

transact?​

optional transact?: (doc) => void

Defined in: packages/lexical-y/src/headless.ts:123

Experimental

Writes to other shared types of the document (for example an activity log), run in one Yjs transaction after the edit, under the edit's client id (doc.clientID). Their roots must be in allowedRoots. It only writes: an update applied to doc here refuses the edit ('imported-items'), as its items would be credited to the writer. doc is released when the call returns: publish the returned update, never this document's own events.

Parameters​
doc​

Doc

Returns​

void

writer​

writer: YWriter | null

Defined in: packages/lexical-y/src/headless.ts:107

Experimental

Who the edit is written as. Required, so that every call decides:

  • a writer from createYWriter (one per agent or integration, created once per process): the edit continues the writer's client id for this document, so the server's edits of a document add one client id to it, not one per edit. It continues only on a state whose clock for that id is where the writer's last update there ended (a state that holds that update); otherwise the edit is written under a new client id. When the state holds the id but not at its tip (a state read before that update), or another call with the writer is writing under it, a WRITER_NEW_CLIENT_ID_WARNING warning says why; a state that holds none of the writer's ids (another document, or one read before the writer's first edit there) gets a new id silently;
  • null: a new anonymous client id for this edit alone. Every edit that writes adds a client id to the document for good: its state vector, which every sync sends, and every call's cost grow with them.

The result's clientID is the client id the edit wrote under.


EditYStateResult​

Defined in: packages/lexical-y/src/headless.ts:55

Experimental

The result of editYState.

Properties​

clientID​

clientID: number

Defined in: packages/lexical-y/src/headless.ts:83

Experimental

The client id the edit wrote under (also when it wrote nothing): the writer's for this document, or a new anonymous one with writer: null. Credit it to the writer's author in your attribution, such as a registry of client ids, or attribute the update's ids directly (createContentIdsFromUpdate(update) from @y/y, when update is not null). Never assign it to a Y.Doc: two writers under one client id corrupt the document.

state​

state: Uint8Array

Defined in: packages/lexical-y/src/headless.ts:68

Experimental

state with update applied, garbage collected as clients and Yjs servers store a document (deleted content keeps only its tombstones). When update is null, state garbage collected the same way.

update​

update: Uint8Array<ArrayBufferLike> | null

Defined in: packages/lexical-y/src/headless.ts:62

Experimental

Everything the edit wrote, as one merged update, or null when it changed nothing. Includes what opening the document wrote (a value an extension assigns on open, which a client would also write), which the edit may depend on.

warnings​

warnings: LexicalWarning[]

Defined in: packages/lexical-y/src/headless.ts:73

Experimental

Warnings reported while opening and editing, oldest first (also passed to config.onWarn).


HeadlessYConfig​

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:76

Experimental

The editor a headless helper binds: the same extensions (or nodes) as the clients' editors, so that the server reads and writes the document the way a client would.

Properties​

clientIDRange?​

optional clientIDRange?: ClientIDRange

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:87

Experimental

The range of the client ids the server writes with (default 'uint53'). Use 'uint32' when updates pass through yrs before 0.28.

extensions?​

optional extensions?: readonly AnyLexicalExtensionArgument[]

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:78

Experimental

Extensions that define the editor: nodes, transforms, NodeState.

nodes?​

optional nodes?: readonly LexicalNodeConfig[]

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:80

Experimental

Node classes, for an editor that is not defined by extensions.

onWarn?​

optional onWarn?: (warning) => void

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:97

Experimental

Called with every warning, as a LexicalWarning (the same ones the result's warnings lists): the binding's (@lexical/y/... codes), the editor's (it replaces an onWarn of the extensions; other errors come as EDITOR_WARNING), and FOLLOW_UPS_EXHAUSTED_WARNING. Warnings never refuse an edit, in any environment, and a throwing handler does not either. Default: console.warn outside production, nothing in production.

Parameters​
warning​

LexicalWarning

Returns​

void

root?​

optional root?: string

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:82

Experimental

The name of the shared root (default 'lexical-y').

selfCheck?​

optional selfCheck?: boolean

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:102

Experimental

The binding's self-check of its own writes (see YBindingOptions). Default: off.


YWriter​

Defined in: packages/lexical-y/src/internal/Writer.ts:43

Experimental

Who editYState writes an edit as (see createYWriter): an author, and the client ids the writer writes under, one per document it edits.

Properties​

[createdByCreateYWriter]​

readonly [createdByCreateYWriter]: true

Defined in: packages/lexical-y/src/internal/Writer.ts:47

Experimental

Phantom brand: only createYWriter makes a writer.

author​

readonly author: string

Defined in: packages/lexical-y/src/internal/Writer.ts:45

Experimental

Who the writer's edits are by, as given to createYWriter.

Type Aliases​

YHeadlessErrorCode​

YHeadlessErrorCode = "not-initialized" | "read-only" | "foreign-roots" | "imported-items" | "ignored-tag"

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:106

Experimental

Error codes of YHeadlessError.


YHeadlessWarningCode​

YHeadlessWarningCode = YWarningCode | typeof EDITOR_WARNING | typeof FOLLOW_UPS_EXHAUSTED_WARNING | typeof WRITER_NEW_CLIENT_ID_WARNING

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:65

Experimental

The codes of the warnings the headless helpers report (the code of each LexicalWarning they return or pass to onWarn): the binding's, EDITOR_WARNING, FOLLOW_UPS_EXHAUSTED_WARNING and WRITER_NEW_CLIENT_ID_WARNING. Codes are never renamed or reused; new ones may be added, so a switch over them needs a default.

Variables​

EDITOR_WARNING​

const EDITOR_WARNING: "@lexical/y/editor-warning" = '@lexical/y/editor-warning'

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:47

Experimental

A warning the editor reported through its onWarn that is not a LexicalWarning (Lexical's own, or an extension's), passed on as one with its message. data: {error: Error} (the warning as reported).


FOLLOW_UPS_EXHAUSTED_WARNING​

const FOLLOW_UPS_EXHAUSTED_WARNING: "@lexical/y/follow-ups-exhausted" = '@lexical/y/follow-ups-exhausted'

Defined in: packages/lexical-y/src/internal/HeadlessEditor.ts:56

Experimental

The edit's listeners kept scheduling updates: after the last follow-up update the helpers commit, the rest were not committed and are not part of the result. data: {limit: number} (the follow-up updates committed). Once the binding writes, an update that changes content and is made after a commit in the same task (as a listener's is) commits at once, so Lexical's own guard stops such listeners instead (EDITOR_WARNING).


WRITER_NEW_CLIENT_ID_WARNING​

const WRITER_NEW_CLIENT_ID_WARNING: "@lexical/y/writer-new-client-id" = '@lexical/y/writer-new-client-id'

Defined in: packages/lexical-y/src/internal/Writer.ts:61

Experimental

A writer could not continue its client id on the state an edit was given, so the edit was written under a new one, and the document now carries one more client id. data: {author: string, clientID: number, previousClientID: number, reason: 'stale-state' | 'busy' | 'range' | 'foreign-writes'}: the state was read before the writer's last update under that id (or the update was never stored); another call with the writer was writing under it (a call made from inside another call); the id does not fit clientIDRange: 'uint32'; or something else wrote under it, and the writer stops using it.

Functions​

createYDoc()​

createYDoc(state?): Doc

Defined in: packages/lexical-y/src/headless.ts:142

Experimental

A Y.Doc for a relay or a server that loads a document's state (to store, compact or merge it), with state applied when given. It has Yjs's format cleanup turned off (cleanupFormatting = false), as the binding has on the clients: applying an update there would otherwise delete format items the clients keep, and the state it stores would read differently from what the clients show once someone types there. Garbage collected, as clients store a document. Merging updates with mergeUpdates needs no document.

Parameters​

state?​

Uint8Array<ArrayBufferLike> | null

Returns​

Doc


createYWriter()​

createYWriter(author): YWriter

Defined in: packages/lexical-y/src/internal/Writer.ts:108

Experimental

A writer for editYState. author names who its edits are by (an agent, an integration): for your attribution, and in the warnings about the writer. It is not written into documents.

Create one per agent or integration, once per process, and pass it to every edit it makes. It keeps one client id per document it edits, continued from edit to edit, so a document the server edits thousands of times carries one client id for it instead of thousands. It remembers up to 10,000 client ids, the least recently used forgotten first; a document whose id it forgot gets a new one on its next edit. A writer created for each edit gives each edit a new client id, as writer: null does.

Parameters​

author​

string

Returns​

YWriter


editYState()​

editYState(state, config, $edit, options): EditYStateResult

Defined in: packages/lexical-y/src/headless.ts:290

Experimental

Run $edit (one discrete editor update, plus the updates it makes listeners schedule) on the document at state and return the update it makes, written as options.writer (required: a writer from createYWriter, or null for a new anonymous client id). The update is checked to write only to allowedRoots. Throws a YHeadlessError when the document is not initialized or is read only, when the update writes elsewhere, or when options.tag names a tag with which the binding writes nothing (COLLABORATION_TAG, SKIP_COLLAB_TAG). Whatever $edit throws (any value, an Error or not) is rethrown as it is, and nothing is written: transact does not run. Warnings (LexicalWarnings) are returned in warnings and passed to config.onWarn; they never refuse the edit.

With $edit a no-op, the update is what opening the document writes (values an extension assigns on open): store it once before relying on readYState for such values.

Parameters​

state​

Uint8Array

config​

HeadlessYConfig

$edit​

() => void

options​

EditYStateOptions

Returns​

EditYStateResult


readYState()​

readYState<T>(state, config, $read): T

Defined in: packages/lexical-y/src/headless.ts:385

Experimental

The value $read returns from the document at state (for example its Markdown or $getEditor().getEditorState().toJSON()). Nothing is written. Throws a YHeadlessError when the document is not initialized or is read only.

What opening the document writes is discarded: a value an extension assigns on open is read here but never stored, so two reads can disagree. Store the update of a no-op editYState first. BlockIdExtension assigns nothing on open: a block stored without an id, or with an id an earlier block stores or derives, reads the id derived from its Yjs identity, the same in every read.

Type Parameters​

T​

T

Parameters​

state​

Uint8Array

config​

HeadlessYConfig

$read​

() => T

Returns​

T


seedYState()​

seedYState(config, $build): Uint8Array

Defined in: packages/lexical-y/src/headless.ts:252

Experimental

The state of a new document whose content $build writes into an empty root: the documented way to seed a document (from a template, an import, or a converter's editor). The content is written as a client's initialize() writes its initial content: with a client id derived from the content (53 bits under 'uint53', 32 under 'uint32') and outside any undo history. Seeding identical content twice gives the same bytes, and the two seeds merge into one copy; content with random parts (such as ids an extension draws for new blocks) is not identical. With BlockIdExtension, a seed and a client's initialization of the same content name its blocks differently (a client's initial content is a load, named by position; a seed's blocks are named by generateId), so they do not merge unless the content gives its blocks fixed ids. The state only holds the layout root, so a converter merges it into the stored document next to an older layout's root. The state is garbage collected, as clients store a document.

It takes no writer: the client id is derived from the content, which is what makes identical seeds merge. To credit a seed in your attribution, use the client ids in its state vector (decodeStateVector(encodeStateVectorFromUpdate(seed)) from @y/y): that one id, unless a listener of the config's extensions writes once the content is read (a value it sets on open), which adds the temporary document's own id.

Parameters​

config​

HeadlessYConfig

$build​

() => void

Returns​

Uint8Array