@rtif-sdk/core 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,90 @@
1
+ /**
2
+ * Offset resolution — converts absolute offsets to block-local coordinates.
3
+ * See SPEC.md §2.4 for specification.
4
+ */
5
+ import { RtifError } from './error.js';
6
+ /**
7
+ * Compute the text length of a block (sum of all span text lengths).
8
+ *
9
+ * @param block - The block to measure
10
+ * @returns Total character count across all spans
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * blockTextLength({ id: 'b1', type: 'text', spans: [{ text: 'hello' }] });
15
+ * // => 5
16
+ * ```
17
+ */
18
+ export function blockTextLength(block) {
19
+ let len = 0;
20
+ for (const span of block.spans) {
21
+ len += span.text.length;
22
+ }
23
+ return len;
24
+ }
25
+ /**
26
+ * Compute the total document length (all block text + virtual newlines between blocks).
27
+ *
28
+ * @param doc - The document to measure
29
+ * @returns Total character count including virtual newline separators
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * docLength({ version: 1, blocks: [
34
+ * { id: 'b1', type: 'text', spans: [{ text: 'hello' }] },
35
+ * { id: 'b2', type: 'text', spans: [{ text: 'world' }] },
36
+ * ] });
37
+ * // => 11 (5 + 1 + 5)
38
+ * ```
39
+ */
40
+ export function docLength(doc) {
41
+ let len = 0;
42
+ for (let i = 0; i < doc.blocks.length; i++) {
43
+ if (i > 0)
44
+ len += 1; // virtual \n separator
45
+ len += blockTextLength(doc.blocks[i]);
46
+ }
47
+ return len;
48
+ }
49
+ /**
50
+ * Resolve an absolute document offset to a block index and local offset.
51
+ *
52
+ * Walks blocks, subtracting lengths (including the +1 separator per block
53
+ * boundary), until the offset lands inside a block.
54
+ *
55
+ * @param doc - The document to resolve against
56
+ * @param offset - Absolute character offset from document start
57
+ * @returns Block index and character offset within that block
58
+ * @throws {RtifError} OFFSET_OUT_OF_RANGE if offset is negative or exceeds document length
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * const { blockIndex, localOffset } = resolve(doc, 5);
63
+ * ```
64
+ */
65
+ export function resolve(doc, offset) {
66
+ if (offset < 0) {
67
+ throw new RtifError('OFFSET_OUT_OF_RANGE', `Offset ${offset} is negative`);
68
+ }
69
+ let remaining = offset;
70
+ for (let i = 0; i < doc.blocks.length; i++) {
71
+ const block = doc.blocks[i];
72
+ const len = blockTextLength(block);
73
+ // If remaining fits within this block (including end-of-block position)
74
+ if (remaining <= len) {
75
+ return { blockIndex: i, localOffset: remaining };
76
+ }
77
+ // Subtract block length + virtual \n separator
78
+ remaining -= len;
79
+ // Account for virtual newline between blocks (not after last block)
80
+ if (i < doc.blocks.length - 1) {
81
+ remaining -= 1; // virtual \n
82
+ if (remaining < 0) {
83
+ // Offset lands exactly on the virtual \n → resolve to end of this block
84
+ return { blockIndex: i, localOffset: len };
85
+ }
86
+ }
87
+ }
88
+ throw new RtifError('OFFSET_OUT_OF_RANGE', `Offset ${offset} exceeds document length ${docLength(doc)}`);
89
+ }
90
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AASvC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,KAAY;IAC1C,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CAAC,GAAa;IACrC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC,GAAG,CAAC;YAAE,GAAG,IAAI,CAAC,CAAC,CAAC,uBAAuB;QAC5C,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,OAAO,CAAC,GAAa,EAAE,MAAc;IACnD,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,SAAS,CACjB,qBAAqB,EACrB,UAAU,MAAM,cAAc,CAC/B,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,GAAG,MAAM,CAAC;IAEvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAEnC,wEAAwE;QACxE,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;YACrB,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;QACnD,CAAC;QAED,+CAA+C;QAC/C,SAAS,IAAI,GAAG,CAAC;QAEjB,oEAAoE;QACpE,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,SAAS,IAAI,CAAC,CAAC,CAAC,aAAa;YAE7B,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBAClB,wEAAwE;gBACxE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,SAAS,CACjB,qBAAqB,EACrB,UAAU,MAAM,4BAA4B,SAAS,CAAC,GAAG,CAAC,EAAE,CAC7D,CAAC;AACJ,CAAC"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Mark serialization contracts for format plugins.
3
+ *
4
+ * Provides a registry for mark-specific serializers that format plugins
5
+ * (plaintext, markdown, HTML) can consult when converting RTIF documents
6
+ * to and from external formats.
7
+ *
8
+ * @module
9
+ */
10
+ /** Supported format identifiers for mark serialization. */
11
+ export type SerializationFormat = 'plaintext' | 'markdown' | 'html';
12
+ /**
13
+ * A mark serializer converts a span's text and mark value to a formatted string.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const boldSerializer: MarkSerializer = {
18
+ * serialize: (text) => `**${text}**`,
19
+ * };
20
+ * ```
21
+ */
22
+ export interface MarkSerializer {
23
+ /**
24
+ * Serialize a marked span's text to the target format.
25
+ *
26
+ * @param text - The span's raw text content
27
+ * @param value - The mark value (e.g., `true` for bold, `{ id, displayName }` for mention)
28
+ * @returns The formatted string representation
29
+ */
30
+ serialize(text: string, value: unknown): string;
31
+ /**
32
+ * Deserialize formatted text back to a mark value.
33
+ * Optional -- not all serializers support deserialization.
34
+ *
35
+ * @param formatted - The formatted string to parse
36
+ * @returns The mark value, or null if the input cannot be parsed
37
+ */
38
+ deserialize?(formatted: string): unknown | null;
39
+ }
40
+ /**
41
+ * Registry of mark serializers, keyed by mark type and format.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * const registry = createMarkSerializerRegistry();
46
+ * registry.register('mention', 'markdown', mentionMarkdownSerializer);
47
+ * const serializer = registry.get('mention', 'markdown');
48
+ * ```
49
+ */
50
+ export interface MarkSerializerRegistry {
51
+ /**
52
+ * Register a serializer for a mark type and format.
53
+ *
54
+ * @param markType - The mark type string (e.g., "mention", "link")
55
+ * @param format - The target serialization format
56
+ * @param serializer - The serializer implementation
57
+ */
58
+ register(markType: string, format: SerializationFormat, serializer: MarkSerializer): void;
59
+ /**
60
+ * Get the serializer for a mark type and format.
61
+ *
62
+ * @param markType - The mark type to look up
63
+ * @param format - The target format
64
+ * @returns The registered serializer, or undefined if none registered
65
+ */
66
+ get(markType: string, format: SerializationFormat): MarkSerializer | undefined;
67
+ /**
68
+ * Check whether a serializer is registered for a mark type and format.
69
+ *
70
+ * @param markType - The mark type to check
71
+ * @param format - The format to check
72
+ * @returns `true` if a serializer is registered
73
+ */
74
+ has(markType: string, format: SerializationFormat): boolean;
75
+ }
76
+ /**
77
+ * Create a new mark serializer registry.
78
+ *
79
+ * @returns An empty registry ready for serializer registration
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * const registry = createMarkSerializerRegistry();
84
+ * registry.register('bold', 'markdown', { serialize: (text) => `**${text}**` });
85
+ * registry.register('bold', 'html', { serialize: (text) => `<strong>${text}</strong>` });
86
+ * ```
87
+ */
88
+ export declare function createMarkSerializerRegistry(): MarkSerializerRegistry;
89
+ //# sourceMappingURL=serialization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,2DAA2D;AAC3D,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;AAEpE;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IAEhD;;;;;;OAMG;IACH,WAAW,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;CACjD;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,UAAU,EAAE,cAAc,GAAG,IAAI,CAAC;IAE1F;;;;;;OAMG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,cAAc,GAAG,SAAS,CAAC;IAE/E;;;;;;OAMG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC;CAC7D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,IAAI,sBAAsB,CAoBrE"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Mark serialization contracts for format plugins.
3
+ *
4
+ * Provides a registry for mark-specific serializers that format plugins
5
+ * (plaintext, markdown, HTML) can consult when converting RTIF documents
6
+ * to and from external formats.
7
+ *
8
+ * @module
9
+ */
10
+ /**
11
+ * Create a new mark serializer registry.
12
+ *
13
+ * @returns An empty registry ready for serializer registration
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const registry = createMarkSerializerRegistry();
18
+ * registry.register('bold', 'markdown', { serialize: (text) => `**${text}**` });
19
+ * registry.register('bold', 'html', { serialize: (text) => `<strong>${text}</strong>` });
20
+ * ```
21
+ */
22
+ export function createMarkSerializerRegistry() {
23
+ const serializers = new Map();
24
+ function makeKey(markType, format) {
25
+ return `${markType}:${format}`;
26
+ }
27
+ return {
28
+ register(markType, format, serializer) {
29
+ serializers.set(makeKey(markType, format), serializer);
30
+ },
31
+ get(markType, format) {
32
+ return serializers.get(makeKey(markType, format));
33
+ },
34
+ has(markType, format) {
35
+ return serializers.has(makeKey(markType, format));
36
+ },
37
+ };
38
+ }
39
+ //# sourceMappingURL=serialization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialization.js","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA0EH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,4BAA4B;IAC1C,MAAM,WAAW,GAAG,IAAI,GAAG,EAA0B,CAAC;IAEtD,SAAS,OAAO,CAAC,QAAgB,EAAE,MAA2B;QAC5D,OAAO,GAAG,QAAQ,IAAI,MAAM,EAAE,CAAC;IACjC,CAAC;IAED,OAAO;QACL,QAAQ,CAAC,QAAgB,EAAE,MAA2B,EAAE,UAA0B;YAChF,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;QACzD,CAAC;QAED,GAAG,CAAC,QAAgB,EAAE,MAA2B;YAC/C,OAAO,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,GAAG,CAAC,QAAgB,EAAE,MAA2B;YAC/C,OAAO,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;QACpD,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Document validation — structural integrity checks.
3
+ * See docs/spec/data-model.md for invariants.
4
+ */
5
+ import type { Document } from './model.js';
6
+ export interface ValidationError {
7
+ readonly path: string;
8
+ readonly message: string;
9
+ }
10
+ export interface ValidationResult {
11
+ readonly valid: boolean;
12
+ readonly errors: readonly ValidationError[];
13
+ }
14
+ /**
15
+ * Validate a document's structural integrity.
16
+ *
17
+ * Checks all six document invariants:
18
+ * 1. `version` is 1
19
+ * 2. At least one block (Invariant 1)
20
+ * 3. Every block has a non-empty `id` and `type`
21
+ * 4. Every block has at least one span (Invariant 2)
22
+ * 5. No empty spans in multi-span blocks (Invariant 3)
23
+ * 6. No adjacent spans with identical marks (Invariant 4)
24
+ * 7. Block IDs are unique (Invariant 5)
25
+ *
26
+ * @param doc - The document to validate
27
+ * @returns Validation result with collected errors
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const result = validate(doc);
32
+ * if (!result.valid) {
33
+ * console.error(result.errors);
34
+ * }
35
+ * ```
36
+ */
37
+ export declare function validate(doc: Document): ValidationResult;
38
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;CAC7C;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,QAAQ,GAAG,gBAAgB,CA0ExD"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Document validation — structural integrity checks.
3
+ * See docs/spec/data-model.md for invariants.
4
+ */
5
+ import { marksEqual } from './normalize.js';
6
+ /**
7
+ * Validate a document's structural integrity.
8
+ *
9
+ * Checks all six document invariants:
10
+ * 1. `version` is 1
11
+ * 2. At least one block (Invariant 1)
12
+ * 3. Every block has a non-empty `id` and `type`
13
+ * 4. Every block has at least one span (Invariant 2)
14
+ * 5. No empty spans in multi-span blocks (Invariant 3)
15
+ * 6. No adjacent spans with identical marks (Invariant 4)
16
+ * 7. Block IDs are unique (Invariant 5)
17
+ *
18
+ * @param doc - The document to validate
19
+ * @returns Validation result with collected errors
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const result = validate(doc);
24
+ * if (!result.valid) {
25
+ * console.error(result.errors);
26
+ * }
27
+ * ```
28
+ */
29
+ export function validate(doc) {
30
+ const errors = [];
31
+ // 1. version must be 1
32
+ if (doc.version !== 1) {
33
+ errors.push({
34
+ path: 'version',
35
+ message: `Expected version 1, got ${String(doc.version)}`,
36
+ });
37
+ }
38
+ // 2. at least one block
39
+ if (doc.blocks.length === 0) {
40
+ errors.push({
41
+ path: 'blocks',
42
+ message: 'Document must have at least one block',
43
+ });
44
+ return { valid: false, errors };
45
+ }
46
+ const seenIds = new Set();
47
+ for (let i = 0; i < doc.blocks.length; i++) {
48
+ const block = doc.blocks[i];
49
+ const bp = `blocks[${i}]`;
50
+ // 3a. non-empty id
51
+ if (!block.id) {
52
+ errors.push({ path: `${bp}.id`, message: 'Block must have a non-empty id' });
53
+ }
54
+ // 3b. non-empty type
55
+ if (!block.type) {
56
+ errors.push({ path: `${bp}.type`, message: 'Block must have a non-empty type' });
57
+ }
58
+ // 7. unique block IDs
59
+ if (block.id) {
60
+ if (seenIds.has(block.id)) {
61
+ errors.push({ path: `${bp}.id`, message: `Duplicate block id '${block.id}'` });
62
+ }
63
+ seenIds.add(block.id);
64
+ }
65
+ // 4. at least one span
66
+ if (block.spans.length === 0) {
67
+ errors.push({ path: `${bp}.spans`, message: 'Block must have at least one span' });
68
+ continue;
69
+ }
70
+ // 5. no empty spans in multi-span blocks
71
+ if (block.spans.length > 1) {
72
+ for (let j = 0; j < block.spans.length; j++) {
73
+ if (block.spans[j].text === '') {
74
+ errors.push({
75
+ path: `${bp}.spans[${j}]`,
76
+ message: 'Empty span in multi-span block',
77
+ });
78
+ }
79
+ }
80
+ }
81
+ // 6. no adjacent spans with identical marks
82
+ for (let j = 0; j < block.spans.length - 1; j++) {
83
+ if (marksEqual(block.spans[j].marks, block.spans[j + 1].marks)) {
84
+ errors.push({
85
+ path: `${bp}.spans[${j}]`,
86
+ message: 'Adjacent spans have identical marks',
87
+ });
88
+ }
89
+ }
90
+ }
91
+ return { valid: errors.length === 0, errors };
92
+ }
93
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAY5C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAa;IACpC,MAAM,MAAM,GAAsB,EAAE,CAAC;IAErC,uBAAuB;IACvB,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,2BAA2B,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;SAC1D,CAAC,CAAC;IACL,CAAC;IAED,wBAAwB;IACxB,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,uCAAuC;SACjD,CAAC,CAAC;QACH,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAClC,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC;QAE1B,mBAAmB;QACnB,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,gCAAgC,EAAE,CAAC,CAAC;QAC/E,CAAC;QAED,qBAAqB;QACrB,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,kCAAkC,EAAE,CAAC,CAAC;QACnF,CAAC;QAED,sBAAsB;QACtB,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;YACb,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC1B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,uBAAuB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;YACjF,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACxB,CAAC;QAED,uBAAuB;QACvB,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC,CAAC;YACnF,SAAS;QACX,CAAC;QAED,yCAAyC;QACzC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5C,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;oBAChC,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG;wBACzB,OAAO,EAAE,gCAAgC;qBAC1C,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,4CAA4C;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjE,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG;oBACzB,OAAO,EAAE,qCAAqC;iBAC/C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AAChD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@rtif-sdk/core",
3
+ "version": "1.0.0",
4
+ "description": "RTIF core data model, operations, and utilities",
5
+ "author": "coryrobinson42@gmail.com",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": ["dist"],
16
+ "sideEffects": false,
17
+ "engines": { "node": ">=20.0.0" },
18
+ "keywords": ["rich-text", "editor", "document-model", "text-editing", "rtif", "operations"],
19
+ "scripts": {
20
+ "build": "tsc --build tsconfig.build.json",
21
+ "test": "vitest run",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "license": "MIT"
25
+ }