@shadow-garden/bapbong-contracts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Le Phuoc Minh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # @shadow-garden/bapbong-contracts
2
+
3
+ The shared **vocabulary** every other bapbong package speaks: paint-ready types,
4
+ the plugin contract, and one small isomorphic utility (`Collection`). Almost all
5
+ types; the only runtime code is `Collection`.
6
+
7
+ - **Scope:** `scope:pure` (leaf — imports no other workspace package)
8
+ - **Depends on:** `prosemirror-state`, `prosemirror-model` — **type-only**, for the
9
+ plugin/editor-change contracts. No DOM: the package is **isomorphic** (runs on
10
+ Node/server; enforced by a `no-restricted-globals` lint guard).
11
+
12
+ ## What it defines
13
+
14
+ - **Flow model** (layout input): `FlowParagraph`, `FlowTable` /
15
+ `FlowTableRow` / `FlowTableCell`, `FlowFloat`, and inlines
16
+ `InlineRun` / `InlineImage` / `InlineBreak` / `InlineField`.
17
+ - **Resolved layout** (paint-ready engine output): `ResolvedLayout`,
18
+ `ResolvedPage`, `LayoutLine`, `LayoutSegment`, `LayoutImageSegment`,
19
+ `ResolvedCell`, `ResolvedFloat`, `ResolvedFootnotes`, `ResolvedChrome`.
20
+ - **Geometry & config:** `PageConfig`, `LayoutConfig`, `ColumnConfig`,
21
+ `ParagraphSpacing`, `ParagraphIndent`, `CellPadding`, `CaretRect`,
22
+ `PagePoint`, `SelectionRect`.
23
+ - **Fonts / measurement:** `FontSpec`, `FontMetrics`, `MeasureText`, `MeasureMetrics`.
24
+ - **Comments:** `IUser`, `CommentNode`, `CommentData`.
25
+ - **Plugin contract** (the stable surface the editor + plugins share, so neither
26
+ imports the other): `EditorPlugin`, `PluginContext`, `EditorChange`,
27
+ `RangeDecoration`, `PaintDecoration`, `EditorPointerEvent` (the pointer hook +
28
+ `ctx.layout`/`ctx.setCursor` let plugins hit-test tables, e.g. column resize).
29
+ - **Command contract**: `Command` (`{ name, run, isActive?, isEnabled? }`) +
30
+ `Dispatch` — the headless editor-operation surface the toolbar/menubar,
31
+ plugins and a backend share. Implementations live in
32
+ `@shadow-garden/bapbong-commands`.
33
+ - **`Collection<T>`** — a name/id-keyed, insertion-ordered collection
34
+ (`get`/`add`/`remove`/`has`/`entries` + iterable). Keys by `id` by default, or
35
+ `new Collection(items, { idProperty })`; throws if an item lacks its key.
36
+ The editor uses it as its plugin registry.
37
+
38
+ ## Build / test
39
+
40
+ ```sh
41
+ pnpm nx build @shadow-garden/bapbong-contracts
42
+ pnpm nx test @shadow-garden/bapbong-contracts
43
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // packages/contracts/src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Collection: () => Collection
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+
27
+ // packages/contracts/src/lib/collection.ts
28
+ var Collection = class {
29
+ items = /* @__PURE__ */ new Map();
30
+ idProperty;
31
+ defaulted;
32
+ constructor(initial = [], options) {
33
+ this.defaulted = options?.idProperty === void 0;
34
+ this.idProperty = options?.idProperty ?? "id";
35
+ for (const it of initial) this.add(it);
36
+ }
37
+ keyOf(keyOrValue) {
38
+ return typeof keyOrValue === "object" && keyOrValue !== null ? keyOrValue[this.idProperty] : keyOrValue;
39
+ }
40
+ /** The item with `key` (or matching the given item), or undefined. */
41
+ get(keyOrValue) {
42
+ return this.items.get(this.keyOf(keyOrValue));
43
+ }
44
+ /** Add (or replace, by key) an item. Throws if the item lacks its key
45
+ * property (e.g. defaulting to `id` on items that have none). */
46
+ add(value) {
47
+ const key = value[this.idProperty];
48
+ if (key === void 0 || key === null) {
49
+ throw new Error(
50
+ `Collection: item has no "${String(this.idProperty)}" key` + (this.defaulted ? " \u2014 pass { idProperty } to key by another property." : ".")
51
+ );
52
+ }
53
+ this.items.set(key, value);
54
+ return this;
55
+ }
56
+ /** Remove by key (or by item). Returns whether something was removed. */
57
+ remove(keyOrValue) {
58
+ return this.items.delete(this.keyOf(keyOrValue));
59
+ }
60
+ has(keyOrValue) {
61
+ return this.items.has(this.keyOf(keyOrValue));
62
+ }
63
+ get size() {
64
+ return this.items.size;
65
+ }
66
+ /** [key, item] pairs, in insertion order. */
67
+ entries() {
68
+ return [...this.items.entries()];
69
+ }
70
+ [Symbol.iterator]() {
71
+ return this.items.values();
72
+ }
73
+ };
74
+ // Annotate the CommonJS export names for ESM import in node:
75
+ 0 && (module.exports = {
76
+ Collection
77
+ });
@@ -0,0 +1,5 @@
1
+ export * from './lib/contracts.js';
2
+ export * from './lib/collection.js';
3
+ export * from './lib/plugin.js';
4
+ export * from './lib/command.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,50 @@
1
+ // packages/contracts/src/lib/collection.ts
2
+ var Collection = class {
3
+ items = /* @__PURE__ */ new Map();
4
+ idProperty;
5
+ defaulted;
6
+ constructor(initial = [], options) {
7
+ this.defaulted = options?.idProperty === void 0;
8
+ this.idProperty = options?.idProperty ?? "id";
9
+ for (const it of initial) this.add(it);
10
+ }
11
+ keyOf(keyOrValue) {
12
+ return typeof keyOrValue === "object" && keyOrValue !== null ? keyOrValue[this.idProperty] : keyOrValue;
13
+ }
14
+ /** The item with `key` (or matching the given item), or undefined. */
15
+ get(keyOrValue) {
16
+ return this.items.get(this.keyOf(keyOrValue));
17
+ }
18
+ /** Add (or replace, by key) an item. Throws if the item lacks its key
19
+ * property (e.g. defaulting to `id` on items that have none). */
20
+ add(value) {
21
+ const key = value[this.idProperty];
22
+ if (key === void 0 || key === null) {
23
+ throw new Error(
24
+ `Collection: item has no "${String(this.idProperty)}" key` + (this.defaulted ? " \u2014 pass { idProperty } to key by another property." : ".")
25
+ );
26
+ }
27
+ this.items.set(key, value);
28
+ return this;
29
+ }
30
+ /** Remove by key (or by item). Returns whether something was removed. */
31
+ remove(keyOrValue) {
32
+ return this.items.delete(this.keyOf(keyOrValue));
33
+ }
34
+ has(keyOrValue) {
35
+ return this.items.has(this.keyOf(keyOrValue));
36
+ }
37
+ get size() {
38
+ return this.items.size;
39
+ }
40
+ /** [key, item] pairs, in insertion order. */
41
+ entries() {
42
+ return [...this.items.entries()];
43
+ }
44
+ [Symbol.iterator]() {
45
+ return this.items.values();
46
+ }
47
+ };
48
+ export {
49
+ Collection
50
+ };
@@ -0,0 +1,42 @@
1
+ /** Property names of T whose value can serve as a key (string | number | symbol). */
2
+ type IdKeysOf<T> = {
3
+ [K in keyof T]: T[K] extends PropertyKey ? K : never;
4
+ }[keyof T];
5
+ /** Default key property: `id` when T has one, otherwise any valid id property. */
6
+ type DefaultIdKey<T> = 'id' extends IdKeysOf<T> ? 'id' : IdKeysOf<T>;
7
+ /**
8
+ * A key-property-keyed, insertion-ordered collection. Items are keyed by a
9
+ * property whose value is a primitive (`string | number | symbol`); it defaults
10
+ * to `id`, or pass `{ idProperty }` to key by another (e.g. plugins by `name`).
11
+ * Lookups/removals accept either the key or the item; iterating yields the
12
+ * items in insertion order.
13
+ *
14
+ * Dependency-free + isomorphic. Used by the editor as its plugin registry
15
+ * (`new Collection<EditorPlugin>([], { idProperty: 'name' })`), but generic.
16
+ *
17
+ * Note: if T has no `id` property you must pass `{ idProperty }` — otherwise
18
+ * items would key by an absent property at runtime.
19
+ */
20
+ export declare class Collection<T extends object, IdKey extends IdKeysOf<T> = DefaultIdKey<T>> implements Iterable<T> {
21
+ private readonly items;
22
+ private readonly idProperty;
23
+ private readonly defaulted;
24
+ constructor(initial?: T[], options?: {
25
+ idProperty?: IdKey;
26
+ });
27
+ private keyOf;
28
+ /** The item with `key` (or matching the given item), or undefined. */
29
+ get(keyOrValue: T[IdKey] | T): T | undefined;
30
+ /** Add (or replace, by key) an item. Throws if the item lacks its key
31
+ * property (e.g. defaulting to `id` on items that have none). */
32
+ add(value: T): this;
33
+ /** Remove by key (or by item). Returns whether something was removed. */
34
+ remove(keyOrValue: T[IdKey] | T): boolean;
35
+ has(keyOrValue: T[IdKey] | T): boolean;
36
+ get size(): number;
37
+ /** [key, item] pairs, in insertion order. */
38
+ entries(): [T[IdKey], T][];
39
+ [Symbol.iterator](): Iterator<T>;
40
+ }
41
+ export {};
42
+ //# sourceMappingURL=collection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../src/lib/collection.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,KAAK,QAAQ,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,WAAW,GAAG,CAAC,GAAG,KAAK;CAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAErF,kFAAkF;AAClF,KAAK,YAAY,CAAC,CAAC,IAAI,IAAI,SAAS,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;AAErE;;;;;;;;;;;;GAYG;AACH,qBAAa,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,SAAS,QAAQ,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CACnF,YAAW,QAAQ,CAAC,CAAC,CAAC;IAEtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;gBAExB,OAAO,GAAE,CAAC,EAAO,EAAE,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,KAAK,CAAA;KAAE;IAM/D,OAAO,CAAC,KAAK;IAMb,sEAAsE;IACtE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS;IAI5C;sEACkE;IAClE,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAYnB,yEAAyE;IACzE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO;IAIzC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO;IAItC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,6CAA6C;IAC7C,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE;IAI1B,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC;CAGjC"}
@@ -0,0 +1,30 @@
1
+ import type { EditorState, Transaction } from 'prosemirror-state';
2
+ /** Apply a transaction to the editor — ProseMirror's dispatch convention. */
3
+ export type Dispatch = (tr: Transaction) => void;
4
+ /**
5
+ * A named editor operation: the shared vocabulary the toolbar/menubar, plugins,
6
+ * and a headless (server-side) caller all speak. It operates purely on
7
+ * {@link EditorState} with no DOM, so the *same* command runs in the browser
8
+ * and on the backend.
9
+ *
10
+ * This is just the contract — implementations live in
11
+ * `@shadow-garden/bapbong-commands`. Keeping the type here lets the editor
12
+ * expose a `Collection<Command>` registry, and the menubar read it, without
13
+ * either importing the implementations (same rationale as {@link EditorPlugin}).
14
+ */
15
+ export interface Command {
16
+ /** Stable identifier — the registry key and the name a menu/toolbar references. */
17
+ readonly name: string;
18
+ /**
19
+ * Apply the operation. Following ProseMirror's convention, omit `dispatch` to
20
+ * probe whether it *would* apply (returns true/false without mutating).
21
+ */
22
+ run(state: EditorState, dispatch?: Dispatch): boolean;
23
+ /** Whether the operation is currently "on" (e.g. bold over the selection) —
24
+ * drives toggle/active UI. */
25
+ isActive?(state: EditorState): boolean;
26
+ /** Whether the operation can apply at all (else a button renders disabled).
27
+ * When omitted, callers fall back to a no-dispatch `run` probe. */
28
+ isEnabled?(state: EditorState): boolean;
29
+ }
30
+ //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/lib/command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElE,6EAA6E;AAC7E,MAAM,MAAM,QAAQ,GAAG,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,OAAO;IACtB,mFAAmF;IACnF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACtD;mCAC+B;IAC/B,QAAQ,CAAC,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC;IACvC;wEACoE;IACpE,SAAS,CAAC,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC;CACzC"}
@@ -0,0 +1,510 @@
1
+ /** Page geometry, in CSS pixels. */
2
+ export interface PageConfig {
3
+ width: number;
4
+ height: number;
5
+ margin: {
6
+ top: number;
7
+ right: number;
8
+ bottom: number;
9
+ left: number;
10
+ };
11
+ }
12
+ /** Multi-column layout (w:cols): `count` equal-width columns separated by
13
+ * `gap` px. count 1 is the ordinary single-column flow. */
14
+ export interface ColumnConfig {
15
+ count: number;
16
+ gap: number;
17
+ }
18
+ /** One document section's flow properties. Sections are delimited by section
19
+ * breaks (w:sectPr); each spans `blockCount` top-level blocks. `newPage` is
20
+ * true for a next-page break (the section starts a fresh page), false for a
21
+ * continuous break (columns switch mid-page). */
22
+ export interface SectionConfig {
23
+ blockCount: number;
24
+ columns: ColumnConfig;
25
+ newPage: boolean;
26
+ }
27
+ /** A document comment (w:comment) referenced by a w:commentRange in the body.
28
+ * `id` matches the comment mark's ids; `text` is the flattened comment body. */
29
+ export interface CommentData {
30
+ id: number;
31
+ author: string;
32
+ date: string;
33
+ text: string;
34
+ }
35
+ /** Author of a comment / reply. `id` identifies the user (for own-only edit
36
+ * checks and @mentions); name/email/avatar are for display. */
37
+ export interface IUser {
38
+ id: string;
39
+ name: string;
40
+ email?: string;
41
+ avatar?: string;
42
+ }
43
+ /** A comment thread node stored on `doc.attrs.comments` (authoring model). The
44
+ * thread is a tree via `parentId` (null = root, the node a comment mark
45
+ * anchors to). `body` is commentSchema ProseMirror-doc JSON. `resolved` is
46
+ * meaningful only on roots. */
47
+ export interface CommentNode {
48
+ id: number;
49
+ parentId: number | null;
50
+ user: IUser;
51
+ date: string;
52
+ body: unknown;
53
+ resolved?: boolean;
54
+ }
55
+ /** A resolved font used for both measuring and painting. */
56
+ export interface FontSpec {
57
+ family: string;
58
+ /** Size in points (CSS `pt`). */
59
+ sizePt: number;
60
+ bold: boolean;
61
+ italic: boolean;
62
+ }
63
+ /** Measures the width (CSS px) of `text` rendered with `font`. */
64
+ export type MeasureText = (text: string, font: FontSpec) => number;
65
+ /** Vertical font metrics (CSS px) for baseline-accurate line boxes. */
66
+ export interface FontMetrics {
67
+ /** Distance from the baseline up to the top of the line box. */
68
+ ascent: number;
69
+ /** Distance from the baseline down to the bottom of the line box. */
70
+ descent: number;
71
+ }
72
+ /** Provides vertical metrics for a font. Injected so the engine stays pure. */
73
+ export type MeasureMetrics = (font: FontSpec) => FontMetrics;
74
+ /** A contiguous run of inline text sharing one font/color/link. */
75
+ export interface InlineRun {
76
+ text: string;
77
+ font: FontSpec;
78
+ color?: string;
79
+ link?: string;
80
+ underline?: boolean;
81
+ strike?: boolean;
82
+ /** Highlight / shading background color, e.g. "#FFFF00". */
83
+ background?: string;
84
+ /** Superscript / subscript (font already reduced; painter shifts baseline). */
85
+ vertAlign?: 'super' | 'sub';
86
+ /** Footnote reference number (w:footnoteReference): the run's text is the
87
+ * superscript mark; the body is laid out at the bottom of its page. */
88
+ footnoteRef?: number;
89
+ /** Comment ids covering this run (w:commentRangeStart/End) — painted with a
90
+ * comment tint; the sidebar locates the range by these ids. */
91
+ commentIds?: number[];
92
+ /** Absolute ProseMirror position of the run's first character. */
93
+ pos?: number;
94
+ }
95
+ /** A vector shape riding an image box (drawn, not a bitmap — `src` stays '').
96
+ * Word drawing shapes (wps/VML rect + straight connector) map to this: same
97
+ * layout semantics as an image (atomic box, inline or anchored), different
98
+ * paint. Dimensions live on the carrying image; colors are CSS. */
99
+ export interface ShapeSpec {
100
+ /** Preset geometry. Names mirror OOXML prstGeom tokens: 'line' is a
101
+ * corner-to-corner straight connector; 'rightArrow' a block arrow;
102
+ * 'horizontalScroll' paints as a stylized banner with rolled ends. */
103
+ kind: 'rect' | 'line' | 'ellipse' | 'roundRect' | 'rightArrow' | 'horizontalScroll';
104
+ /** Stroke color; absent = no stroke (a:noFill on the outline). */
105
+ stroke?: string;
106
+ /** Stroke width in px (defaults to 1 when a stroke is drawn). */
107
+ strokeWidth?: number;
108
+ /** Rect fill; absent = transparent (outline only). */
109
+ fill?: string;
110
+ /** Line drawn bottom-left → top-right instead (a:xfrm flipV). */
111
+ flipV?: boolean;
112
+ }
113
+ /** An atomic inline image laid out inline with text. Dimensions are CSS px. */
114
+ export interface InlineImage {
115
+ src: string;
116
+ width: number;
117
+ height: number;
118
+ link?: string;
119
+ /** Present when this box is a drawn vector shape instead of a bitmap. */
120
+ shape?: ShapeSpec;
121
+ /** Clockwise degrees around the box center — paint-only: the layout box
122
+ * stays axis-aligned (Word re-wraps only on commit, not live). */
123
+ rotation?: number;
124
+ /** Absolute ProseMirror position of the image node (occupies 1 position). */
125
+ pos?: number;
126
+ }
127
+ /** A dynamic field whose text is substituted at paint time (page numbers).
128
+ * Occupies one PM position, like an image atom. */
129
+ export interface InlineField {
130
+ field: 'pageNumber' | 'pageCount';
131
+ font: FontSpec;
132
+ color?: string;
133
+ pos?: number;
134
+ }
135
+ /** A forced line break inside a paragraph (w:br). Occupies one PM position. */
136
+ export interface InlineBreak {
137
+ break: true;
138
+ pos?: number;
139
+ }
140
+ /** One piece of a paragraph's inline content. Distinguish with `'src' in x`
141
+ * (image) / `'field' in x` (field) / `'break' in x` / otherwise text run. */
142
+ export type FlowInline = InlineRun | InlineImage | InlineField | InlineBreak;
143
+ /** A floating image (wp:anchor) anchored to a paragraph. Text flows around
144
+ * its rectangle ('square'), skips below it ('topAndBottom'), or ignores it
145
+ * ('none' — painted only). All values are CSS px. */
146
+ export interface FlowFloat {
147
+ src: string;
148
+ width: number;
149
+ height: number;
150
+ /** Present when this float is a drawn vector shape instead of a bitmap. */
151
+ shape?: ShapeSpec;
152
+ wrap: 'square' | 'topAndBottom' | 'none';
153
+ /** Horizontal: alignment within hRel, or an offset from its left edge. */
154
+ hAlign?: 'left' | 'right' | 'center';
155
+ hOffset?: number;
156
+ hRel?: 'margin' | 'page';
157
+ /** Vertical: offset from the anchor paragraph top / margin / page top. */
158
+ vOffset?: number;
159
+ vRel?: 'paragraph' | 'margin' | 'page';
160
+ /** Text-to-image gaps. */
161
+ distL?: number;
162
+ distR?: number;
163
+ distT?: number;
164
+ distB?: number;
165
+ /** Textbox (wps:txbx) paragraphs laid out inside the shape's box. */
166
+ content?: FlowParagraph[];
167
+ /** Textbox interior padding (wps:bodyPr lIns…), px. Absent → Word defaults. */
168
+ inset?: {
169
+ l: number;
170
+ t: number;
171
+ r: number;
172
+ b: number;
173
+ };
174
+ /** Clockwise degrees around the box center — paint-only: wrap exclusions
175
+ * keep the axis-aligned box. */
176
+ rotation?: number;
177
+ /** Absolute PM position of the carrying image node — lets the editor map a
178
+ * resolved float back to its node (resize). Absent in chrome (not
179
+ * caret-addressable). */
180
+ pos?: number;
181
+ }
182
+ /** Paragraph horizontal alignment (mirrors w:jc / CSS text-align). */
183
+ export type Align = 'left' | 'center' | 'right' | 'justify';
184
+ /** A custom tab stop (w:tabs/w:tab). `pos` is px from the paragraph's content
185
+ * left edge. `val` says how the following text aligns at the stop; `leader`
186
+ * fills the jumped-over gap (TOC dots etc.). */
187
+ export interface TabStop {
188
+ pos: number;
189
+ val: 'left' | 'right' | 'center' | 'decimal';
190
+ leader?: 'dot' | 'hyphen' | 'underscore' | 'middleDot';
191
+ }
192
+ /** Paragraph indentation in CSS px (mirrors w:ind). `firstLine` and `hanging`
193
+ * are mutually exclusive; if both are present, `hanging` takes precedence. */
194
+ export interface ParagraphIndent {
195
+ left?: number;
196
+ right?: number;
197
+ firstLine?: number;
198
+ hanging?: number;
199
+ }
200
+ /** Paragraph spacing (mirrors w:spacing). `before`/`after` are px gaps around
201
+ * the paragraph; `line` is the inter-line measure interpreted by `lineRule`:
202
+ * 'auto' → multiple of the natural line height, 'exact'/'atLeast' → px. */
203
+ export interface ParagraphSpacing {
204
+ before?: number;
205
+ after?: number;
206
+ line?: number;
207
+ lineRule?: 'auto' | 'exact' | 'atLeast';
208
+ }
209
+ /** A block flattened and ready for layout (paragraph only, for now). */
210
+ export interface FlowParagraph {
211
+ type: 'paragraph';
212
+ /** Ordered inline content: text runs and atomic images. */
213
+ runs: FlowInline[];
214
+ /** List marker text (e.g. "1.", "•") if this paragraph is a list item. */
215
+ marker?: string;
216
+ /** Horizontal alignment; defaults to 'left' when omitted. */
217
+ align?: Align;
218
+ /** Indentation in CSS px; defaults to no indent when omitted. */
219
+ indent?: ParagraphIndent;
220
+ /** Line spacing + space before/after; defaults to single, no gaps. */
221
+ spacing?: ParagraphSpacing;
222
+ /** Force this paragraph to start a new page (w:pageBreakBefore / a page
223
+ * break run at its head). */
224
+ pageBreakBefore?: boolean;
225
+ /** Absolute PM position where the paragraph's content starts (nodePos + 1). */
226
+ pos?: number;
227
+ /** Absolute PM position after the paragraph's last character. */
228
+ end?: number;
229
+ /** Floating images anchored to this paragraph. */
230
+ floats?: FlowFloat[];
231
+ /** Custom tab stops; tabs past the last stop use the default grid. */
232
+ tabs?: TabStop[];
233
+ }
234
+ /** A table cell, holding nested flow content (paragraphs / tables). */
235
+ export interface FlowTableCell {
236
+ colspan: number;
237
+ rowspan: number;
238
+ /** Px widths of the spanned grid columns, or null to derive equally. */
239
+ colwidth: number[] | null;
240
+ /** Cell fill color (w:shd), e.g. "#D9E2F3". */
241
+ background?: string;
242
+ /** Vertical alignment of content within the cell (w:vAlign); top default. */
243
+ vAlign?: 'center' | 'bottom';
244
+ /** Per-cell border overrides (w:tcBorders); each side overrides the table. */
245
+ borders?: TableBorders;
246
+ content: FlowBlock[];
247
+ }
248
+ export interface FlowTableRow {
249
+ cells: FlowTableCell[];
250
+ /** Repeat this row at the top of every page the table spans (w:tblHeader).
251
+ * Only honored for contiguous header rows at the top of the table. */
252
+ header?: boolean;
253
+ /** w:cantSplit — never break this row across pages (Word default allows). */
254
+ cantSplit?: boolean;
255
+ /** Explicit row height (w:trHeight): a floor, or `exact` to force it. */
256
+ height?: {
257
+ value: number;
258
+ exact: boolean;
259
+ };
260
+ }
261
+ /** Which table borders are visible (w:tblBorders). OOXML tables have NO
262
+ * borders unless declared — absence of this object means draw nothing. */
263
+ /** Stroke style of a visible border edge (maps to/from w:val). */
264
+ export type BorderStyle = 'solid' | 'dashed' | 'dotted' | 'double';
265
+ /** Appearance of one visible border edge. */
266
+ export interface BorderSide {
267
+ /** Stroke width in CSS px. */
268
+ width: number;
269
+ style: BorderStyle;
270
+ /** Hex colour, e.g. "#000000". */
271
+ color: string;
272
+ }
273
+ /**
274
+ * Per-side border appearance. A side holding a {@link BorderSide} is visible
275
+ * with that width/style/colour; `false` is an explicit "no border"; an absent
276
+ * side inherits (a cell falls back to the table's outer/inside border).
277
+ */
278
+ export interface TableBorders {
279
+ top?: BorderSide | false;
280
+ bottom?: BorderSide | false;
281
+ left?: BorderSide | false;
282
+ right?: BorderSide | false;
283
+ insideH?: BorderSide | false;
284
+ insideV?: BorderSide | false;
285
+ }
286
+ /** Cell padding overrides (px) from w:tblCellMar; unset sides use defaults. */
287
+ export interface CellPadding {
288
+ left?: number;
289
+ right?: number;
290
+ top?: number;
291
+ bottom?: number;
292
+ }
293
+ /** A table flattened and ready for layout. */
294
+ export interface FlowTable {
295
+ type: 'table';
296
+ rows: FlowTableRow[];
297
+ cellPadding?: CellPadding;
298
+ borders?: TableBorders;
299
+ /** Table alignment within the content area (w:jc); left default. */
300
+ align?: 'center' | 'right';
301
+ }
302
+ export type FlowBlock = FlowParagraph | FlowTable;
303
+ export interface LayoutConfig {
304
+ page: PageConfig;
305
+ measureText: MeasureText;
306
+ /** Optional vertical metrics. When provided, line boxes use real
307
+ * ascent/descent; otherwise a font-size factor approximates them. */
308
+ measureMetrics?: MeasureMetrics;
309
+ /** Default tab-stop interval in px (Word's default is 48px = 0.5in). */
310
+ tabWidth?: number;
311
+ /** Defaults for runs that don't specify a value. */
312
+ defaultFont?: Partial<FontSpec>;
313
+ /** Whole-document column config for the flat (FlowBlock) layout path. The PM
314
+ * doc path reads per-section columns from the doc instead. */
315
+ columns?: ColumnConfig;
316
+ }
317
+ /** One painted text segment, positioned in page coordinates (px). */
318
+ export interface LayoutSegment {
319
+ x: number;
320
+ text: string;
321
+ font: FontSpec;
322
+ color?: string;
323
+ link?: string;
324
+ underline?: boolean;
325
+ strike?: boolean;
326
+ /** Highlight / shading background painted behind the text. */
327
+ background?: string;
328
+ /** Superscript / subscript: the painter shifts the baseline (font is
329
+ * already the reduced size). */
330
+ vertAlign?: 'super' | 'sub';
331
+ /** Measured width (px) — lets the painter draw text decorations without
332
+ * re-measuring at paint time. */
333
+ width?: number;
334
+ /** Dynamic field: the painter substitutes the page number / page count for
335
+ * `text` while painting. The segment occupies ONE PM position. */
336
+ field?: 'pageNumber' | 'pageCount';
337
+ /** Footnote reference number: the placer counts which notes land on each
338
+ * page so it can reserve bottom space and lay their bodies out there. */
339
+ footnoteRef?: number;
340
+ /** Comment ids covering this segment (w:commentRangeStart/End) — the painter
341
+ * tints it; null/absent means no comment. */
342
+ commentIds?: number[];
343
+ /** Absolute PM position of the segment's first character. Segments without
344
+ * a position (list markers) are decoration — not addressable by a caret. */
345
+ pos?: number;
346
+ }
347
+ /** A painted inline image; (x) is its left edge, sitting on the line baseline.
348
+ * width/height are CSS px. */
349
+ export interface LayoutImageSegment {
350
+ x: number;
351
+ src: string;
352
+ width: number;
353
+ height: number;
354
+ link?: string;
355
+ /** Present when this box is a drawn vector shape instead of a bitmap. */
356
+ shape?: ShapeSpec;
357
+ /** Clockwise degrees around the box center (paint-only). */
358
+ rotation?: number;
359
+ /** Absolute PM position of the image node (occupies 1 position). */
360
+ pos?: number;
361
+ }
362
+ /** A laid-out line; (x, y) is its top-left in page coordinates (px). */
363
+ export interface LayoutLine {
364
+ x: number;
365
+ y: number;
366
+ width: number;
367
+ height: number;
368
+ /** Baseline offset from the line's top (px). */
369
+ baseline: number;
370
+ segments: LayoutSegment[];
371
+ /** Inline images on this line, positioned like segments. */
372
+ images?: LayoutImageSegment[];
373
+ /** PM position of the line's first caret slot. */
374
+ from?: number;
375
+ /** PM position after the line's last painted content. */
376
+ to?: number;
377
+ }
378
+ /** A laid-out table cell. All coordinates are page-absolute (px); `lines` and
379
+ * `tables` are the cell's content, already positioned inside the cell box. */
380
+ export interface ResolvedCell {
381
+ x: number;
382
+ y: number;
383
+ width: number;
384
+ height: number;
385
+ colspan: number;
386
+ rowspan: number;
387
+ lines: LayoutLine[];
388
+ /** Cell fill color, painted behind the content. */
389
+ background?: string;
390
+ /** Per-cell border overrides; each side overrides the table's edge. */
391
+ borders?: TableBorders;
392
+ /** Tables nested inside this cell. */
393
+ tables?: ResolvedTable[];
394
+ /** Anchored images/shapes positioned within this cell (v1: painted at their
395
+ * anchor offsets; cell text does not wrap around them). */
396
+ floats?: ResolvedFloat[];
397
+ }
398
+ /** A laid-out table; (x, y) is its top-left in page coordinates (px). */
399
+ export interface ResolvedTable {
400
+ x: number;
401
+ y: number;
402
+ width: number;
403
+ height: number;
404
+ cells: ResolvedCell[];
405
+ /** Bottom edge (px from the table top) of the repeating header band, when
406
+ * the table's leading rows are marked as header rows. */
407
+ headerBottom?: number;
408
+ /** Vertical bands (px from the table top) of rows marked w:cantSplit — the
409
+ * paginator moves these whole instead of splitting them mid-content. */
410
+ cantSplitBands?: {
411
+ top: number;
412
+ bottom: number;
413
+ }[];
414
+ /** Visible borders; absent → the table paints borderless (OOXML default). */
415
+ borders?: TableBorders;
416
+ }
417
+ /** A floating image placed on a page (page-local coordinates, px). */
418
+ export interface ResolvedFloat {
419
+ x: number;
420
+ y: number;
421
+ width: number;
422
+ height: number;
423
+ src: string;
424
+ /** Present when this float is a drawn vector shape instead of a bitmap. */
425
+ shape?: ShapeSpec;
426
+ /** Textbox text laid out inside the shape, in BOX-LOCAL coordinates
427
+ * (origin at the float's top-left) — the painter translates by (x, y).
428
+ * Never caret-addressable; PM positions are stripped. */
429
+ lines?: LayoutLine[];
430
+ /** Clockwise degrees around the box center (paint-only). */
431
+ rotation?: number;
432
+ /** Absolute PM position of the carrying image node (absent in chrome). */
433
+ pos?: number;
434
+ }
435
+ export interface ResolvedPage {
436
+ index: number;
437
+ width: number;
438
+ height: number;
439
+ lines: LayoutLine[];
440
+ /** Tables on this page, positioned in page coordinates. */
441
+ tables?: ResolvedTable[];
442
+ /** Floating images on this page (painted behind the text). */
443
+ floats?: ResolvedFloat[];
444
+ /** Footnote bodies whose references fall on this page, laid out at the
445
+ * bottom above the footer. Absent when the page has no footnotes. */
446
+ footnotes?: ResolvedFootnotes;
447
+ }
448
+ /** Footnote bodies reserved at the bottom of a page. `separatorY` is where the
449
+ * short rule above the notes is drawn; `lines` are the note bodies, already
450
+ * positioned in page coordinates (px). */
451
+ export interface ResolvedFootnotes {
452
+ separatorY: number;
453
+ lines: LayoutLine[];
454
+ }
455
+ /** Repeating page furniture (a header or footer band). Coordinates are
456
+ * page-local; the painter stamps it onto every page. Not caret-addressable —
457
+ * PM positions are stripped (the band belongs to a separate document). */
458
+ export interface ResolvedChrome {
459
+ lines: LayoutLine[];
460
+ tables: ResolvedTable[];
461
+ /** Anchored images/shapes positioned within the band (e.g. the horizontal
462
+ * rule real headers draw under their contact block). Painted only — the
463
+ * chrome text does not wrap around them. */
464
+ floats?: ResolvedFloat[];
465
+ height: number;
466
+ }
467
+ /** The paint-ready result the canvas painter consumes (M3). */
468
+ export interface ResolvedLayout {
469
+ pages: ResolvedPage[];
470
+ /** Default (odd-page) header/footer, stamped on every page unless a
471
+ * first/even variant applies (see chromeSelect). */
472
+ pageHeader?: ResolvedChrome;
473
+ pageFooter?: ResolvedChrome;
474
+ /** Title-page header/footer (w:type="first"), shown on page 1 when
475
+ * chromeSelect.titlePg is set. */
476
+ pageHeaderFirst?: ResolvedChrome;
477
+ pageFooterFirst?: ResolvedChrome;
478
+ /** Even-page header/footer (w:type="even"), shown on even pages when
479
+ * chromeSelect.evenAndOdd is set. */
480
+ pageHeaderEven?: ResolvedChrome;
481
+ pageFooterEven?: ResolvedChrome;
482
+ /** Which chrome variant applies per page. `titlePg` → page 1 uses the first
483
+ * variant (blank if none); `evenAndOdd` → even pages use the even variant. */
484
+ chromeSelect?: {
485
+ titlePg: boolean;
486
+ evenAndOdd: boolean;
487
+ };
488
+ }
489
+ /** A point in page-local coordinates (px), tagged with its page. */
490
+ export interface PagePoint {
491
+ pageIndex: number;
492
+ x: number;
493
+ y: number;
494
+ }
495
+ /** Caret placement in page-local coordinates (px). */
496
+ export interface CaretRect {
497
+ pageIndex: number;
498
+ x: number;
499
+ y: number;
500
+ height: number;
501
+ }
502
+ /** One highlighted rectangle of a selection, in page-local coordinates. */
503
+ export interface SelectionRect {
504
+ pageIndex: number;
505
+ x: number;
506
+ y: number;
507
+ width: number;
508
+ height: number;
509
+ }
510
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/lib/contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,185 @@
1
+ import type { EditorState, Transaction } from 'prosemirror-state';
2
+ import type { MarkSpec, NodeSpec } from 'prosemirror-model';
3
+ import type { CaretRect, PagePoint, ResolvedLayout, SelectionRect } from './contracts.js';
4
+ /** A decoration a plugin paints over a document range (comment tint, find
5
+ * highlight, track-change underline…). Doc positions; the editor resolves them
6
+ * to page geometry before painting. */
7
+ export interface RangeDecoration {
8
+ from: number;
9
+ to: number;
10
+ kind: 'background' | 'underline' | 'strike';
11
+ color: string;
12
+ }
13
+ /** A {@link RangeDecoration} resolved to page-local rects — what the painter
14
+ * consumes (it never maps doc positions itself). */
15
+ export interface PaintDecoration {
16
+ rects: SelectionRect[];
17
+ kind: 'background' | 'underline' | 'strike';
18
+ color: string;
19
+ }
20
+ /**
21
+ * Emitted after every editor layout/paint cycle so a host (any framework) and
22
+ * plugins can mirror document state — page count, comment threads (on
23
+ * doc.attrs), selection.
24
+ */
25
+ export interface EditorChange {
26
+ /** The current editor state (doc + selection). */
27
+ state: EditorState;
28
+ /** Number of laid-out pages. */
29
+ pageCount: number;
30
+ /** Whether the doc changed this cycle (false = selection-only). Consumers use
31
+ * it to skip rebuilding doc-derived UI (comment sidebars, JSON panels). */
32
+ docChanged: boolean;
33
+ }
34
+ /**
35
+ * A pointer event on the canvas, offered to plugins (via
36
+ * {@link EditorPlugin.onPointer}) before the editor's own caret/selection
37
+ * handling. `point` is page-local geometry; `pos` is the document position under
38
+ * it (computed for `down`/`up`/`contextmenu` — null for `move`, which fires on
39
+ * every hover, to keep hover cheap). A plugin returns true to claim the event.
40
+ */
41
+ export interface EditorPointerEvent {
42
+ type: 'down' | 'move' | 'up' | 'contextmenu';
43
+ /** Page-local point under the pointer, or null if outside any page. */
44
+ point: PagePoint | null;
45
+ /** Document position under the point (null for `move`). */
46
+ pos: number | null;
47
+ /** Viewport coordinates (for positioning UI like a context menu). */
48
+ clientX: number;
49
+ clientY: number;
50
+ /** Mouse buttons bitmask. */
51
+ buttons: number;
52
+ /** Modifier keys held — e.g. Ctrl/Cmd-click to open a hyperlink. */
53
+ ctrlKey: boolean;
54
+ metaKey: boolean;
55
+ shiftKey: boolean;
56
+ altKey: boolean;
57
+ }
58
+ /** A keyboard event offered to plugins (via {@link EditorPlugin.onKey})
59
+ * before the editor's own keymaps see it. */
60
+ export interface EditorKeyEvent {
61
+ /** `KeyboardEvent.key` — e.g. "Escape", "Enter", "a". */
62
+ key: string;
63
+ ctrlKey: boolean;
64
+ metaKey: boolean;
65
+ shiftKey: boolean;
66
+ altKey: boolean;
67
+ }
68
+ /** A transient vertical guide line shown during a drag (page-local geometry) —
69
+ * e.g. a column-resize preview. The editor positions it on the canvas. */
70
+ export interface OverlayGuide {
71
+ pageIndex: number;
72
+ x: number;
73
+ y: number;
74
+ height: number;
75
+ }
76
+ /** A selection frame around an object (image resize): border + 8 resize
77
+ * handles + a rotate knob above the top edge, rotated by `rotation` degrees
78
+ * around the rect center. Page-local geometry; purely visual — the plugin
79
+ * hit-tests handles itself from the same numbers. */
80
+ export interface OverlayFrame {
81
+ pageIndex: number;
82
+ x: number;
83
+ y: number;
84
+ width: number;
85
+ height: number;
86
+ /** Clockwise degrees around the rect center (default 0). */
87
+ rotation?: number;
88
+ /** Small readout above the frame (e.g. "320 × 214" during a resize). */
89
+ label?: string;
90
+ }
91
+ /** A page-local rect the editor fills as a translucent highlight (e.g. a
92
+ * selected table-cell block). */
93
+ export interface OverlayRect {
94
+ pageIndex: number;
95
+ x: number;
96
+ y: number;
97
+ width: number;
98
+ height: number;
99
+ }
100
+ /**
101
+ * The controlled surface an {@link EditorPlugin} gets onto the editor core:
102
+ * read/dispatch document state plus the geometry + paint helpers it needs to
103
+ * anchor UI. The editor hands one of these to each plugin's `setup`.
104
+ */
105
+ export interface PluginContext {
106
+ /** Current editor state (doc + selection). Live — read it each time. */
107
+ readonly state: EditorState;
108
+ /** Apply a ProseMirror transaction. */
109
+ dispatch(tr: Transaction): void;
110
+ /** Caret geometry at a doc position (page-local), or null. */
111
+ caretRect(pos: number): CaretRect | null;
112
+ /** Map a page-local point to canvas-stack coordinates, or null. */
113
+ pageToCanvas(p: {
114
+ pageIndex: number;
115
+ x: number;
116
+ y: number;
117
+ }): {
118
+ x: number;
119
+ y: number;
120
+ } | null;
121
+ /** Move the selection (caret if `to` omitted). */
122
+ setSelection(from: number, to?: number): void;
123
+ /** Scroll the viewport so the caret at `pos` sits `topMargin` px from the top. */
124
+ scrollToPos(pos: number, topMargin?: number): void;
125
+ /** Force a content repaint (e.g. after a plugin's decorations change). */
126
+ requestPaint(): void;
127
+ /** The current paint-ready layout (page/table/cell geometry), or null before
128
+ * a document loads. Lets pointer plugins hit-test tables/columns. */
129
+ readonly layout: ResolvedLayout | null;
130
+ /** Set the canvas cursor (e.g. `'col-resize'`); null restores the default. */
131
+ setCursor(cursor: string | null): void;
132
+ /** Show a transient vertical guide (e.g. a column-resize preview), or null to
133
+ * clear it. Page-local geometry; the editor positions it on the canvas. */
134
+ setGuide(guide: OverlayGuide | null): void;
135
+ /** Fill these page-local rects as a translucent highlight (e.g. a selected
136
+ * table-cell block), or null to clear. The editor renders them on the canvas. */
137
+ setHighlight(rects: OverlayRect[] | null): void;
138
+ /** Show an object-selection frame (border + resize handles + rotate knob),
139
+ * or null to clear. Page-local geometry; the editor renders it as DOM
140
+ * overlay in the canvas stack — no canvas repaint. */
141
+ setFrame(frame: OverlayFrame | null): void;
142
+ /** Show a small action button straddling a page-local point (e.g. a selected
143
+ * cell block's top-right), invoking `onActivate` on click/tap; null clears it.
144
+ * A touch-friendly trigger where hover/right-click aren't available. */
145
+ setActionButton(at: PagePoint | null, onActivate?: () => void): void;
146
+ }
147
+ /**
148
+ * A framework-agnostic editor extension. The editor invokes these hooks; the
149
+ * plugin reaches back through {@link PluginContext}. Every hook is optional — a
150
+ * plugin implements only what it needs.
151
+ *
152
+ * This is the stable contract both the editor (which calls the hooks) and
153
+ * plugin packages (which implement them) depend on, so neither needs to import
154
+ * the other. Decoration / schema / docx-part hooks are introduced in later
155
+ * phases; adding them is purely additive.
156
+ */
157
+ export interface EditorPlugin {
158
+ /** Stable identifier (also used for diagnostics). */
159
+ readonly name: string;
160
+ /** Schema contributions merged into the editor's document schema, so a plugin
161
+ * can own its marks/nodes. Composed once when a document loads. */
162
+ schema?: {
163
+ marks?: Record<string, MarkSpec>;
164
+ nodes?: Record<string, NodeSpec>;
165
+ };
166
+ /** Called once when the editor is constructed; may return a teardown fn. */
167
+ setup?(ctx: PluginContext): void | (() => void);
168
+ /** Called after every editor layout/paint cycle. */
169
+ onChange?(change: EditorChange): void;
170
+ /** Called when a pointerdown places the caret at doc position `pos`. */
171
+ onCaretPick?(pos: number): void;
172
+ /** Decorations to paint this content frame (collected on every content
173
+ * repaint; call `ctx.requestPaint()` when they change). */
174
+ decorations?(ctx: PluginContext): RangeDecoration[];
175
+ /** Pointer activity on the canvas, offered before the editor's own
176
+ * caret/selection handling. Return true to claim the event (the editor then
177
+ * preventDefaults it, captures the pointer on `down`, and skips its default).
178
+ * `move` fires on every hover (for cursor feedback / drag). */
179
+ onPointer?(ev: EditorPointerEvent): boolean;
180
+ /** Keyboard input, offered before the editor's keymaps (typing, undo,
181
+ * arrows) — e.g. Escape cancelling an in-flight drag gesture. Return true
182
+ * to claim (the editor preventDefaults and stops the event). */
183
+ onKey?(ev: EditorKeyEvent): boolean;
184
+ }
185
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/lib/plugin.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@shadow-garden/bapbong-contracts",
3
+ "version": "0.1.0",
4
+ "description": "bapbong — shared layout + plugin contracts/types (type-only deps)",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/shadowgarden-app/bapbong.git",
9
+ "directory": "packages/contracts"
10
+ },
11
+ "type": "module",
12
+ "main": "./dist/index.cjs",
13
+ "module": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ "./package.json": "./package.json",
17
+ ".": {
18
+ "@shadow-garden/source": "./src/index.ts",
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js",
21
+ "require": "./dist/index.cjs",
22
+ "default": "./dist/index.js"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "!**/*.tsbuildinfo"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "nx": {
33
+ "tags": [
34
+ "scope:pure"
35
+ ],
36
+ "targets": {
37
+ "build": {
38
+ "executor": "@nx/esbuild:esbuild",
39
+ "outputs": [
40
+ "{options.outputPath}"
41
+ ],
42
+ "options": {
43
+ "outputPath": "packages/contracts/dist",
44
+ "main": "packages/contracts/src/index.ts",
45
+ "tsConfig": "packages/contracts/tsconfig.lib.json",
46
+ "format": [
47
+ "esm",
48
+ "cjs"
49
+ ],
50
+ "declarationRootDir": "packages/contracts/src"
51
+ }
52
+ }
53
+ }
54
+ },
55
+ "dependencies": {
56
+ "prosemirror-model": "^1.25.7",
57
+ "prosemirror-state": "^1.4.4"
58
+ }
59
+ }