@phuong-tran-redoc/document-engine-core 0.1.0 → 0.1.1
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/README.md +105 -115
- package/THIRD-PARTY-NOTICES.txt +67 -0
- package/package.json +8 -1
- package/src/__tests__/helpers/editor-factory.d.ts +0 -13
- package/src/__tests__/helpers/editor-factory.js +0 -25
package/README.md
CHANGED
|
@@ -2,210 +2,202 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@phuong-tran-redoc/document-engine-core) 
|
|
4
4
|
|
|
5
|
-
A **framework-agnostic** document editor core
|
|
5
|
+
A **framework-agnostic** document editor core built on [Tiptap](https://tiptap.dev/) and [ProseMirror](https://prosemirror.net/). It packages the custom extensions, nodes, schema kit, and headless helpers that power the Document Engine, with no framework dependency.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## 🎯 Overview
|
|
10
10
|
|
|
11
|
-
`document-engine-core` is the heart of the Document Engine
|
|
11
|
+
`document-engine-core` is the heart of the Document Engine. It contains the editor schema (the canonical extension/node set), business extensions (dynamic fields, restricted editing, styled tables, indentation, text case), a headless HTML serializer, and a small document-migration system — all as plain ESM TypeScript that runs in the browser or in Node.
|
|
12
12
|
|
|
13
13
|
### Key Features
|
|
14
14
|
|
|
15
|
-
- **Framework-
|
|
16
|
-
- **
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- **
|
|
21
|
-
- **JSON-based Data Model:** Documents are represented as structured JSON, not raw HTML
|
|
22
|
-
- **TypeScript-First:** Full type safety and IntelliSense support
|
|
23
|
-
- **Extensible Architecture:** Easy to add custom extensions and plugins
|
|
15
|
+
- **Framework-agnostic ESM:** pure TypeScript, usable from Angular, React, Vue, or headless Node.
|
|
16
|
+
- **Ready-made schema kit:** `defaultExtensions` — the canonical node/mark/structure set the editor ships with.
|
|
17
|
+
- **Business extensions:** Dynamic Fields (`{{customer_name}}`), Restricted Editing (editable regions), Styled Tables, Indent, Text Case, custom Ordered List.
|
|
18
|
+
- **Headless serialization:** `generateHTML(doc)` renders a ProseMirror JSON document to HTML on the server (env-aware) or in the browser.
|
|
19
|
+
- **Document migrations:** `EditorDocument` wrapper + `migrateDoc()` to version and upgrade stored content.
|
|
20
|
+
- **JSON-first data model:** documents are ProseMirror JSON, not raw HTML.
|
|
24
21
|
|
|
25
22
|
---
|
|
26
23
|
|
|
27
24
|
## 📦 Installation
|
|
28
25
|
|
|
29
|
-
> ⚠️ **This is a private package. Please contact an authorized person to install it.**
|
|
30
|
-
|
|
31
26
|
```bash
|
|
32
27
|
npm install @phuong-tran-redoc/document-engine-core
|
|
33
28
|
# or
|
|
34
29
|
pnpm add @phuong-tran-redoc/document-engine-core
|
|
35
30
|
```
|
|
36
31
|
|
|
32
|
+
Published publicly on npm under the MIT license.
|
|
33
|
+
|
|
37
34
|
### Peer Dependencies
|
|
38
35
|
|
|
36
|
+
Only one peer dependency — Tiptap/ProseMirror ship as bundled dependencies and are installed automatically:
|
|
37
|
+
|
|
39
38
|
```json
|
|
40
39
|
{
|
|
41
|
-
"
|
|
42
|
-
"@tiptap/pm": "^2.x.x"
|
|
40
|
+
"lodash-es": "^4.17.10"
|
|
43
41
|
}
|
|
44
42
|
```
|
|
45
43
|
|
|
44
|
+
> Built against `@tiptap/* ^3.26.0` (bundled). If your app also uses Tiptap directly, align on the same major to share a single ProseMirror instance.
|
|
45
|
+
|
|
46
46
|
---
|
|
47
47
|
|
|
48
48
|
## 🚀 Quick Start
|
|
49
49
|
|
|
50
|
-
###
|
|
50
|
+
### Build an editor with the default schema
|
|
51
51
|
|
|
52
52
|
```typescript
|
|
53
53
|
import { Editor } from '@tiptap/core';
|
|
54
|
-
import {
|
|
54
|
+
import { defaultExtensions } from '@phuong-tran-redoc/document-engine-core';
|
|
55
55
|
|
|
56
|
-
// Create an editor instance with Document Engine extensions
|
|
57
56
|
const editor = new Editor({
|
|
58
|
-
element: document.querySelector('#editor')
|
|
59
|
-
extensions: [...
|
|
57
|
+
element: document.querySelector('#editor')!,
|
|
58
|
+
extensions: [...defaultExtensions],
|
|
60
59
|
content: '<p>Hello World!</p>',
|
|
61
60
|
});
|
|
62
61
|
```
|
|
63
62
|
|
|
64
|
-
###
|
|
63
|
+
### Dynamic fields
|
|
65
64
|
|
|
66
65
|
```typescript
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
name: 'customer_name',
|
|
72
|
-
label: 'Customer Name',
|
|
73
|
-
});
|
|
66
|
+
// Insert a {{customer_name}} placeholder
|
|
67
|
+
editor.commands.insertDynamicField({ fieldId: 'customer_name', label: 'Customer Name' });
|
|
68
|
+
// Renders: <span data-field-id="customer_name" data-label="Customer Name" class="dynamic-field">{{customer_name}}</span>
|
|
69
|
+
```
|
|
74
70
|
|
|
75
|
-
|
|
76
|
-
const fields = editor.commands.getDynamicFields();
|
|
71
|
+
### Restricted editing (editable regions)
|
|
77
72
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
73
|
+
```typescript
|
|
74
|
+
// Wrap the current selection in an editable region
|
|
75
|
+
editor.commands.wrapSelectionInEditableRegion();
|
|
76
|
+
editor.commands.toggleEditableRegion();
|
|
77
|
+
editor.commands.removeEditableRegion();
|
|
83
78
|
```
|
|
84
79
|
|
|
85
|
-
###
|
|
80
|
+
### Other custom commands
|
|
86
81
|
|
|
87
82
|
```typescript
|
|
88
|
-
|
|
83
|
+
editor.commands.insertPageBreak(); // PageBreak node
|
|
84
|
+
editor.commands.insertImageRef({ imageId: 'logo-01' }); // URL-free image reference
|
|
85
|
+
editor.commands.textCase('uppercase'); // TextCase: 'uppercase' | 'lowercase' | 'capitalize'
|
|
86
|
+
editor.commands.increaseIndent(); // Indent
|
|
87
|
+
editor.commands.setListStyle('lower-alpha'); // CustomOrderedList
|
|
88
|
+
```
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
editor.commands.setEditableRegion();
|
|
90
|
+
### Headless HTML (server-side)
|
|
92
91
|
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
```typescript
|
|
93
|
+
import { generateHTML, defaultExtensions } from '@phuong-tran-redoc/document-engine-core';
|
|
95
94
|
|
|
96
|
-
//
|
|
97
|
-
|
|
95
|
+
// generateHTML(doc: JSONContent, extensions = defaultExtensions): Promise<string>
|
|
96
|
+
const html = await generateHTML(myProseMirrorJSON);
|
|
98
97
|
```
|
|
99
98
|
|
|
100
|
-
|
|
99
|
+
### Versioned documents + migrations
|
|
101
100
|
|
|
102
|
-
|
|
101
|
+
```typescript
|
|
102
|
+
import { migrateDoc, LATEST_SCHEMA_VERSION, type EditorDocument } from '@phuong-tran-redoc/document-engine-core';
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
├── extensions/ # Custom Tiptap extensions
|
|
107
|
-
│ ├── dynamic-field/ # Dynamic field support
|
|
108
|
-
│ ├── restricted/ # Restricted editing
|
|
109
|
-
│ └── ...
|
|
110
|
-
├── nodes/ # Custom document nodes
|
|
111
|
-
├── marks/ # Custom text marks
|
|
112
|
-
├── plugins/ # ProseMirror plugins
|
|
113
|
-
├── commands/ # Editor commands
|
|
114
|
-
├── utils/ # Utility functions
|
|
115
|
-
└── types/ # TypeScript type definitions
|
|
104
|
+
const stored: EditorDocument = { schemaVersion: 0, content: myProseMirrorJSON };
|
|
105
|
+
const upgraded = migrateDoc(stored); // walks registered migrations up to LATEST_SCHEMA_VERSION
|
|
116
106
|
```
|
|
117
107
|
|
|
118
108
|
---
|
|
119
109
|
|
|
120
|
-
##
|
|
110
|
+
## 📦 Public API
|
|
121
111
|
|
|
122
|
-
|
|
112
|
+
Everything below is re-exported from the package entry (`@phuong-tran-redoc/document-engine-core`).
|
|
123
113
|
|
|
124
|
-
|
|
114
|
+
### Extensions (`extensions`)
|
|
125
115
|
|
|
126
|
-
|
|
116
|
+
| Export | Notable commands |
|
|
117
|
+
| --- | --- |
|
|
118
|
+
| `ClearContent` | `clear()` |
|
|
119
|
+
| `Indent` | `increaseIndent()`, `decreaseIndent()` |
|
|
120
|
+
| `CustomOrderedList` | `toggleOrderedList()`, `setListStyle(type)` |
|
|
121
|
+
| `ResetFormat` | `resetFormat()` |
|
|
122
|
+
| `ResetOnEnter` | — (Enter-key behavior) |
|
|
123
|
+
| `RestrictedEditing` (+ `EditableRegion`) | `wrapSelectionInEditableRegion()`, `toggleEditableRegion()`, `removeEditableRegion()` |
|
|
124
|
+
| `StyledTable` / `StyledTableKit` (+ `StyledTableCell`, `StyledTableHeader`) | `insertTable()`, `setTableBorder()`, `setTableBackgroundColor()`, `setCellBackgroundColor()`, `setCellTextAlign()`, … |
|
|
125
|
+
| `TextCase` | `textCase(type)` |
|
|
127
126
|
|
|
128
|
-
|
|
129
|
-
- List all fields in document
|
|
130
|
-
- Batch replace field values
|
|
131
|
-
- Custom field styling
|
|
127
|
+
### Nodes (`nodes`)
|
|
132
128
|
|
|
133
|
-
|
|
129
|
+
| Export | Renders |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `DynamicField` | inline `<span data-field-id …>{{fieldId}}</span>` — `insertDynamicField({ fieldId, label })` |
|
|
132
|
+
| `PageBreak` | `<div data-page-break="true" …>` — `insertPageBreak()` |
|
|
133
|
+
| `ImageRef` | `<figure data-block="image-ref" data-image-id …>` (+ optional `<figcaption>`) — `insertImageRef({ imageId, caption?, captionPosition? })` |
|
|
134
|
+
| `NotumHeading` | extends Tiptap `Heading` — `removeHeading()` |
|
|
134
135
|
|
|
135
|
-
|
|
136
|
+
### Kit (`kit`)
|
|
136
137
|
|
|
137
|
-
|
|
138
|
+
- `defaultExtensions: Extensions` — the canonical schema (nodes, marks, structures).
|
|
139
|
+
- `generateHTML(doc, extensions?): Promise<string>` — async, environment-aware headless serializer.
|
|
138
140
|
|
|
139
|
-
|
|
140
|
-
- Lock/unlock document
|
|
141
|
-
- Visual indicators for editable areas
|
|
142
|
-
- Keyboard navigation between editable regions
|
|
141
|
+
### Migrations (`migrations`)
|
|
143
142
|
|
|
144
|
-
|
|
143
|
+
- `EditorDocument` — `{ schemaVersion: number; content: JSONContent }`.
|
|
144
|
+
- `LATEST_SCHEMA_VERSION` — current schema version.
|
|
145
|
+
- `docMigrations` — the migration registry.
|
|
146
|
+
- `migrateDoc(doc, migrations?, latest?)` — pure upgrade walker.
|
|
145
147
|
|
|
146
|
-
|
|
148
|
+
### Models, types, utils, views
|
|
147
149
|
|
|
148
|
-
**
|
|
150
|
+
- **models:** `Color` (`Color.from()`, `.equals()`, `.is()`).
|
|
151
|
+
- **types:** `ListStyleType`, `TextCaseType`, `ImageRefAttributes`, `DynamicFieldAttributes`, `DynamicFieldItem`, `DynamicFieldCategory`, …
|
|
152
|
+
- **utils:** `normalizeColor` (color), `getClosestDomElement` (dom), `getCursorCellInfo` / `getSelectedCells` (table), `getSelectedText` / `getActiveMarkRange` (text).
|
|
153
|
+
- **views:** `HandleNodeView`, `TableNodeView`, `PageBreakNodeView`, `createTableNodeView`, `createPageBreakNodeView`.
|
|
154
|
+
- **constants:** `INDENT_DEFAULT`.
|
|
149
155
|
|
|
150
|
-
|
|
151
|
-
- Add/remove rows and columns
|
|
152
|
-
- Table headers
|
|
153
|
-
- Cell styling
|
|
154
|
-
|
|
155
|
-
_(More extensions to be documented)_
|
|
156
|
+
> The package entry `index.ts` is the public contract — additive changes only between minor versions.
|
|
156
157
|
|
|
157
158
|
---
|
|
158
159
|
|
|
159
|
-
##
|
|
160
|
+
## 🏗️ Source Layout
|
|
160
161
|
|
|
161
|
-
### Building
|
|
162
|
-
|
|
163
|
-
Build the library:
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
nx build document-engine-core
|
|
167
162
|
```
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
163
|
+
document-engine-core/src/
|
|
164
|
+
├── constants/ # exported constants (e.g. INDENT_DEFAULT)
|
|
165
|
+
├── extensions/ # custom Tiptap extensions
|
|
166
|
+
├── kit/ # defaultExtensions + generateHTML
|
|
167
|
+
├── migrations/ # EditorDocument + migrateDoc
|
|
168
|
+
├── models/ # Color, …
|
|
169
|
+
├── nodes/ # DynamicField, PageBreak, ImageRef, NotumHeading
|
|
170
|
+
├── types/ # shared TypeScript types
|
|
171
|
+
├── utils/ # color / dom / table / text helpers
|
|
172
|
+
└── views/ # ProseMirror node views
|
|
175
173
|
```
|
|
176
174
|
|
|
177
|
-
|
|
175
|
+
---
|
|
178
176
|
|
|
179
|
-
|
|
177
|
+
## 🔧 Development
|
|
180
178
|
|
|
181
179
|
```bash
|
|
182
|
-
nx
|
|
180
|
+
nx build @phuong-tran-redoc/document-engine-core # build the library
|
|
181
|
+
nx test @phuong-tran-redoc/document-engine-core # unit tests
|
|
182
|
+
nx lint @phuong-tran-redoc/document-engine-core # lint
|
|
183
183
|
```
|
|
184
184
|
|
|
185
185
|
---
|
|
186
186
|
|
|
187
187
|
## 🎨 Framework Wrappers
|
|
188
188
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
- **Angular:** [`@phuong-tran-redoc/document-engine-angular`](../document-engine-angular)
|
|
189
|
+
- **Angular:** [`@phuong-tran-redoc/document-engine-angular`](../document-engine-angular/README.md)
|
|
192
190
|
|
|
193
191
|
---
|
|
194
192
|
|
|
195
|
-
## 📖
|
|
196
|
-
|
|
197
|
-
- **[Live Demo](#)** - See the editor in action
|
|
198
|
-
- **[API Reference](#)** - Detailed API documentation
|
|
199
|
-
- **[Examples](#)** - Code examples and use cases
|
|
200
|
-
- **[Contributing](#)** - How to contribute
|
|
201
|
-
|
|
202
|
-
---
|
|
203
|
-
|
|
204
|
-
## 🔗 Related Resources
|
|
193
|
+
## 📖 Resources
|
|
205
194
|
|
|
195
|
+
- 📦 [npm package](https://www.npmjs.com/package/@phuong-tran-redoc/document-engine-core)
|
|
196
|
+
- 📝 [Changelog](../../CHANGELOG.md)
|
|
197
|
+
- 🐙 [Repository](https://github.com/phuong-tran-redoc/document-engine)
|
|
198
|
+
- ▶️ [Demo app](https://github.com/phuong-tran-redoc/document-engine) — clone the repo and run `pnpm start` (http://localhost:4200)
|
|
206
199
|
- [Tiptap Documentation](https://tiptap.dev)
|
|
207
200
|
- [ProseMirror Documentation](https://prosemirror.net)
|
|
208
|
-
- [Main Project Repository](#)
|
|
209
201
|
|
|
210
202
|
---
|
|
211
203
|
|
|
@@ -221,6 +213,4 @@ Developed by **Duc Phuong (Jack)**
|
|
|
221
213
|
|
|
222
214
|
## 📄 License
|
|
223
215
|
|
|
224
|
-
**MIT License**
|
|
225
|
-
|
|
226
|
-
See [LICENSE.md](./LICENSE.md) for full license text.
|
|
216
|
+
**MIT License** — see [LICENSE.md](./LICENSE.md).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
THIRD-PARTY SOFTWARE NOTICES
|
|
2
|
+
|
|
3
|
+
The Document Engine packages bundle or depend on the third-party software listed
|
|
4
|
+
below (the full production dependency closure). Each is distributed under its own
|
|
5
|
+
license; the full license text ships within each package in node_modules and is
|
|
6
|
+
available at the linked repository.
|
|
7
|
+
|
|
8
|
+
==============================================================================
|
|
9
|
+
|
|
10
|
+
@angular/cdk@20.2.12
|
|
11
|
+
license: MIT
|
|
12
|
+
repository: https://github.com/angular/components
|
|
13
|
+
|
|
14
|
+
@angular/common@20.3.10
|
|
15
|
+
license: MIT
|
|
16
|
+
repository: https://github.com/angular/angular
|
|
17
|
+
publisher: angular
|
|
18
|
+
|
|
19
|
+
@angular/compiler@20.3.10
|
|
20
|
+
license: MIT
|
|
21
|
+
repository: https://github.com/angular/angular
|
|
22
|
+
publisher: angular
|
|
23
|
+
|
|
24
|
+
@angular/core@20.3.10
|
|
25
|
+
license: MIT
|
|
26
|
+
repository: https://github.com/angular/angular
|
|
27
|
+
publisher: angular
|
|
28
|
+
|
|
29
|
+
@angular/forms@20.3.10
|
|
30
|
+
license: MIT
|
|
31
|
+
repository: https://github.com/angular/angular
|
|
32
|
+
publisher: angular
|
|
33
|
+
|
|
34
|
+
@angular/material@20.2.12
|
|
35
|
+
license: MIT
|
|
36
|
+
repository: https://github.com/angular/components
|
|
37
|
+
|
|
38
|
+
@angular/platform-browser-dynamic@20.3.10
|
|
39
|
+
license: MIT
|
|
40
|
+
repository: https://github.com/angular/angular
|
|
41
|
+
publisher: angular
|
|
42
|
+
|
|
43
|
+
@angular/platform-browser@20.3.10
|
|
44
|
+
license: MIT
|
|
45
|
+
repository: https://github.com/angular/angular
|
|
46
|
+
publisher: angular
|
|
47
|
+
|
|
48
|
+
@angular/router@20.3.10
|
|
49
|
+
license: MIT
|
|
50
|
+
repository: https://github.com/angular/angular
|
|
51
|
+
publisher: angular
|
|
52
|
+
|
|
53
|
+
lodash-es@4.17.21
|
|
54
|
+
license: MIT
|
|
55
|
+
repository: https://github.com/lodash/lodash
|
|
56
|
+
publisher: John-David Dalton
|
|
57
|
+
|
|
58
|
+
rxjs@7.8.2
|
|
59
|
+
license: Apache-2.0
|
|
60
|
+
repository: https://github.com/reactivex/rxjs
|
|
61
|
+
publisher: Ben Lesh
|
|
62
|
+
|
|
63
|
+
zone.js@0.15.1
|
|
64
|
+
license: MIT
|
|
65
|
+
repository: https://github.com/angular/angular
|
|
66
|
+
publisher: Brian Ford
|
|
67
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phuong-tran-redoc/document-engine-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Realestatedoc (Redoc)",
|
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
"description": "Framework-agnostic core library for Document Engine",
|
|
11
11
|
"main": "./src/index.js",
|
|
12
12
|
"types": "./src/index.d.ts",
|
|
13
|
+
"files": [
|
|
14
|
+
"src/**/*.js",
|
|
15
|
+
"src/**/*.d.ts",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE.md",
|
|
18
|
+
"THIRD-PARTY-NOTICES.txt"
|
|
19
|
+
],
|
|
13
20
|
"repository": {
|
|
14
21
|
"type": "git",
|
|
15
22
|
"url": "git+https://github.com/phuong-tran-redoc/document-engine.git"
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Editor } from '@tiptap/core';
|
|
2
|
-
import type { Extensions } from '@tiptap/core';
|
|
3
|
-
/**
|
|
4
|
-
* Create a test editor instance with minimal required extensions
|
|
5
|
-
* @param extensions Additional extensions to include
|
|
6
|
-
* @param content Initial content (HTML string or JSON)
|
|
7
|
-
* @returns Editor instance
|
|
8
|
-
*/
|
|
9
|
-
export declare function createTestEditor(extensions?: Extensions, content?: string | Record<string, unknown>): Editor;
|
|
10
|
-
/**
|
|
11
|
-
* Destroy editor and cleanup
|
|
12
|
-
*/
|
|
13
|
-
export declare function destroyEditor(editor: Editor): void;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Editor } from '@tiptap/core';
|
|
2
|
-
import { Document } from '@tiptap/extension-document';
|
|
3
|
-
import { Paragraph } from '@tiptap/extension-paragraph';
|
|
4
|
-
import { Text } from '@tiptap/extension-text';
|
|
5
|
-
/**
|
|
6
|
-
* Create a test editor instance with minimal required extensions
|
|
7
|
-
* @param extensions Additional extensions to include
|
|
8
|
-
* @param content Initial content (HTML string or JSON)
|
|
9
|
-
* @returns Editor instance
|
|
10
|
-
*/ export function createTestEditor(extensions = [], content = '') {
|
|
11
|
-
return new Editor({
|
|
12
|
-
extensions: [
|
|
13
|
-
Document,
|
|
14
|
-
Paragraph,
|
|
15
|
-
Text,
|
|
16
|
-
...extensions
|
|
17
|
-
],
|
|
18
|
-
content
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Destroy editor and cleanup
|
|
23
|
-
*/ export function destroyEditor(editor) {
|
|
24
|
-
editor.destroy();
|
|
25
|
-
}
|