@reiwuzen/blocky 1.0.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.
@@ -0,0 +1,195 @@
1
+ import { Result } from '@reiwuzen/result';
2
+ // ─── Trigger map ───────────────────────────────────────────────────────────────
3
+ const TRIGGERS = {
4
+ "-": "bullet",
5
+ "1.": "number",
6
+ "[]": "todo",
7
+ "#": "heading1",
8
+ "##": "heading2",
9
+ "###": "heading3",
10
+ };
11
+ // ─── Helpers ───────────────────────────────────────────────────────────────────
12
+ function getRawText(block) {
13
+ const first = block.content[0];
14
+ if (!first || first.type !== "text")
15
+ return "";
16
+ return first.text;
17
+ }
18
+ function stripPrefix(block, prefix) {
19
+ const first = block.content[0];
20
+ if (!first || first.type !== "text")
21
+ return block.content;
22
+ const stripped = first.text.slice(prefix.length + 1); // +1 for the space
23
+ if (stripped.length === 0)
24
+ return [];
25
+ return [{ ...first, text: stripped }, ...block.content.slice(1)];
26
+ }
27
+ function buildMeta(type) {
28
+ switch (type) {
29
+ case "bullet":
30
+ case "number":
31
+ case "todo": return { depth: 0 };
32
+ case "heading1":
33
+ case "heading2":
34
+ case "heading3": return {};
35
+ }
36
+ }
37
+ // ─── Core ──────────────────────────────────────────────────────────────────────
38
+ /**
39
+ * Call this when a space is typed.
40
+ *
41
+ * Guards (returns converted=false if any fail):
42
+ * 1. block.type must be "paragraph"
43
+ * 2. cursorOffset must be ≤ trigger.length + 1
44
+ * — ensures the space was typed right after the trigger at position 0
45
+ * — blocks mid-text spaces like "hello - " from converting
46
+ * 3. text must start with a known trigger prefix
47
+ */
48
+ export function applyMarkdownTransform(block, cursorOffset) {
49
+ // Guard 1 — only paragraph blocks
50
+ if (block.type !== "paragraph")
51
+ return Result.Ok({ block, converted: false });
52
+ const text = getRawText(block);
53
+ // Guard 2 — find trigger first, then validate cursor is right after it
54
+ // Sort longest first so ### beats ## beats #
55
+ const match = Object.keys(TRIGGERS)
56
+ .sort((a, b) => b.length - a.length)
57
+ .find((trigger) => text === trigger || text.startsWith(trigger + " "));
58
+ if (!match)
59
+ return Result.Ok({ block, converted: false });
60
+ // Guard 3 — cursor must be positioned right after "trigger + space"
61
+ // e.g. "## My Title" → match="##", valid cursor range is 0..3
62
+ // "hello ## Title" would never match since trigger must be at start
63
+ const triggerEnd = match.length + 1; // +1 for the space
64
+ if (cursorOffset < triggerEnd)
65
+ return Result.Ok({ block, converted: false });
66
+ const targetType = TRIGGERS[match];
67
+ const strippedContent = stripPrefix(block, match);
68
+ const converted = {
69
+ id: block.id,
70
+ type: targetType,
71
+ content: strippedContent,
72
+ meta: buildMeta(targetType),
73
+ };
74
+ return Result.Ok({ block: converted, converted: true });
75
+ }
76
+ // ─── changeBlockType ───────────────────────────────────────────────────────────
77
+ /**
78
+ * Convert a block to a new type while preserving content as much as possible.
79
+ *
80
+ * rich → rich keep content as-is, update type + meta
81
+ * rich → code strip all formatting, concat all text → [CodeNode]
82
+ * rich → equation strip all formatting, concat all text → [EquationNode]
83
+ * code → rich single TextNode with code.text
84
+ * equation → rich single TextNode with equation.latex
85
+ * code → equation [EquationNode] with code.text as latex
86
+ * equation → code [CodeNode] with equation.latex as text
87
+ */
88
+ export function changeBlockType(block, targetType) {
89
+ if (block.type === targetType)
90
+ return Result.Ok(block);
91
+ const content = deriveContent(block, targetType);
92
+ const meta = buildMetaForTarget(targetType);
93
+ return Result.Ok({
94
+ id: block.id,
95
+ type: targetType,
96
+ content,
97
+ meta,
98
+ });
99
+ }
100
+ /** Concat all readable text out of any block's content */
101
+ function extractText(block) {
102
+ if (block.type === "code")
103
+ return block.content[0].text;
104
+ if (block.type === "equation")
105
+ return block.content[0].latex;
106
+ // rich block — concat text from all nodes, ignore inline code/eq
107
+ return block.content
108
+ .map((n) => {
109
+ if (n.type === "text")
110
+ return n.text;
111
+ if (n.type === "code")
112
+ return n.text;
113
+ if (n.type === "equation")
114
+ return n.latex;
115
+ return "";
116
+ })
117
+ .join("");
118
+ }
119
+ function deriveContent(block, targetType) {
120
+ const text = extractText(block);
121
+ // → code
122
+ if (targetType === "code")
123
+ return [{ type: "code", text }];
124
+ // → equation
125
+ if (targetType === "equation")
126
+ return [{ type: "equation", latex: text }];
127
+ // → rich block
128
+ if (block.type === "code" || block.type === "equation") {
129
+ // single clean TextNode, no formatters
130
+ return text.length ? [{ type: "text", text }] : [];
131
+ }
132
+ // rich → rich — keep content as-is
133
+ return block.content;
134
+ }
135
+ function buildMetaForTarget(targetType) {
136
+ switch (targetType) {
137
+ case "bullet":
138
+ case "number":
139
+ case "todo": return { depth: 0 };
140
+ case "heading1":
141
+ case "heading2":
142
+ case "heading3":
143
+ case "paragraph":
144
+ case "code":
145
+ case "equation": return {};
146
+ }
147
+ }
148
+ // ─── toggleTodo ────────────────────────────────────────────────────────────────
149
+ /**
150
+ * Toggle the checked state of a todo block.
151
+ * checked: undefined → checked: true → checked: undefined (cycle)
152
+ */
153
+ export function toggleTodo(block) {
154
+ if (block.type !== "todo")
155
+ return Result.Err(`toggleTodo expects a "todo" block, got "${block.type}"`);
156
+ const todo = block;
157
+ const checked = todo.meta.checked ? undefined : true;
158
+ const meta = checked
159
+ ? { ...todo.meta, checked }
160
+ : (({ checked: _, ...rest }) => rest)(todo.meta);
161
+ return Result.Ok({ ...todo, meta });
162
+ }
163
+ const MAX_DEPTH = 6;
164
+ function isIndentable(block) {
165
+ return block.type === "bullet" || block.type === "number" || block.type === "todo";
166
+ }
167
+ /**
168
+ * Increase the depth of a bullet, number, or todo block by 1.
169
+ * Max depth is 6. Returns Err if block type is not indentable.
170
+ */
171
+ export function indentBlock(block) {
172
+ if (!isIndentable(block))
173
+ return Result.Err(`indentBlock only supports bullet, number, todo — got "${block.type}"`);
174
+ if (block.meta.depth >= MAX_DEPTH)
175
+ return Result.Err(`already at max depth (${MAX_DEPTH})`);
176
+ return Result.Ok({
177
+ ...block,
178
+ meta: { ...block.meta, depth: block.meta.depth + 1 },
179
+ });
180
+ }
181
+ /**
182
+ * Decrease the depth of a bullet, number, or todo block by 1.
183
+ * Min depth is 0. Returns Err if block type is not indentable or already at 0.
184
+ */
185
+ export function outdentBlock(block) {
186
+ if (!isIndentable(block))
187
+ return Result.Err(`outdentBlock only supports bullet, number, todo — got "${block.type}"`);
188
+ if (block.meta.depth <= 0)
189
+ return Result.Err(`already at min depth (0)`);
190
+ return Result.Ok({
191
+ ...block,
192
+ meta: { ...block.meta, depth: block.meta.depth - 1 },
193
+ });
194
+ }
195
+ //# sourceMappingURL=transform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.js","sourceRoot":"","sources":["../../src/engine/transform.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export { insertAt, deleteLastChar, deleteRange, replaceRange, splitBlock, mergeBlocks } from "./engine/content";
2
+ export { formatNodes, toggleBold, toggleItalic, toggleUnderline, toggleStrikethrough, toggleHighlight, toggleColor, setLink, removeLink, mergeAdjacentNodes } from "./engine/format";
3
+ export { applyMarkdownTransform, changeBlockType, toggleTodo, indentBlock, outdentBlock } from "./engine/transform";
4
+ export { serialize, deserialize, serializeNodes, deserializeNodes, toPlainText, toMarkdown } from "./engine/serializer";
5
+ export { createHistory, push, undo, redo, canUndo, canRedo, currentBlocks } from "./engine/history";
6
+ export type { History, HistoryEntry } from "./engine/history";
7
+ export { generateId, createBlock, insertBlockAfter, deleteBlock, duplicateBlock, moveBlock } from "./utils/block";
8
+ export type { Node, Block, BlockContent, BlockMeta, BlockType, AnyBlock } from "./types/block";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGhH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,eAAe,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGrL,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGpH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGxH,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACpG,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAG9D,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAGlH,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ // ─── Content ───────────────────────────────────────────────────────────────────
2
+ export { insertAt, deleteLastChar, deleteRange, replaceRange, splitBlock, mergeBlocks } from "./engine/content";
3
+ // ─── Format ────────────────────────────────────────────────────────────────────
4
+ export { formatNodes, toggleBold, toggleItalic, toggleUnderline, toggleStrikethrough, toggleHighlight, toggleColor, setLink, removeLink, mergeAdjacentNodes } from "./engine/format";
5
+ // ─── Transform ─────────────────────────────────────────────────────────────────
6
+ export { applyMarkdownTransform, changeBlockType, toggleTodo, indentBlock, outdentBlock } from "./engine/transform";
7
+ // ─── Serializer ────────────────────────────────────────────────────────────────
8
+ export { serialize, deserialize, serializeNodes, deserializeNodes, toPlainText, toMarkdown } from "./engine/serializer";
9
+ // ─── History ───────────────────────────────────────────────────────────────────
10
+ export { createHistory, push, undo, redo, canUndo, canRedo, currentBlocks } from "./engine/history";
11
+ // ─── Utils ─────────────────────────────────────────────────────────────────────
12
+ export { generateId, createBlock, insertBlockAfter, deleteBlock, duplicateBlock, moveBlock } from "./utils/block";
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEhH,kFAAkF;AAClF,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,eAAe,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErL,kFAAkF;AAClF,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEpH,kFAAkF;AAClF,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAExH,kFAAkF;AAClF,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGpG,kFAAkF;AAClF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,44 @@
1
+ export type BlockType = "paragraph" | "heading1" | "heading2" | "heading3" | "bullet" | "number" | "todo" | "equation" | "code";
2
+ export type Node = {
3
+ type: "text";
4
+ text: string;
5
+ highlighted?: "yellow" | "green";
6
+ color?: "red" | 'blue' | 'green';
7
+ bold?: true;
8
+ italic?: true;
9
+ underline?: true;
10
+ strikethrough?: true;
11
+ link?: string;
12
+ } | {
13
+ type: "code";
14
+ text: string;
15
+ } | {
16
+ type: "equation";
17
+ latex: string;
18
+ };
19
+ export type BlockMeta<T extends BlockType> = T extends "todo" ? {
20
+ checked?: true;
21
+ depth: number;
22
+ } : T extends "bullet" | "number" ? {
23
+ depth: number;
24
+ } : T extends "code" ? {
25
+ language?: string;
26
+ } : Record<string, never>;
27
+ export type BlockContent<T extends BlockType> = T extends "code" ? [Extract<Node, {
28
+ type: "code";
29
+ }>] : T extends "equation" ? [Extract<Node, {
30
+ type: "equation";
31
+ }>] : Node[];
32
+ export type Block<T extends BlockType = BlockType> = {
33
+ id: string;
34
+ type: T;
35
+ meta: BlockMeta<T>;
36
+ content: BlockContent<T>;
37
+ };
38
+ /**
39
+ * Discriminated Union of Block
40
+ */
41
+ export type AnyBlock = {
42
+ [K in BlockType]: Block<K>;
43
+ }[BlockType];
44
+ //# sourceMappingURL=block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../src/types/block.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,UAAU,GACV,UAAU,GACV,UAAU,GACV,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,UAAU,GACV,MAAM,CAAC;AAIX,MAAM,MAAM,IAAI,GACZ;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACjC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAA;IAChC,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAIxC,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,SAAS,MAAM,GACzD;IAAE,OAAO,CAAC,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC,CAAC,SAAS,QAAQ,GAAG,QAAQ,GAC7B;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB,CAAC,SAAS,MAAM,GAChB;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACrB,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAO1B,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,SAAS,MAAM,GAC5D,CAAC,OAAO,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,GACjC,CAAC,SAAS,UAAU,GACpB,CAAC,OAAO,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC,GACrC,IAAI,EAAE,CAAC;AAIX,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,IAAI;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,CAAC,CAAC;IACR,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG;KAAG,CAAC,IAAI,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC;CAAE,CAAC,SAAS,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.js","sourceRoot":"","sources":["../../src/types/block.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/types/editor.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/types/editor.ts"],"names":[],"mappings":""}
@@ -0,0 +1,32 @@
1
+ import { Result } from '@reiwuzen/result';
2
+ import type { Block, BlockType, AnyBlock } from '../types/block';
3
+ /**
4
+ * Generate a unique block id.
5
+ * Pass a custom fn to override the default (uuid v7).
6
+ */
7
+ export declare function generateId(fn?: () => string): string;
8
+ /**
9
+ * Create a new block of the given type with default content and meta.
10
+ * Optionally pass a custom id generator.
11
+ *
12
+ * @param type - the block type to create
13
+ * @param idFn - optional custom id generator (defaults to uuid v7)
14
+ */
15
+ export declare function createBlock<T extends BlockType>(type: T, idFn?: () => string): Result<Block<T>, unknown>;
16
+ export declare function insertBlockAfter<T extends BlockType>(blocks: AnyBlock[], afterId: string, type: T, idFn?: () => string): Result<{
17
+ blocks: AnyBlock[];
18
+ newId: string;
19
+ }, unknown>;
20
+ export declare function deleteBlock(blocks: AnyBlock[], id: string): {
21
+ blocks: AnyBlock[];
22
+ prevId: string;
23
+ };
24
+ export declare function changeBlockTypeInList<T extends BlockType>(blocks: AnyBlock[], id: string, type: T): AnyBlock[];
25
+ export declare function duplicateBlock(incoming: AnyBlock, newId: string): AnyBlock;
26
+ /**
27
+ * Move a block up or down by one position in the array.
28
+ * Returns the same array unchanged if block is already at the boundary.
29
+ * Returns Err if id not found.
30
+ */
31
+ export declare function moveBlock(blocks: AnyBlock[], id: string, direction: "up" | "down"): Result<AnyBlock[], string>;
32
+ //# sourceMappingURL=block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../src/utils/block.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAA2B,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI1F;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,CAAC,EAAE,MAAM,MAAM,GAAG,MAAM,CAEpD;AAgCD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,SAAS,EAC7C,IAAI,EAAE,CAAC,EACP,IAAI,CAAC,EAAE,MAAM,MAAM,GAClB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAU3B;AAID,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,SAAS,EAClD,MAAM,EAAE,QAAQ,EAAE,EAClB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,CAAC,EACP,IAAI,CAAC,EAAE,MAAM,MAAM,GAClB,MAAM,CAAC;IAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,CAAC,CAOxD;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,QAAQ,EAAE,EAClB,EAAE,EAAE,MAAM,GACT;IAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAIxC;AAED,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,SAAS,EACvD,MAAM,EAAE,QAAQ,EAAE,EAClB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,CAAC,GACN,QAAQ,EAAE,CAMZ;AAKD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAE1E;AAID;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,QAAQ,EAAE,EAClB,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,IAAI,GAAG,MAAM,GACvB,MAAM,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,CAiB5B"}
@@ -0,0 +1,97 @@
1
+ import { Result } from '@reiwuzen/result';
2
+ import { v7 } from 'uuid';
3
+ // ─── generateId ────────────────────────────────────────────────────────────────
4
+ /**
5
+ * Generate a unique block id.
6
+ * Pass a custom fn to override the default (uuid v7).
7
+ */
8
+ export function generateId(fn) {
9
+ return fn ? fn() : v7();
10
+ }
11
+ // ─── Default content per block type ───────────────────────────────────────────
12
+ const defaultContent = {
13
+ paragraph: [],
14
+ heading1: [],
15
+ heading2: [],
16
+ heading3: [],
17
+ bullet: [],
18
+ number: [],
19
+ todo: [],
20
+ code: [{ type: "code", text: "" }],
21
+ equation: [{ type: "equation", latex: "" }],
22
+ };
23
+ // ─── Default meta per block type ──────────────────────────────────────────────
24
+ const defaultMeta = {
25
+ paragraph: {},
26
+ heading1: {},
27
+ heading2: {},
28
+ heading3: {},
29
+ bullet: { depth: 0 },
30
+ number: { depth: 0 },
31
+ todo: { depth: 0 },
32
+ code: {},
33
+ equation: {},
34
+ };
35
+ // ─── createBlock ──────────────────────────────────────────────────────────────
36
+ /**
37
+ * Create a new block of the given type with default content and meta.
38
+ * Optionally pass a custom id generator.
39
+ *
40
+ * @param type - the block type to create
41
+ * @param idFn - optional custom id generator (defaults to uuid v7)
42
+ */
43
+ export function createBlock(type, idFn) {
44
+ return Result.try(() => {
45
+ const block = {
46
+ id: generateId(idFn),
47
+ type,
48
+ meta: defaultMeta[type],
49
+ content: defaultContent[type],
50
+ };
51
+ return block;
52
+ });
53
+ }
54
+ // ─── Block array helpers ───────────────────────────────────────────────────────
55
+ export function insertBlockAfter(blocks, afterId, type, idFn) {
56
+ return createBlock(type, idFn).map((newBlock) => {
57
+ const index = blocks.findIndex((b) => b.id === afterId);
58
+ const next = [...blocks];
59
+ next.splice(index + 1, 0, newBlock);
60
+ return { blocks: next, newId: newBlock.id };
61
+ });
62
+ }
63
+ export function deleteBlock(blocks, id) {
64
+ var _a, _b, _c, _d;
65
+ const index = blocks.findIndex((b) => b.id === id);
66
+ const prevId = (_d = (_b = (_a = blocks[index - 1]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : (_c = blocks[index + 1]) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : "";
67
+ return { blocks: blocks.filter((b) => b.id !== id), prevId };
68
+ }
69
+ export function changeBlockTypeInList(blocks, id, type) {
70
+ return blocks.map((b) => b.id === id
71
+ ? { ...b, type, meta: defaultMeta[type], content: defaultContent[type] }
72
+ : b);
73
+ }
74
+ // ─── duplicateBlock ────────────────────────────────────────────────────────────
75
+ export function duplicateBlock(incoming, newId) {
76
+ return { ...incoming, id: newId };
77
+ }
78
+ // ─── moveBlock ─────────────────────────────────────────────────────────────────
79
+ /**
80
+ * Move a block up or down by one position in the array.
81
+ * Returns the same array unchanged if block is already at the boundary.
82
+ * Returns Err if id not found.
83
+ */
84
+ export function moveBlock(blocks, id, direction) {
85
+ const index = blocks.findIndex((b) => b.id === id);
86
+ if (index === -1)
87
+ return Result.Err(`Block with id "${id}" not found`);
88
+ if (direction === "up" && index === 0)
89
+ return Result.Ok([...blocks]); // already at top
90
+ if (direction === "down" && index === blocks.length - 1)
91
+ return Result.Ok([...blocks]); // already at bottom
92
+ const next = [...blocks];
93
+ const swapIndex = direction === "up" ? index - 1 : index + 1;
94
+ [next[index], next[swapIndex]] = [next[swapIndex], next[index]];
95
+ return Result.Ok(next);
96
+ }
97
+ //# sourceMappingURL=block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.js","sourceRoot":"","sources":["../../src/utils/block.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@reiwuzen/blocky",
3
+ "version": "1.0.0",
4
+ "description": "Pure TypeScript block editor engine. Headless, framework-agnostic — content mutation, formatting, transforms, serialization, and history.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsc --watch",
14
+ "clean": "rimraf dist",
15
+ "test": "tsx tests/test.ts"
16
+ },
17
+ "keywords": [
18
+ "block-editor",
19
+ "headless-editor",
20
+ "block-based",
21
+ "rich-text",
22
+ "editor-engine",
23
+ "editor-core",
24
+ "typescript"
25
+ ],
26
+ "author": "Rei WuZen",
27
+ "license": "ISC",
28
+ "dependencies": {
29
+ "@reiwuzen/result": "^1.0.1",
30
+ "uuid": "^13.0.0"
31
+ },
32
+ "devDependencies": {
33
+ "rimraf": "^6.0.1",
34
+ "tsx": "^4.19.3",
35
+ "typescript": "^5.9.3"
36
+ },
37
+ "exports": {
38
+ ".": {
39
+ "import": "./dist/index.js",
40
+ "types": "./dist/index.d.ts"
41
+ }
42
+ }
43
+ }