@editneo/core 0.1.1 → 0.1.2

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 CHANGED
@@ -32,7 +32,6 @@ type BlockType =
32
32
  | "code-block"
33
33
  | "image"
34
34
  | "video"
35
- | "pdf-page"
36
35
  | "quote"
37
36
  | "divider"
38
37
  | "callout";
@@ -99,28 +98,22 @@ interface EditorState {
99
98
 
100
99
  ## Editor Store
101
100
 
102
- The store is a [Zustand](https://zustand-demo.pmnd.rs/) store. You can use it directly in React via the hook, or access it imperatively from anywhere.
101
+ The store uses [Zustand](https://zustand-demo.pmnd.rs/) and follows a **per-instance factory pattern**. Each editor creates its own isolated store via `createEditorStore()`, so multiple editors on the same page don't share state. The store is seeded with an initial empty paragraph block.
103
102
 
104
- ### Using the hook (inside React components)
103
+ ### Creating a store instance
105
104
 
106
105
  ```typescript
107
- import { useEditorStore } from "@editneo/core";
106
+ import { createEditorStore } from "@editneo/core";
108
107
 
109
- function MyComponent() {
110
- // Subscribe to specific slices to avoid unnecessary re-renders
111
- const blocks = useEditorStore((state) => state.blocks);
112
- const rootBlocks = useEditorStore((state) => state.rootBlocks);
113
- const selection = useEditorStore((state) => state.selection);
114
- }
108
+ const store = createEditorStore();
109
+ // Each call returns a new, independent store
115
110
  ```
116
111
 
117
- ### Imperative access (outside React, in tests, etc.)
112
+ ### Accessing state
118
113
 
119
114
  ```typescript
120
- import { useEditorStore } from "@editneo/core";
121
-
122
- const state = useEditorStore.getState();
123
- const { addBlock, updateBlock, deleteBlock, toggleMark, undo, redo } = state;
115
+ const state = store.getState();
116
+ const { blocks, rootBlocks, selection } = state;
124
117
  ```
125
118
 
126
119
  ### Actions
@@ -134,9 +127,25 @@ addBlock("paragraph"); // Appends a paragraph at the end
134
127
  addBlock("heading-1", "block-abc"); // Inserts a heading after block-abc
135
128
  ```
136
129
 
130
+ #### `insertFullBlock(block, afterId?)`
131
+
132
+ Inserts a complete `NeoBlock` object (e.g. one created by PDF extraction or imported data). Unlike `addBlock`, this accepts a fully formed block rather than just a type.
133
+
134
+ ```typescript
135
+ insertFullBlock(myBlock, "block-abc");
136
+ ```
137
+
138
+ #### `insertFullBlocks(blocks, afterId?)`
139
+
140
+ Batch-inserts multiple complete blocks at once.
141
+
142
+ ```typescript
143
+ insertFullBlocks(pdfBlocks, "block-abc");
144
+ ```
145
+
137
146
  #### `updateBlock(id, partial)`
138
147
 
139
- Merges partial data into an existing block. The `updatedAt` timestamp is set automatically. History is recorded.
148
+ Merges partial data into an existing block. The `updatedAt` timestamp is set automatically. History is debounced — rapid edits to the same block within 300ms are grouped into a single undo step.
140
149
 
141
150
  ```typescript
142
151
  updateBlock("block-abc", {
@@ -150,24 +159,61 @@ updateBlock("block-xyz", {
150
159
 
151
160
  #### `deleteBlock(id)`
152
161
 
153
- Removes a block from the document. If the block has children, those children are promoted to the root level in the same position. History is recorded.
162
+ Removes a block from the document. If the block has children, those children are promoted to the root level in the same position with their `parentId` cleared. History is recorded.
154
163
 
155
164
  ```typescript
156
165
  deleteBlock("block-abc");
157
166
  ```
158
167
 
168
+ #### `moveBlock(id, afterId)`
169
+
170
+ Moves a block to a new position. If `afterId` is `null`, the block is moved to the beginning.
171
+
172
+ ```typescript
173
+ moveBlock("block-abc", "block-xyz"); // Move abc after xyz
174
+ moveBlock("block-abc", null); // Move abc to the start
175
+ ```
176
+
177
+ #### `setBlockType(id, newType)`
178
+
179
+ Changes a block's type without altering its content.
180
+
181
+ ```typescript
182
+ setBlockType("block-abc", "heading-1");
183
+ ```
184
+
159
185
  #### `toggleMark(mark)`
160
186
 
161
- Toggles an inline formatting mark on the currently selected block's content. If all spans already have the mark, it is removed. Otherwise it is applied to all spans. Supported marks: `'bold'`, `'italic'`, `'underline'`, `'strike'`, `'code'`.
187
+ Toggles an inline formatting mark on the currently selected range. The mark is applied precisely within the selection's `startOffset`/`endOffset`, splitting spans as needed. Supported marks: `'bold'`, `'italic'`, `'underline'`, `'strike'`, `'code'`.
162
188
 
163
189
  ```typescript
164
190
  toggleMark("bold");
165
191
  toggleMark("italic");
166
192
  ```
167
193
 
194
+ #### `setLink(url)`
195
+
196
+ Sets (or removes) a hyperlink on the selected text range. Pass `null` to remove a link.
197
+
198
+ ```typescript
199
+ setLink("https://editneo.dev");
200
+ setLink(null); // Remove link
201
+ ```
202
+
203
+ #### `exportJSON()` / `importJSON(data)`
204
+
205
+ Serialize and restore the document.
206
+
207
+ ```typescript
208
+ const data = exportJSON();
209
+ // data: { blocks: Record<string, NeoBlock>, rootBlocks: string[] }
210
+
211
+ importJSON(data); // Replaces the current document
212
+ ```
213
+
168
214
  #### `undo()` / `redo()`
169
215
 
170
- Navigates through the history stack. `undo()` restores the previous state, `redo()` moves forward. Both are no-ops at the boundaries of histoy.
216
+ Navigates through the history stack. `undo()` restores the previous state, `redo()` moves forward. Both are no-ops at the boundaries of history.
171
217
 
172
218
  ```typescript
173
219
  undo();
@@ -176,7 +222,7 @@ redo();
176
222
 
177
223
  ## History Model
178
224
 
179
- Every mutating action (`addBlock`, `updateBlock`, `deleteBlock`, `toggleMark`) captures a snapshot of `blocks`, `rootBlocks`, and `selection` before applying the change, and appends it to the `history` array. When `undo()` is called, the editor reverts to the snapshot at `historyIndex`. On `redo()`, it moves forward.
225
+ Every mutating action captures a snapshot of `blocks`, `rootBlocks`, and `selection` before applying the change. `updateBlock` uses a 300ms debounce window — rapid edits to the same block within that window are grouped into a single undo step, preventing every keystroke from creating a snapshot.
180
226
 
181
227
  If a new action is performed after undoing, the forward history is discarded (standard undo stack behavior).
182
228
 
package/dist/store.d.ts CHANGED
@@ -1,13 +1,40 @@
1
1
  import { NeoBlock, EditorState, BlockType, Span } from './types';
2
- interface EditorActions {
2
+ export interface EditorActions {
3
3
  addBlock: (type: BlockType, afterId?: string | null) => void;
4
+ insertFullBlock: (block: NeoBlock, afterId?: string | null) => void;
5
+ insertFullBlocks: (blocks: NeoBlock[], afterId?: string | null) => void;
4
6
  updateBlock: (id: string, partial: Partial<NeoBlock>) => void;
5
7
  deleteBlock: (id: string) => void;
8
+ moveBlock: (id: string, afterId: string | null) => void;
9
+ setBlockType: (id: string, newType: BlockType) => void;
6
10
  toggleMark: (mark: keyof Pick<Span, 'bold' | 'italic' | 'underline' | 'strike' | 'code'>) => void;
11
+ setLink: (url: string | null) => void;
7
12
  undo: () => void;
8
13
  redo: () => void;
14
+ exportJSON: () => {
15
+ blocks: Record<string, NeoBlock>;
16
+ rootBlocks: string[];
17
+ };
18
+ importJSON: (data: {
19
+ blocks: Record<string, NeoBlock>;
20
+ rootBlocks: string[];
21
+ }) => void;
9
22
  }
10
- type EditorStore = EditorState & EditorActions;
11
- export declare const useEditorStore: import("zustand").UseBoundStore<import("zustand").StoreApi<EditorStore>>;
12
- export {};
23
+ export type EditorStore = EditorState & EditorActions;
24
+ /**
25
+ * Creates a new, isolated editor store instance.
26
+ * Each NeoEditor should have its own store so multiple editors
27
+ * on the same page don't share state.
28
+ *
29
+ * The store is seeded with one empty paragraph so the editor
30
+ * is never completely blank.
31
+ */
32
+ export declare function createEditorStore(): import("zustand/vanilla").StoreApi<EditorStore>;
33
+ /** The type returned by createEditorStore() */
34
+ export type EditorStoreInstance = ReturnType<typeof createEditorStore>;
35
+ /**
36
+ * @deprecated Use createEditorStore() + context pattern instead.
37
+ * Kept for backward compatibility — this is a global singleton.
38
+ */
39
+ export declare const useEditorStore: import("zustand/vanilla").StoreApi<EditorStore>;
13
40
  //# sourceMappingURL=store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEjE,UAAU,aAAa;IACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7D,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAC9D,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IAClG,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,KAAK,WAAW,GAAG,WAAW,GAAG,aAAa,CAAC;AAE/C,eAAO,MAAM,cAAc,0EA+JxB,CAAC"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AA2FjE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7D,eAAe,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACpE,gBAAgB,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACxE,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAC9D,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACxD,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC;IACvD,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IAClG,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACtC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,UAAU,EAAE,MAAM;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC7E,UAAU,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;CACxF;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,aAAa,CAAC;AAItD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,oDAiThC;AAED,+CAA+C;AAC/C,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEvE;;;GAGG;AACH,eAAO,MAAM,cAAc,iDAAsB,CAAC"}
package/dist/store.js CHANGED
@@ -1,145 +1,356 @@
1
- import { create } from 'zustand';
1
+ import { createStore } from 'zustand/vanilla';
2
2
  import { v4 as uuid } from 'uuid';
3
- export const useEditorStore = create((set) => ({
4
- blocks: {},
5
- rootBlocks: [],
6
- selection: {
7
- blockId: null,
8
- startOffset: 0,
9
- endOffset: 0,
10
- },
11
- history: [],
12
- historyIndex: -1,
13
- undo: () => set((state) => {
14
- if (state.historyIndex < 0)
15
- return state;
16
- const prev = state.history[state.historyIndex];
17
- return {
18
- ...prev,
19
- historyIndex: state.historyIndex - 1,
20
- history: state.history, // Preserve history
21
- };
22
- }),
23
- redo: () => set((state) => {
24
- if (state.historyIndex >= state.history.length - 1)
25
- return state;
26
- const next = state.history[state.historyIndex + 1];
27
- return {
28
- ...next,
29
- historyIndex: state.historyIndex + 1,
30
- history: state.history, // Preserve history
31
- };
32
- }),
33
- // Helper to push state to history
34
- // Note: specific actions should call this before mutating
35
- // For simplicity in this MVP, we might wrap setters or just manually push in actions
36
- addBlock: (type, afterId = null) => set((state) => {
37
- // Push current state to history before change
38
- const historyEntry = {
39
- blocks: state.blocks,
40
- rootBlocks: state.rootBlocks,
41
- selection: state.selection
42
- };
43
- const newHistory = [...state.history.slice(0, state.historyIndex + 1), historyEntry];
44
- const newId = uuid();
45
- const newBlock = {
46
- id: newId,
47
- type,
48
- content: [],
49
- props: {},
50
- children: [],
51
- parentId: null,
52
- createdAt: Date.now(),
53
- updatedAt: Date.now(),
54
- };
55
- const newRootBlocks = [...state.rootBlocks];
56
- if (afterId && state.rootBlocks.includes(afterId)) {
57
- const index = newRootBlocks.indexOf(afterId);
58
- newRootBlocks.splice(index + 1, 0, newId);
3
+ // ── Helpers ──────────────────────────────────────────────────────────
4
+ /** Create a blank block with sensible defaults. */
5
+ function makeBlock(type, content = [], props = {}) {
6
+ return {
7
+ id: uuid(),
8
+ type,
9
+ content,
10
+ props,
11
+ children: [],
12
+ parentId: null,
13
+ createdAt: Date.now(),
14
+ updatedAt: Date.now(),
15
+ };
16
+ }
17
+ /** Capture a snapshot of the mutable state fields for undo history. */
18
+ function snapshot(state) {
19
+ return {
20
+ blocks: state.blocks,
21
+ rootBlocks: state.rootBlocks,
22
+ selection: state.selection,
23
+ };
24
+ }
25
+ /**
26
+ * Slice spans by character offsets and toggle a mark on the selected range.
27
+ * Returns the new content array with the mark toggled only within [start, end).
28
+ */
29
+ function toggleMarkInRange(spans, start, end, mark) {
30
+ if (spans.length === 0 || start >= end)
31
+ return spans;
32
+ const ranges = [];
33
+ let offset = 0;
34
+ for (const span of spans) {
35
+ ranges.push({ span, from: offset, to: offset + span.text.length });
36
+ offset += span.text.length;
37
+ }
38
+ // Clamp selection to content length
39
+ const selStart = Math.max(0, start);
40
+ const selEnd = Math.min(offset, end);
41
+ // If selection covers the entire block, fall back to the old toggle-all behavior
42
+ if (selStart === 0 && selEnd === offset) {
43
+ const allMarked = spans.length > 0 && spans.every((s) => s[mark]);
44
+ return spans.map((s) => ({ ...s, [mark]: !allMarked }));
45
+ }
46
+ // Check if every span within the selection range already has the mark
47
+ const selectedSpans = ranges.filter((r) => r.to > selStart && r.from < selEnd);
48
+ const allMarked = selectedSpans.every((r) => r.span[mark]);
49
+ const newValue = !allMarked;
50
+ // Split and rebuild
51
+ const result = [];
52
+ for (const { span, from, to } of ranges) {
53
+ if (to <= selStart || from >= selEnd) {
54
+ // Entirely outside selection — keep as-is
55
+ result.push(span);
59
56
  }
60
- else {
61
- newRootBlocks.push(newId);
57
+ else if (from >= selStart && to <= selEnd) {
58
+ // Entirely inside selection — toggle
59
+ result.push({ ...span, [mark]: newValue });
62
60
  }
63
- return {
64
- blocks: { ...state.blocks, [newId]: newBlock },
65
- rootBlocks: newRootBlocks,
66
- history: newHistory,
67
- historyIndex: newHistory.length - 1,
68
- selection: { blockId: newId, startOffset: 0, endOffset: 0 }
69
- };
70
- }),
71
- updateBlock: (id, partial) => set((state) => {
72
- const block = state.blocks[id];
73
- if (!block)
74
- return state;
75
- // naive history push for every update (might need debouncing for text)
76
- const historyEntry = {
77
- blocks: state.blocks,
78
- rootBlocks: state.rootBlocks,
79
- selection: state.selection
80
- };
81
- const newHistory = [...state.history.slice(0, state.historyIndex + 1), historyEntry];
82
- return {
83
- blocks: {
84
- ...state.blocks,
85
- [id]: { ...block, ...partial, updatedAt: Date.now() },
86
- },
87
- history: newHistory,
88
- historyIndex: newHistory.length - 1
89
- };
90
- }),
91
- deleteBlock: (id) => set((state) => {
92
- const block = state.blocks[id];
93
- if (!block)
94
- return state;
95
- const historyEntry = {
96
- blocks: state.blocks,
97
- rootBlocks: state.rootBlocks,
98
- selection: state.selection
99
- };
100
- const newHistory = [...state.history.slice(0, state.historyIndex + 1), historyEntry];
101
- const { [id]: deleted, ...remainingBlocks } = state.blocks;
102
- const newRootBlocks = state.rootBlocks.filter((blockId) => blockId !== id);
103
- if (block.children.length > 0) {
104
- const index = state.rootBlocks.indexOf(id);
105
- if (index !== -1) {
106
- newRootBlocks.splice(index, 0, ...block.children);
61
+ else {
62
+ // Partially overlaps split the span
63
+ if (from < selStart) {
64
+ result.push({ ...span, text: span.text.slice(0, selStart - from) });
65
+ }
66
+ const overlapStart = Math.max(from, selStart);
67
+ const overlapEnd = Math.min(to, selEnd);
68
+ result.push({ ...span, text: span.text.slice(overlapStart - from, overlapEnd - from), [mark]: newValue });
69
+ if (to > selEnd) {
70
+ result.push({ ...span, text: span.text.slice(selEnd - from) });
107
71
  }
108
72
  }
109
- return {
110
- blocks: remainingBlocks,
111
- rootBlocks: newRootBlocks,
112
- history: newHistory,
113
- historyIndex: newHistory.length - 1
114
- };
115
- }),
116
- toggleMark: (mark) => set((state) => {
117
- const blockId = state.selection.blockId;
118
- if (!blockId)
119
- return state;
120
- const block = state.blocks[blockId];
121
- if (!block)
122
- return state;
123
- // Determine if the mark is currently active on all spans in the selection range
124
- const allMarked = block.content.length > 0 && block.content.every((span) => span[mark]);
125
- const newContent = block.content.map((span) => ({
126
- ...span,
127
- [mark]: !allMarked,
128
- }));
129
- const historyEntry = {
130
- blocks: state.blocks,
131
- rootBlocks: state.rootBlocks,
132
- selection: state.selection,
133
- };
134
- const newHistory = [...state.history.slice(0, state.historyIndex + 1), historyEntry];
135
- return {
136
- blocks: {
137
- ...state.blocks,
138
- [blockId]: { ...block, content: newContent, updatedAt: Date.now() },
139
- },
140
- history: newHistory,
141
- historyIndex: newHistory.length - 1,
142
- };
143
- }),
144
- }));
73
+ }
74
+ return result;
75
+ }
76
+ // ── Store factory ────────────────────────────────────────────────────
77
+ /**
78
+ * Creates a new, isolated editor store instance.
79
+ * Each NeoEditor should have its own store so multiple editors
80
+ * on the same page don't share state.
81
+ *
82
+ * The store is seeded with one empty paragraph so the editor
83
+ * is never completely blank.
84
+ */
85
+ export function createEditorStore() {
86
+ // Seed with one empty paragraph (#1)
87
+ const initialBlock = makeBlock('paragraph');
88
+ return createStore((set, get) => ({
89
+ blocks: { [initialBlock.id]: initialBlock },
90
+ rootBlocks: [initialBlock.id],
91
+ selection: {
92
+ blockId: initialBlock.id,
93
+ startOffset: 0,
94
+ endOffset: 0,
95
+ },
96
+ history: [],
97
+ historyIndex: -1,
98
+ // ── History navigation ─────────────────────────────────────────
99
+ undo: () => set((state) => {
100
+ if (state.historyIndex < 0)
101
+ return state;
102
+ const prev = state.history[state.historyIndex];
103
+ return {
104
+ ...prev,
105
+ historyIndex: state.historyIndex - 1,
106
+ history: state.history,
107
+ };
108
+ }),
109
+ redo: () => set((state) => {
110
+ if (state.historyIndex >= state.history.length - 1)
111
+ return state;
112
+ const next = state.history[state.historyIndex + 1];
113
+ return {
114
+ ...next,
115
+ historyIndex: state.historyIndex + 1,
116
+ history: state.history,
117
+ };
118
+ }),
119
+ // ── Block CRUD ─────────────────────────────────────────────────
120
+ addBlock: (type, afterId = null) => set((state) => {
121
+ const newHistory = [...state.history.slice(0, state.historyIndex + 1), snapshot(state)];
122
+ const newBlock = makeBlock(type);
123
+ const newRootBlocks = [...state.rootBlocks];
124
+ if (afterId && state.rootBlocks.includes(afterId)) {
125
+ const index = newRootBlocks.indexOf(afterId);
126
+ newRootBlocks.splice(index + 1, 0, newBlock.id);
127
+ }
128
+ else {
129
+ newRootBlocks.push(newBlock.id);
130
+ }
131
+ return {
132
+ blocks: { ...state.blocks, [newBlock.id]: newBlock },
133
+ rootBlocks: newRootBlocks,
134
+ history: newHistory,
135
+ historyIndex: newHistory.length - 1,
136
+ selection: { blockId: newBlock.id, startOffset: 0, endOffset: 0 },
137
+ };
138
+ }),
139
+ /** Insert a complete NeoBlock object (e.g. from PDF extraction). (#2) */
140
+ insertFullBlock: (block, afterId = null) => set((state) => {
141
+ const newHistory = [...state.history.slice(0, state.historyIndex + 1), snapshot(state)];
142
+ const newRootBlocks = [...state.rootBlocks];
143
+ if (afterId && state.rootBlocks.includes(afterId)) {
144
+ const index = newRootBlocks.indexOf(afterId);
145
+ newRootBlocks.splice(index + 1, 0, block.id);
146
+ }
147
+ else {
148
+ newRootBlocks.push(block.id);
149
+ }
150
+ return {
151
+ blocks: { ...state.blocks, [block.id]: block },
152
+ rootBlocks: newRootBlocks,
153
+ history: newHistory,
154
+ historyIndex: newHistory.length - 1,
155
+ selection: { blockId: block.id, startOffset: 0, endOffset: 0 },
156
+ };
157
+ }),
158
+ /** Insert multiple complete blocks at once (batch insert). */
159
+ insertFullBlocks: (blocks, afterId = null) => set((state) => {
160
+ const newHistory = [...state.history.slice(0, state.historyIndex + 1), snapshot(state)];
161
+ const newBlocks = { ...state.blocks };
162
+ const newRootBlocks = [...state.rootBlocks];
163
+ const insertIndex = afterId && state.rootBlocks.includes(afterId)
164
+ ? newRootBlocks.indexOf(afterId) + 1
165
+ : newRootBlocks.length;
166
+ const ids = [];
167
+ for (const block of blocks) {
168
+ newBlocks[block.id] = block;
169
+ ids.push(block.id);
170
+ }
171
+ newRootBlocks.splice(insertIndex, 0, ...ids);
172
+ const lastId = ids[ids.length - 1] || null;
173
+ return {
174
+ blocks: newBlocks,
175
+ rootBlocks: newRootBlocks,
176
+ history: newHistory,
177
+ historyIndex: newHistory.length - 1,
178
+ selection: { blockId: lastId, startOffset: 0, endOffset: 0 },
179
+ };
180
+ }),
181
+ updateBlock: (id, partial) => {
182
+ const now = Date.now();
183
+ const DEBOUNCE_MS = 300;
184
+ set((state) => {
185
+ const block = state.blocks[id];
186
+ if (!block)
187
+ return state;
188
+ // (#5) Debounce: only push history if >300ms since last update to this block,
189
+ // or if a different block is being updated
190
+ const timeSinceLastUpdate = now - (block.updatedAt || 0);
191
+ const shouldPushHistory = timeSinceLastUpdate > DEBOUNCE_MS;
192
+ let newHistory = state.history;
193
+ let newHistoryIndex = state.historyIndex;
194
+ if (shouldPushHistory) {
195
+ newHistory = [...state.history.slice(0, state.historyIndex + 1), snapshot(state)];
196
+ newHistoryIndex = newHistory.length - 1;
197
+ }
198
+ return {
199
+ blocks: {
200
+ ...state.blocks,
201
+ [id]: { ...block, ...partial, updatedAt: now },
202
+ },
203
+ history: newHistory,
204
+ historyIndex: newHistoryIndex,
205
+ };
206
+ });
207
+ },
208
+ /** Delete a block. Children are promoted to root with parentId cleared. (#4) */
209
+ deleteBlock: (id) => set((state) => {
210
+ const block = state.blocks[id];
211
+ if (!block)
212
+ return state;
213
+ const newHistory = [...state.history.slice(0, state.historyIndex + 1), snapshot(state)];
214
+ const { [id]: _deleted, ...remainingBlocks } = state.blocks;
215
+ const newRootBlocks = state.rootBlocks.filter((blockId) => blockId !== id);
216
+ // Promote children to root and clear their parentId
217
+ if (block.children.length > 0) {
218
+ const index = state.rootBlocks.indexOf(id);
219
+ if (index !== -1) {
220
+ newRootBlocks.splice(index, 0, ...block.children);
221
+ }
222
+ for (const childId of block.children) {
223
+ if (remainingBlocks[childId]) {
224
+ remainingBlocks[childId] = { ...remainingBlocks[childId], parentId: null };
225
+ }
226
+ }
227
+ }
228
+ return {
229
+ blocks: remainingBlocks,
230
+ rootBlocks: newRootBlocks,
231
+ history: newHistory,
232
+ historyIndex: newHistory.length - 1,
233
+ };
234
+ }),
235
+ /** Move a block to a new position (after afterId, or to the start if null). (#6) */
236
+ moveBlock: (id, afterId) => set((state) => {
237
+ if (!state.blocks[id])
238
+ return state;
239
+ const newHistory = [...state.history.slice(0, state.historyIndex + 1), snapshot(state)];
240
+ const newRootBlocks = state.rootBlocks.filter((bid) => bid !== id);
241
+ if (afterId && newRootBlocks.includes(afterId)) {
242
+ const idx = newRootBlocks.indexOf(afterId);
243
+ newRootBlocks.splice(idx + 1, 0, id);
244
+ }
245
+ else {
246
+ newRootBlocks.unshift(id);
247
+ }
248
+ return {
249
+ rootBlocks: newRootBlocks,
250
+ history: newHistory,
251
+ historyIndex: newHistory.length - 1,
252
+ };
253
+ }),
254
+ /** Change a block's type without losing content. (#6) */
255
+ setBlockType: (id, newType) => set((state) => {
256
+ const block = state.blocks[id];
257
+ if (!block)
258
+ return state;
259
+ const newHistory = [...state.history.slice(0, state.historyIndex + 1), snapshot(state)];
260
+ return {
261
+ blocks: {
262
+ ...state.blocks,
263
+ [id]: { ...block, type: newType, updatedAt: Date.now() },
264
+ },
265
+ history: newHistory,
266
+ historyIndex: newHistory.length - 1,
267
+ };
268
+ }),
269
+ // ── Inline formatting ──────────────────────────────────────────
270
+ /** Toggle a mark on the selected range only (#3). */
271
+ toggleMark: (mark) => set((state) => {
272
+ const blockId = state.selection.blockId;
273
+ if (!blockId)
274
+ return state;
275
+ const block = state.blocks[blockId];
276
+ if (!block)
277
+ return state;
278
+ const { startOffset, endOffset } = state.selection;
279
+ const newContent = toggleMarkInRange(block.content, startOffset, endOffset, mark);
280
+ const newHistory = [...state.history.slice(0, state.historyIndex + 1), snapshot(state)];
281
+ return {
282
+ blocks: {
283
+ ...state.blocks,
284
+ [blockId]: { ...block, content: newContent, updatedAt: Date.now() },
285
+ },
286
+ history: newHistory,
287
+ historyIndex: newHistory.length - 1,
288
+ };
289
+ }),
290
+ /** Set or clear a link on the selected range. (#19 support) */
291
+ setLink: (url) => set((state) => {
292
+ const blockId = state.selection.blockId;
293
+ if (!blockId)
294
+ return state;
295
+ const block = state.blocks[blockId];
296
+ if (!block || block.content.length === 0)
297
+ return state;
298
+ const { startOffset, endOffset } = state.selection;
299
+ const newHistory = [...state.history.slice(0, state.historyIndex + 1), snapshot(state)];
300
+ // Apply link to spans in the selection range
301
+ const result = [];
302
+ let offset = 0;
303
+ for (const span of block.content) {
304
+ const from = offset;
305
+ const to = offset + span.text.length;
306
+ offset = to;
307
+ if (to <= startOffset || from >= endOffset) {
308
+ result.push(span);
309
+ }
310
+ else if (from >= startOffset && to <= endOffset) {
311
+ result.push({ ...span, link: url || undefined });
312
+ }
313
+ else {
314
+ if (from < startOffset) {
315
+ result.push({ ...span, text: span.text.slice(0, startOffset - from) });
316
+ }
317
+ const overlapStart = Math.max(from, startOffset);
318
+ const overlapEnd = Math.min(to, endOffset);
319
+ result.push({ ...span, text: span.text.slice(overlapStart - from, overlapEnd - from), link: url || undefined });
320
+ if (to > endOffset) {
321
+ result.push({ ...span, text: span.text.slice(endOffset - from) });
322
+ }
323
+ }
324
+ }
325
+ return {
326
+ blocks: {
327
+ ...state.blocks,
328
+ [blockId]: { ...block, content: result, updatedAt: Date.now() },
329
+ },
330
+ history: newHistory,
331
+ historyIndex: newHistory.length - 1,
332
+ };
333
+ }),
334
+ // ── Serialization (#45) ────────────────────────────────────────
335
+ exportJSON: () => {
336
+ const state = get();
337
+ return { blocks: state.blocks, rootBlocks: state.rootBlocks };
338
+ },
339
+ importJSON: (data) => set((state) => {
340
+ const newHistory = [...state.history.slice(0, state.historyIndex + 1), snapshot(state)];
341
+ return {
342
+ blocks: data.blocks,
343
+ rootBlocks: data.rootBlocks,
344
+ history: newHistory,
345
+ historyIndex: newHistory.length - 1,
346
+ selection: { blockId: data.rootBlocks[0] || null, startOffset: 0, endOffset: 0 },
347
+ };
348
+ }),
349
+ }));
350
+ }
351
+ /**
352
+ * @deprecated Use createEditorStore() + context pattern instead.
353
+ * Kept for backward compatibility — this is a global singleton.
354
+ */
355
+ export const useEditorStore = createEditorStore();
145
356
  //# sourceMappingURL=store.js.map
package/dist/store.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type BlockType = 'paragraph' | 'heading-1' | 'heading-2' | 'heading-3' | 'bullet-list' | 'ordered-list' | 'todo-list' | 'code-block' | 'image' | 'video' | 'pdf-page' | 'quote' | 'divider' | 'callout';
1
+ export type BlockType = 'paragraph' | 'heading-1' | 'heading-2' | 'heading-3' | 'bullet-list' | 'ordered-list' | 'todo-list' | 'code-block' | 'image' | 'video' | 'quote' | 'divider' | 'callout';
2
2
  export interface Span {
3
3
  text: string;
4
4
  bold?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,WAAW,GAAG,WAAW,GAAG,WAAW,GACvC,aAAa,GAAG,cAAc,GAAG,WAAW,GAC5C,YAAY,GACZ,OAAO,GAAG,OAAO,GAAG,UAAU,GAC9B,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;AAEpC,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,IAAI,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE;QACT,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,WAAW,GAAG,WAAW,GAAG,WAAW,GACvC,aAAa,GAAG,cAAc,GAAG,WAAW,GAC5C,YAAY,GACZ,OAAO,GAAG,OAAO,GACjB,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;AAEpC,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,IAAI,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE;QACT,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH"}
package/package.json CHANGED
@@ -1,9 +1,17 @@
1
1
  {
2
2
  "name": "@editneo/core",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Core engine for EditNeo — block-based editor with CRDT sync",
5
+ "type": "module",
5
6
  "main": "./dist/index.js",
6
7
  "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
7
15
  "files": ["dist"],
8
16
  "scripts": {
9
17
  "build": "tsc",
@@ -14,8 +22,7 @@
14
22
  },
15
23
  "dependencies": {
16
24
  "zustand": "^4.5.1",
17
- "uuid": "^9.0.1",
18
- "immer": "^10.0.3"
25
+ "uuid": "^9.0.1"
19
26
  },
20
27
  "devDependencies": {
21
28
  "typescript": "^5.3.3",