@seed-hypermedia/client 0.0.35 → 0.0.36

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/dist/hm-types.mjs CHANGED
@@ -149,6 +149,8 @@ import {
149
149
  ParsedFragmentSchema,
150
150
  StrikeAnnotationSchema,
151
151
  TextColorAnnotationSchema,
152
+ TextFamilyAnnotationSchema,
153
+ TextSizeAnnotationSchema,
152
154
  UnderlineAnnotationSchema,
153
155
  codePointLength,
154
156
  entityQueryPathToHmIdPath,
@@ -167,7 +169,7 @@ import {
167
169
  toNumber,
168
170
  unpackHmId,
169
171
  unpackedHmIdSchema
170
- } from "./chunk-RDTEH34P.mjs";
172
+ } from "./chunk-2BRMXRIG.mjs";
171
173
  export {
172
174
  BackgroundColorAnnotationSchema,
173
175
  BlockRangeSchema,
@@ -319,6 +321,8 @@ export {
319
321
  ParsedFragmentSchema,
320
322
  StrikeAnnotationSchema,
321
323
  TextColorAnnotationSchema,
324
+ TextFamilyAnnotationSchema,
325
+ TextSizeAnnotationSchema,
322
326
  UnderlineAnnotationSchema,
323
327
  codePointLength,
324
328
  entityQueryPathToHmIdPath,
package/dist/index.mjs CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  serializeBlockRange,
18
18
  toNumber,
19
19
  unpackHmId
20
- } from "./chunk-RDTEH34P.mjs";
20
+ } from "./chunk-2BRMXRIG.mjs";
21
21
 
22
22
  // src/capability.ts
23
23
  import { encode as cborEncode2 } from "@ipld/dag-cbor";
