@seed-hypermedia/client 0.0.34 → 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";
@@ -3506,8 +3556,15 @@ function toHMBlockType(editorBlockType) {
3506
3556
  if (editorBlockType === "query") return "Query";
3507
3557
  return void 0;
3508
3558
  }
3559
+ function toImageWidthNumber(width) {
3560
+ if (width == null ? void 0 : width.trim().endsWith("%")) {
3561
+ const percentage = Number(width.trim().slice(0, -1));
3562
+ return Number.isFinite(percentage) && percentage > 0 ? percentage : null;
3563
+ }
3564
+ return toNumber(width);
3565
+ }
3509
3566
  function editorBlockToHMBlock(editorBlock) {
3510
- var _a, _b, _c, _d, _e, _f, _g, _h;
3567
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
3511
3568
  const blockType = toHMBlockType(editorBlock.type);
3512
3569
  if (!blockType) throw new Error("Unsupported block type " + editorBlock.type);
3513
3570
  let block = {
@@ -3563,10 +3620,16 @@ function editorBlockToHMBlock(editorBlock) {
3563
3620
  annotations.addSpan("Link", { link: leaf.href }, start, end);
3564
3621
  }
3565
3622
  if ((_g = leaf.styles) == null ? void 0 : _g.textColor) {
3566
- annotations.addSpan("TextColor", { color: leaf.styles.textColor }, start, end);
3623
+ annotations.addSpan("TextColor", { value: leaf.styles.textColor }, start, end);
3567
3624
  }
3568
3625
  if ((_h = leaf.styles) == null ? void 0 : _h.backgroundColor) {
3569
- 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);
3570
3633
  }
3571
3634
  block.text += leaf.text;
3572
3635
  pos += charCount;
@@ -3592,7 +3655,7 @@ function editorBlockToHMBlock(editorBlock) {
3592
3655
  } else {
3593
3656
  blockImage.link = "";
3594
3657
  }
3595
- const width = toNumber(editorBlock.props.width);
3658
+ const width = toImageWidthNumber(editorBlock.props.width);
3596
3659
  if (width) {
3597
3660
  blockImage.attributes.width = width;
3598
3661
  }
@@ -3805,7 +3868,7 @@ function hmBlockToEditorBlock(block) {
3805
3868
  if (key == "width" || key == "size") {
3806
3869
  if (typeof value == "number") {
3807
3870
  ;
3808
- out.props[key] = String(value);
3871
+ out.props[key] = blockType === "image" && key === "width" && value > 0 && value <= 100 ? `${value}%` : String(value);
3809
3872
  }
3810
3873
  } else if (typeof value == "boolean") {
3811
3874
  ;
@@ -3905,7 +3968,7 @@ function hmBlockToEditorBlock(block) {
3905
3968
  i += codeUnits;
3906
3969
  }
3907
3970
  function startLeaf(posAnnotations) {
3908
- var _a2, _b2;
3971
+ var _a2, _b2, _c2, _d2;
3909
3972
  const newLeaf = {
3910
3973
  type: "text",
3911
3974
  text: "",
@@ -3932,19 +3995,33 @@ function hmBlockToEditorBlock(block) {
3932
3995
  newLeaf.styles[styleKey] = true;
3933
3996
  }
3934
3997
  if (annotationData.type === "TextColor") {
3935
- const color = (_a2 = annotationData.attributes) == null ? void 0 : _a2.color;
3998
+ const color = (_a2 = annotationData.attributes) == null ? void 0 : _a2.value;
3936
3999
  if (typeof color === "string" && color) {
3937
4000
  ;
3938
4001
  newLeaf.styles.textColor = color;
3939
4002
  }
3940
4003
  }
3941
4004
  if (annotationData.type === "BackgroundColor") {
3942
- const color = (_b2 = annotationData.attributes) == null ? void 0 : _b2.color;
4005
+ const color = (_b2 = annotationData.attributes) == null ? void 0 : _b2.value;
3943
4006
  if (typeof color === "string" && color) {
3944
4007
  ;
3945
4008
  newLeaf.styles.backgroundColor = color;
3946
4009
  }
3947
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
+ }
3948
4025
  }
3949
4026
  if (linkAnnotation) {
3950
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.34",
3
+ "version": "0.0.36",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/seed-hypermedia/seed",