@@ -530,6 +530,120 @@ function stripUndefined(obj) {
530
530
  import { decode as cborDecode2, encode as cborEncode6 } from "@ipld/dag-cbor";
531
531
  import { CID as CID3 } from "multiformats";
532
532
  import { base58btc as base58btc3 } from "multiformats/bases/base58";
533
+
534
+ // src/unicode.ts
535
+ var AnnotationSet = class {
536
+ annotations;
537
+ constructor() {
538
+ this.annotations = /* @__PURE__ */ new Map();
539
+ }
540
+ addSpan(type, attributes, start, end) {
541
+ const id = this._annotationId(type, attributes);
542
+ let annotation = this.annotations.get(id);
543
+ if (!annotation) {
544
+ const annAttrs = attributes ? { ...attributes } : {};
545
+ let link;
546
+ if (type == "Link" || type == "Embed") {
547
+ link = attributes == null ? void 0 : attributes.link;
548
+ delete annAttrs.link;
549
+ }
550
+ annotation = {
551
+ type,
552
+ attributes: annAttrs,
553
+ link: link || "",
554
+ starts: [],
555
+ ends: []
556
+ };
557
+ this.annotations.set(id, annotation);
558
+ }
559
+ addSpanToAnnotation(annotation, start, end);
560
+ }
561
+ _annotationId(type, attributes) {
562
+ if (attributes) {
563
+ if (attributes.link) {
564
+ return `${type}-${attributes.link}`;
565
+ }
566
+ if (attributes.href) {
567
+ return `${type}-${attributes.href}`;
568
+ }
569
+ if (attributes.value) {
570
+ return `${type}-${attributes.value}`;
571
+ }
572
+ }
573
+ return type;
574
+ }
575
+ list() {
576
+ const keys = Array.from(this.annotations.keys()).sort();
577
+ let out = new Array(keys.length);
578
+ for (let i in keys) {
579
+ const annotation = this.annotations.get(keys[i]);
580
+ if (annotation) out[i] = annotation;
581
+ }
582
+ out = out.sort((a, b) => {
583
+ let startA = a.starts[0];
584
+ let startB = b.starts[0];
585
+ return (startA || 0) - (startB || 0);
586
+ });
587
+ return out;
588
+ }
589
+ };
590
+ function addSpanToAnnotation(annotation, start, end) {
591
+ if (!annotation.starts) {
592
+ annotation.starts = [];
593
+ }
594
+ if (!annotation.ends) {
595
+ annotation.ends = [];
596
+ }
597
+ if (annotation.starts.length == 0) {
598
+ pushSpanToAnnotation(annotation, start, end);
599
+ return;
600
+ }
601
+ const lastIdx = annotation.starts.length - 1;
602
+ if (annotation.ends[lastIdx] == start) {
603
+ annotation.ends[lastIdx] = end;
604
+ return;
605
+ }
606
+ pushSpanToAnnotation(annotation, start, end);
607
+ }
608
+ function pushSpanToAnnotation(annotation, start, end) {
609
+ annotation.starts.push(start);
610
+ annotation.ends.push(end);
611
+ }
612
+ var EXCLUSIVE_TYPES = ["TextColor", "BackgroundColor", "TextSize", "TextFamily"];
613
+ function spansOverlap(a, b) {
614
+ for (let i = 0; i < a.starts.length; i++) {
615
+ const aStart = a.starts[i];
616
+ const aEnd = a.ends[i];
617
+ if (aStart === void 0 || aEnd === void 0) continue;
618
+ for (let j = 0; j < b.starts.length; j++) {
619
+ const bStart = b.starts[j];
620
+ const bEnd = b.ends[j];
621
+ if (bStart === void 0 || bEnd === void 0) continue;
622
+ if (aStart < bEnd && bStart < aEnd) return true;
623
+ }
624
+ }
625
+ return false;
626
+ }
627
+ function validateExclusiveAnnotations(annotations) {
628
+ var _a, _b;
629
+ for (const type of EXCLUSIVE_TYPES) {
630
+ const ofType = annotations.filter((a) => a.type === type);
631
+ for (let i = 0; i < ofType.length; i++) {
632
+ for (let j = i + 1; j < ofType.length; j++) {
633
+ const a = ofType[i];
634
+ const b = ofType[j];
635
+ const aVal = (_a = a.attributes) == null ? void 0 : _a.value;
636
+ const bVal = (_b = b.attributes) == null ? void 0 : _b.value;
637
+ if (aVal && bVal && aVal === bVal) continue;
638
+ if (spansOverlap(a, b)) {
639
+ throw new Error(`${type} annotations with different values have overlapping ranges`);
640
+ }
641
+ }
642
+ }
643
+ }
644
+ }
645
+
646
+ // src/comment.ts
533
647
  function trimTrailingEmptyBlocks(blocks) {
534
648
  let end = blocks.length;
535
649
  while (end > 0) {
@@ -546,7 +660,9 @@ function isEmptyBlockNode(node) {
546
660
  return !block.text || block.text.trim() === "";
547
661
  }
548
662
  function annotationsToPublishable(annotations) {
663
+ validateExclusiveAnnotations(annotations);
549
664
  return annotations.map((annotation) => {
665
+ var _a, _b, _c, _d;
550
666
  const { type, starts, ends } = annotation;
551
667
  if (type === "Bold") return { type: "Bold", starts, ends };
552
668
  if (type === "Italic") return { type: "Italic", starts, ends };
@@ -555,6 +671,19 @@ function annotationsToPublishable(annotations) {
555
671
  if (type === "Code") return { type: "Code", starts, ends };
556
672
  if (type === "Link") return { type: "Link", starts, ends, link: annotation.link || "" };
557
673
  if (type === "Embed") return { type: "Embed", starts, ends, link: annotation.link || "" };
674
+ if (type === "TextColor")
675
+ return { type: "TextColor", starts, ends, attributes: { value: ((_a = annotation.attributes) == null ? void 0 : _a.value) || "" } };
676
+ if (type === "BackgroundColor")
677
+ return {
678
+ type: "BackgroundColor",
679
+ starts,
680
+ ends,
681
+ attributes: { value: ((_b = annotation.attributes) == null ? void 0 : _b.value) || "" }
682
+ };
683
+ if (type === "TextSize")
684
+ return { type: "TextSize", starts, ends, attributes: { value: ((_c = annotation.attributes) == null ? void 0 : _c.value) || "" } };
685
+ if (type === "TextFamily")
686
+ return { type: "TextFamily", starts, ends, attributes: { value: ((_d = annotation.attributes) == null ? void 0 : _d.value) || "" } };
558
687
  throw new Error(`Unsupported annotation type: ${type}`);
559
688
  });
560
689
  }
@@ -3412,85 +3541,6 @@ function generateBlockId5() {
3412
3541
  return id;
3413
3542
  }
3414
3543
 
3415
- // src/unicode.ts
3416
- var AnnotationSet = class {
3417
- annotations;
3418
- constructor() {
3419
- this.annotations = /* @__PURE__ */ new Map();
3420
- }
3421
- addSpan(type, attributes, start, end) {
3422
- const id = this._annotationId(type, attributes);
3423
- let annotation = this.annotations.get(id);
3424
- if (!annotation) {
3425
- const annAttrs = attributes ? { ...attributes } : {};
3426
- let link;
3427
- if (type == "Link" || type == "Embed") {
3428
- link = attributes == null ? void 0 : attributes.link;
3429
- delete annAttrs.link;
3430
- }
3431
- annotation = {
3432
- type,
3433
- attributes: annAttrs,
3434
- link: link || "",
3435
- starts: [],
3436
- ends: []
3437
- };
3438
- this.annotations.set(id, annotation);
3439
- }
3440
- addSpanToAnnotation(annotation, start, end);
3441
- }
3442
- _annotationId(type, attributes) {
3443
- if (attributes) {
3444
- if (attributes.link) {
3445
- return `${type}-${attributes.link}`;
3446
- }
3447
- if (attributes.href) {
3448
- return `${type}-${attributes.href}`;
3449
- }
3450
- if (attributes.color) {
3451
- return `${type}-${attributes.color}`;
3452
- }
3453
- }
3454
- return type;
3455
- }
3456
- list() {
3457
- const keys = Array.from(this.annotations.keys()).sort();
3458
- let out = new Array(keys.length);
3459
- for (let i in keys) {
3460
- const annotation = this.annotations.get(keys[i]);
3461
- if (annotation) out[i] = annotation;
3462
- }
3463
- out = out.sort((a, b) => {
3464
- let startA = a.starts[0];
3465
- let startB = b.starts[0];
3466
- return (startA || 0) - (startB || 0);
3467
- });
3468
- return out;
3469
- }
3470
- };
3471
- function addSpanToAnnotation(annotation, start, end) {
3472
- if (!annotation.starts) {
3473
- annotation.starts = [];
3474
- }
3475
- if (!annotation.ends) {
3476
- annotation.ends = [];
3477
- }
3478
- if (annotation.starts.length == 0) {
3479
- pushSpanToAnnotation(annotation, start, end);
3480
- return;
3481
- }
3482
- const lastIdx = annotation.starts.length - 1;
3483
- if (annotation.ends[lastIdx] == start) {
3484
- annotation.ends[lastIdx] = end;
3485
- return;
3486
- }
3487
- pushSpanToAnnotation(annotation, start, end);
3488
- }
3489
- function pushSpanToAnnotation(annotation, start, end) {
3490
- annotation.starts.push(start);
3491
- annotation.ends.push(end);
3492
- }
3493
-
3494
3544
  // src/editorblock-to-hmblock.ts
3495
3545
  function toHMBlockType(editorBlockType) {
3496
3546
  if (editorBlockType === "heading") return "Heading";
@@ -3514,7 +3564,7 @@ function toImageWidthNumber(width) {
3514
3564
  return toNumber(width);
3515
3565
  }
3516
3566
  function editorBlockToHMBlock(editorBlock) {
3517
- var _a, _b, _c, _d, _e, _f, _g, _h;
3567
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
3518
3568
  const blockType = toHMBlockType(editorBlock.type);
3519
3569
  if (!blockType) throw new Error("Unsupported block type " + editorBlock.type);
3520
3570
  let block = {
@@ -3570,10 +3620,16 @@ function editorBlockToHMBlock(editorBlock) {
3570
3620
  annotations.addSpan("Link", { link: leaf.href }, start, end);
3571
3621
  }
3572
3622
  if ((_g = leaf.styles) == null ? void 0 : _g.textColor) {
3573
- annotations.addSpan("TextColor", { color: leaf.styles.textColor }, start, end);
3623
+ annotations.addSpan("TextColor", { value: leaf.styles.textColor }, start, end);
3574
3624
  }
3575
3625
  if ((_h = leaf.styles) == null ? void 0 : _h.backgroundColor) {
3576
- annotations.addSpan("BackgroundColor", { color: leaf.styles.backgroundColor }, start, end);
3626
+ annotations.addSpan("BackgroundColor", { value: leaf.styles.backgroundColor }, start, end);
3627
+ }
3628
+ if ((_i = leaf.styles) == null ? void 0 : _i.textSize) {
3629
+ annotations.addSpan("TextSize", { value: leaf.styles.textSize }, start, end);
3630
+ }
3631
+ if ((_j = leaf.styles) == null ? void 0 : _j.textFamily) {
3632
+ annotations.addSpan("TextFamily", { value: leaf.styles.textFamily }, start, end);
3577
3633
  }
3578
3634
  block.text += leaf.text;
3579
3635
  pos += charCount;
@@ -3912,7 +3968,7 @@ function hmBlockToEditorBlock(block) {
3912
3968
  i += codeUnits;
3913
3969
  }
3914
3970
  function startLeaf(posAnnotations) {
3915
- var _a2, _b2;
3971
+ var _a2, _b2, _c2, _d2;
3916
3972
  const newLeaf = {
3917
3973
  type: "text",
3918
3974
  text: "",
@@ -3939,19 +3995,33 @@ function hmBlockToEditorBlock(block) {
3939
3995
  newLeaf.styles[styleKey] = true;
3940
3996
  }
3941
3997
  if (annotationData.type === "TextColor") {
3942
- const color = (_a2 = annotationData.attributes) == null ? void 0 : _a2.color;
3998
+ const color = (_a2 = annotationData.attributes) == null ? void 0 : _a2.value;
3943
3999
  if (typeof color === "string" && color) {
3944
4000
  ;
3945
4001
  newLeaf.styles.textColor = color;
3946
4002
  }
3947
4003
  }
3948
4004
  if (annotationData.type === "BackgroundColor") {
3949
- const color = (_b2 = annotationData.attributes) == null ? void 0 : _b2.color;
4005
+ const color = (_b2 = annotationData.attributes) == null ? void 0 : _b2.value;
3950
4006
  if (typeof color === "string" && color) {
3951
4007
  ;
3952
4008
  newLeaf.styles.backgroundColor = color;
3953
4009
  }
3954
4010
  }
4011
+ if (annotationData.type === "TextSize") {
4012
+ const size = (_c2 = annotationData.attributes) == null ? void 0 : _c2.value;
4013
+ if (typeof size === "string" && size) {
4014
+ ;
4015
+ newLeaf.styles.textSize = size;
4016
+ }
4017
+ }
4018
+ if (annotationData.type === "TextFamily") {
4019
+ const family = (_d2 = annotationData.attributes) == null ? void 0 : _d2.value;
4020
+ if (typeof family === "string" && family) {
4021
+ ;
4022
+ newLeaf.styles.textFamily = family;
4023
+ }
4024
+ }
3955
4025
  }
3956
4026
  if (linkAnnotation) {
3957
4027
  if (linkAnnotation.type === "Embed") {
package/dist/unicode.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { HMAnnotations } from './hm-types';
1
+ import type { HMAnnotation, HMAnnotations } from './hm-types';
2
2
  /**
3
3
  * Mutable annotation shape used during construction.
4
4
  * Structurally compatible with HMAnnotation but uses plain objects
@@ -31,5 +31,10 @@ export declare class AnnotationSet {
31
31
  export declare function addSpanToAnnotation(annotation: SpanAnnotation, start: number, end: number): void;
32
32
  /** Push a span to an annotation without checking adjacency. */
33
33
  export declare function pushSpanToAnnotation(annotation: SpanAnnotation, start: number, end: number): void;
34
+ /**
35
+ * Validate that exclusive annotations of the same type with different values
36
+ * do not have overlapping ranges. Throws on invalid state.
37
+ */
38
+ export declare function validateExclusiveAnnotations(annotations: HMAnnotation[]): void;
34
39
  /** @deprecated Import from `@seed-hypermedia/client/hm-types` instead. */
35
40
  export { codePointLength, isSurrogate } from './hm-types';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seed-hypermedia/client",
3
- "version": "0.0.35",
3
+ "version": "0.0.36",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/seed-hypermedia/seed",