@seed-hypermedia/client 0.0.2 → 0.0.4

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/index.mjs CHANGED
@@ -1,5 +1,7 @@
1
1
  import {
2
2
  HMActionSchema,
3
+ HMBlockButtonAlignmentSchema,
4
+ HMBlockSchema,
3
5
  HMRequestSchema,
4
6
  HYPERMEDIA_SCHEME,
5
7
  codePointLength,
@@ -12,8 +14,9 @@ import {
12
14
  parseCustomURL,
13
15
  parseFragment,
14
16
  serializeBlockRange,
17
+ toNumber,
15
18
  unpackHmId
16
- } from "./chunk-PPK3SKPV.mjs";
19
+ } from "./chunk-YIND2WNJ.mjs";
17
20
 
18
21
  // src/capability.ts
19
22
  import { encode as cborEncode2 } from "@ipld/dag-cbor";
@@ -2517,6 +2520,37 @@ function parseMarkdown(markdown) {
2517
2520
  }
2518
2521
  return { tree: rootNodes, metadata };
2519
2522
  }
2523
+ function markdownBlockNodesToHMBlockNodes(nodes) {
2524
+ return nodes.map((node) => {
2525
+ const { block } = node;
2526
+ const attributes = {};
2527
+ if (block.childrenType !== void 0) {
2528
+ attributes.childrenType = block.childrenType;
2529
+ }
2530
+ if (block.language !== void 0) {
2531
+ attributes.language = block.language;
2532
+ }
2533
+ const hmBlock = {
2534
+ type: block.type,
2535
+ id: block.id,
2536
+ text: block.text,
2537
+ annotations: block.annotations.map((a) => ({
2538
+ type: a.type,
2539
+ starts: a.starts,
2540
+ ends: a.ends,
2541
+ ...a.link !== void 0 ? { link: a.link } : {}
2542
+ })),
2543
+ attributes
2544
+ };
2545
+ if (block.link !== void 0) {
2546
+ hmBlock.link = block.link;
2547
+ }
2548
+ return {
2549
+ block: hmBlock,
2550
+ children: node.children.length > 0 ? markdownBlockNodesToHMBlockNodes(node.children) : void 0
2551
+ };
2552
+ });
2553
+ }
2520
2554
  function flattenToOperations(tree, parentId = "") {
2521
2555
  const ops = [];
2522
2556
  const blockIds = [];
@@ -2777,6 +2811,23 @@ function formatMediaUrl(url, useGateway) {
2777
2811
  function indent(depth) {
2778
2812
  return " ".repeat(depth);
2779
2813
  }
2814
+ function slugify(title) {
2815
+ return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60);
2816
+ }
2817
+ function draftFilename(slug, id) {
2818
+ if (!slug) return `${id}.md`;
2819
+ return `${slug}_${id}.md`;
2820
+ }
2821
+ function parseDraftFilename(filename) {
2822
+ const lastDot = filename.lastIndexOf(".");
2823
+ const ext = lastDot >= 0 ? filename.slice(lastDot) : "";
2824
+ const base = lastDot >= 0 ? filename.slice(0, lastDot) : filename;
2825
+ const lastUnderscore = base.lastIndexOf("_");
2826
+ if (lastUnderscore >= 0 && ext === ".md") {
2827
+ return { id: base.slice(lastUnderscore + 1), ext };
2828
+ }
2829
+ return { id: base, ext };
2830
+ }
2780
2831
 
2781
2832
  // src/block-diff.ts
2782
2833
  function createBlocksMap(nodes, parentId = "") {
@@ -3140,12 +3191,640 @@ function generateBlockId5() {
3140
3191
  }
3141
3192
  return id;
3142
3193
  }
3194
+
3195
+ // src/unicode.ts
3196
+ var AnnotationSet = class {
3197
+ annotations;
3198
+ constructor() {
3199
+ this.annotations = /* @__PURE__ */ new Map();
3200
+ }
3201
+ addSpan(type, attributes, start, end) {
3202
+ const id = this._annotationId(type, attributes);
3203
+ let annotation = this.annotations.get(id);
3204
+ if (!annotation) {
3205
+ const annAttrs = attributes ? { ...attributes } : {};
3206
+ let link;
3207
+ if (type == "Link" || type == "Embed") {
3208
+ link = attributes == null ? void 0 : attributes.link;
3209
+ delete annAttrs.link;
3210
+ }
3211
+ annotation = {
3212
+ type,
3213
+ attributes: annAttrs,
3214
+ link: link || "",
3215
+ starts: [],
3216
+ ends: []
3217
+ };
3218
+ this.annotations.set(id, annotation);
3219
+ }
3220
+ addSpanToAnnotation(annotation, start, end);
3221
+ }
3222
+ _annotationId(type, attributes) {
3223
+ if (attributes) {
3224
+ if (attributes.link) {
3225
+ return `${type}-${attributes.link}`;
3226
+ }
3227
+ if (attributes.href) {
3228
+ return `${type}-${attributes.href}`;
3229
+ }
3230
+ }
3231
+ return type;
3232
+ }
3233
+ list() {
3234
+ const keys = Array.from(this.annotations.keys()).sort();
3235
+ let out = new Array(keys.length);
3236
+ for (let i in keys) {
3237
+ const annotation = this.annotations.get(keys[i]);
3238
+ if (annotation) out[i] = annotation;
3239
+ }
3240
+ out = out.sort((a, b) => {
3241
+ let startA = a.starts[0];
3242
+ let startB = b.starts[0];
3243
+ return (startA || 0) - (startB || 0);
3244
+ });
3245
+ return out;
3246
+ }
3247
+ };
3248
+ function addSpanToAnnotation(annotation, start, end) {
3249
+ if (!annotation.starts) {
3250
+ annotation.starts = [];
3251
+ }
3252
+ if (!annotation.ends) {
3253
+ annotation.ends = [];
3254
+ }
3255
+ if (annotation.starts.length == 0) {
3256
+ pushSpanToAnnotation(annotation, start, end);
3257
+ return;
3258
+ }
3259
+ const lastIdx = annotation.starts.length - 1;
3260
+ if (annotation.ends[lastIdx] == start) {
3261
+ annotation.ends[lastIdx] = end;
3262
+ return;
3263
+ }
3264
+ pushSpanToAnnotation(annotation, start, end);
3265
+ }
3266
+ function pushSpanToAnnotation(annotation, start, end) {
3267
+ annotation.starts.push(start);
3268
+ annotation.ends.push(end);
3269
+ }
3270
+
3271
+ // src/editorblock-to-hmblock.ts
3272
+ function toHMBlockType(editorBlockType) {
3273
+ if (editorBlockType === "heading") return "Heading";
3274
+ if (editorBlockType === "paragraph") return "Paragraph";
3275
+ if (editorBlockType === "code-block") return "Code";
3276
+ if (editorBlockType === "math") return "Math";
3277
+ if (editorBlockType === "image") return "Image";
3278
+ if (editorBlockType === "video") return "Video";
3279
+ if (editorBlockType === "file") return "File";
3280
+ if (editorBlockType === "button") return "Button";
3281
+ if (editorBlockType === "embed") return "Embed";
3282
+ if (editorBlockType === "web-embed") return "WebEmbed";
3283
+ if (editorBlockType === "query") return "Query";
3284
+ return void 0;
3285
+ }
3286
+ function editorBlockToHMBlock(editorBlock) {
3287
+ var _a, _b, _c, _d, _e, _f;
3288
+ const blockType = toHMBlockType(editorBlock.type);
3289
+ if (!blockType) throw new Error("Unsupported block type " + editorBlock.type);
3290
+ let block = {
3291
+ id: editorBlock.id,
3292
+ type: blockType,
3293
+ attributes: {},
3294
+ text: "",
3295
+ annotations: []
3296
+ };
3297
+ let leaves = flattenLeaves(editorBlock.content);
3298
+ if (editorBlock.props.childrenType == "Group") {
3299
+ block.attributes.childrenType = "Group";
3300
+ } else if (editorBlock.props.childrenType == "Unordered") {
3301
+ block.attributes.childrenType = "Unordered";
3302
+ } else if (editorBlock.props.childrenType == "Ordered") {
3303
+ block.attributes.childrenType = "Ordered";
3304
+ } else if (editorBlock.props.childrenType == "Blockquote") {
3305
+ block.attributes.childrenType = "Blockquote";
3306
+ } else if (editorBlock.props.childrenType == "Grid") {
3307
+ block.attributes.childrenType = "Grid";
3308
+ if (editorBlock.props.columnCount) {
3309
+ block.attributes.columnCount = Number(editorBlock.props.columnCount);
3310
+ }
3311
+ }
3312
+ const annotations = new AnnotationSet();
3313
+ let pos = 0;
3314
+ for (let leaf of leaves) {
3315
+ const start = pos;
3316
+ const charCount = codePointLength(leaf.text);
3317
+ const end = start + charCount;
3318
+ if ((_a = leaf.styles) == null ? void 0 : _a.bold) {
3319
+ annotations.addSpan("Bold", null, start, end);
3320
+ }
3321
+ if ((_b = leaf.styles) == null ? void 0 : _b.italic) {
3322
+ annotations.addSpan("Italic", null, start, end);
3323
+ }
3324
+ if ((_c = leaf.styles) == null ? void 0 : _c.underline) {
3325
+ annotations.addSpan("Underline", null, start, end);
3326
+ }
3327
+ if ((_d = leaf.styles) == null ? void 0 : _d.strike) {
3328
+ annotations.addSpan("Strike", null, start, end);
3329
+ }
3330
+ if ((_e = leaf.styles) == null ? void 0 : _e.code) {
3331
+ annotations.addSpan("Code", null, start, end);
3332
+ }
3333
+ if ((_f = leaf.styles) == null ? void 0 : _f.math) {
3334
+ annotations.addSpan("Math", null, start, end);
3335
+ }
3336
+ if (leaf.type == "inline-embed") {
3337
+ annotations.addSpan("Embed", { link: leaf.link }, start, end);
3338
+ }
3339
+ if (leaf.type == "link") {
3340
+ annotations.addSpan("Link", { link: leaf.href }, start, end);
3341
+ }
3342
+ block.text += leaf.text;
3343
+ pos += charCount;
3344
+ }
3345
+ let outAnnotations = annotations.list();
3346
+ if (outAnnotations) {
3347
+ block.annotations = outAnnotations;
3348
+ }
3349
+ const blockCode = block.type === "Code" ? block : void 0;
3350
+ if (blockCode && editorBlock.type == "code-block") {
3351
+ blockCode.attributes.language = editorBlock.props.language;
3352
+ }
3353
+ const blockImage = block.type === "Image" ? block : void 0;
3354
+ if (blockImage && editorBlock.type == "image") {
3355
+ if (editorBlock.props.url && !editorBlock.props.mediaRef) {
3356
+ blockImage.link = editorBlock.props.url;
3357
+ } else if (editorBlock.props.mediaRef) {
3358
+ blockImage.link = "";
3359
+ } else if (editorBlock.props.displaySrc) {
3360
+ blockImage.link = editorBlock.props.displaySrc;
3361
+ } else if (editorBlock.props.src) {
3362
+ blockImage.link = editorBlock.props.src;
3363
+ } else {
3364
+ blockImage.link = "";
3365
+ }
3366
+ const width = toNumber(editorBlock.props.width);
3367
+ if (width) {
3368
+ blockImage.attributes.width = width;
3369
+ }
3370
+ }
3371
+ const blockVideo = block.type === "Video" ? block : void 0;
3372
+ if (blockVideo && editorBlock.type == "video") {
3373
+ blockVideo.text = "";
3374
+ if (editorBlock.props.url && !editorBlock.props.mediaRef) {
3375
+ blockVideo.link = editorBlock.props.url;
3376
+ } else if (editorBlock.props.mediaRef) {
3377
+ blockVideo.link = "";
3378
+ }
3379
+ const width = toNumber(editorBlock.props.width);
3380
+ if (width) blockVideo.attributes.width = width;
3381
+ if (editorBlock.props.name) {
3382
+ blockVideo.attributes.name = editorBlock.props.name;
3383
+ }
3384
+ }
3385
+ const blockFile = block.type === "File" ? block : void 0;
3386
+ if (blockFile && editorBlock.type == "file") {
3387
+ if (editorBlock.props.url && !editorBlock.props.mediaRef) {
3388
+ blockFile.link = editorBlock.props.url;
3389
+ } else if (editorBlock.props.mediaRef) {
3390
+ blockFile.link = "";
3391
+ }
3392
+ if (editorBlock.props.name) blockFile.attributes.name = editorBlock.props.name;
3393
+ const size = toNumber(editorBlock.props.size);
3394
+ if (size) blockFile.attributes.size = size;
3395
+ }
3396
+ const blockButton = block.type === "Button" ? block : void 0;
3397
+ if (blockButton && editorBlock.type == "button") {
3398
+ if (editorBlock.props.url) blockButton.link = editorBlock.props.url;
3399
+ if (editorBlock.props.name) blockButton.attributes.name = editorBlock.props.name;
3400
+ if (editorBlock.props.alignment)
3401
+ blockButton.attributes.alignment = HMBlockButtonAlignmentSchema.parse(editorBlock.props.alignment);
3402
+ }
3403
+ const blockWebEmbed = block.type === "WebEmbed" ? block : void 0;
3404
+ if (blockWebEmbed && editorBlock.type == "web-embed" && editorBlock.props.url) {
3405
+ blockWebEmbed.link = editorBlock.props.url;
3406
+ }
3407
+ const blockEmbed = block.type === "Embed" ? block : void 0;
3408
+ if (blockEmbed && editorBlock.type == "embed") {
3409
+ block.text = "";
3410
+ if (editorBlock.props.url) blockEmbed.link = editorBlock.props.url;
3411
+ if (editorBlock.props.view) blockEmbed.attributes.view = editorBlock.props.view;
3412
+ }
3413
+ const blockQuery = block.type === "Query" ? block : void 0;
3414
+ if (blockQuery && editorBlock.type == "query") {
3415
+ blockQuery.attributes.style = editorBlock.props.style;
3416
+ blockQuery.attributes.columnCount = Number(editorBlock.props.columnCount);
3417
+ const query = {
3418
+ includes: [],
3419
+ sort: []
3420
+ };
3421
+ if (editorBlock.props.queryIncludes) query.includes = JSON.parse(editorBlock.props.queryIncludes);
3422
+ if (editorBlock.props.querySort) query.sort = JSON.parse(editorBlock.props.querySort);
3423
+ if (editorBlock.props.queryLimit) query.limit = Number(editorBlock.props.queryLimit);
3424
+ blockQuery.attributes.query = query;
3425
+ blockQuery.attributes.banner = editorBlock.props.banner == "true";
3426
+ }
3427
+ const blockParse = HMBlockSchema.safeParse(block);
3428
+ if (blockParse.success) {
3429
+ return blockParse.data;
3430
+ }
3431
+ const failedParse = blockParse;
3432
+ console.error("Failed to validate block for writing", block, failedParse.error);
3433
+ throw new Error("Failed to validate block for writing " + JSON.stringify(failedParse.error));
3434
+ }
3435
+ function editorBlocksToHMBlockNodes(editorBlocks) {
3436
+ return editorBlocks.map((block) => {
3437
+ var _a, _b;
3438
+ try {
3439
+ return {
3440
+ block: editorBlockToHMBlock(block),
3441
+ children: ((_a = block.children) == null ? void 0 : _a.length) ? editorBlocksToHMBlockNodes(block.children) : void 0
3442
+ };
3443
+ } catch {
3444
+ return {
3445
+ block: {
3446
+ id: block.id || "unknown",
3447
+ type: "Paragraph",
3448
+ text: `[Unsupported block type: ${block.type}]`,
3449
+ annotations: [],
3450
+ attributes: {}
3451
+ },
3452
+ children: ((_b = block.children) == null ? void 0 : _b.length) ? editorBlocksToHMBlockNodes(block.children) : void 0
3453
+ };
3454
+ }
3455
+ }).filter(Boolean);
3456
+ }
3457
+ function flattenLeaves(content) {
3458
+ let result = [];
3459
+ for (let i = 0; i < content.length; i++) {
3460
+ const leaf = content[i];
3461
+ if (!leaf) continue;
3462
+ if (leaf.type == "link") {
3463
+ let nestedLeaves = flattenLeaves(leaf.content).map(
3464
+ (l) => ({
3465
+ ...l,
3466
+ href: leaf.href,
3467
+ type: "link"
3468
+ })
3469
+ );
3470
+ result.push(...nestedLeaves);
3471
+ }
3472
+ if (leaf.type == "inline-embed") {
3473
+ result.push({
3474
+ ...leaf,
3475
+ text: "\uFFFC",
3476
+ link: leaf.link
3477
+ });
3478
+ }
3479
+ if (leaf.type == "text") {
3480
+ result.push(leaf);
3481
+ }
3482
+ }
3483
+ return result;
3484
+ }
3485
+
3486
+ // src/hmblock-to-editorblock.ts
3487
+ function toEditorBlockType(hmBlockType) {
3488
+ if (hmBlockType === "Heading") return "heading";
3489
+ if (hmBlockType === "Paragraph") return "paragraph";
3490
+ if (hmBlockType === "Code") return "code-block";
3491
+ if (hmBlockType === "Math") return "math";
3492
+ if (hmBlockType === "Image") return "image";
3493
+ if (hmBlockType === "Video") return "video";
3494
+ if (hmBlockType === "File") return "file";
3495
+ if (hmBlockType === "Button") return "button";
3496
+ if (hmBlockType === "Embed") return "embed";
3497
+ if (hmBlockType === "WebEmbed") return "web-embed";
3498
+ if (hmBlockType === "Nostr") return "nostr";
3499
+ if (hmBlockType === "Query") return "query";
3500
+ return "unknown";
3501
+ }
3502
+ function hmBlocksToEditorContent(blocks, opts = { level: 1 }) {
3503
+ const childRecursiveOpts = {
3504
+ level: opts.level || 0
3505
+ };
3506
+ return blocks.map((hmBlock) => {
3507
+ var _a, _b, _c;
3508
+ let res = hmBlock.block ? hmBlockToEditorBlock(hmBlock.block) : null;
3509
+ if (res && ((_a = hmBlock.children) == null ? void 0 : _a.length)) {
3510
+ const childrenType = (_c = ((_b = hmBlock.block) == null ? void 0 : _b.attributes) || {}) == null ? void 0 : _c.childrenType;
3511
+ const validChildrenType = childrenType === "Group" || childrenType === "Ordered" || childrenType === "Unordered" || childrenType === "Blockquote" || childrenType === "Grid" ? childrenType : "Group";
3512
+ res.children = hmBlocksToEditorContent(hmBlock.children, {
3513
+ level: childRecursiveOpts.level ? childRecursiveOpts.level + 1 : 1,
3514
+ childrenType: validChildrenType
3515
+ });
3516
+ }
3517
+ return res;
3518
+ }).filter((block) => block !== null);
3519
+ }
3520
+ function hmBlockToEditorBlock(block) {
3521
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
3522
+ const blockType = toEditorBlockType(block.type);
3523
+ if (blockType === "unknown") {
3524
+ return {
3525
+ id: block.id,
3526
+ type: "unknown",
3527
+ content: [],
3528
+ props: {
3529
+ revision: block.revision,
3530
+ originalType: block.type,
3531
+ originalData: JSON.stringify(block)
3532
+ },
3533
+ children: []
3534
+ };
3535
+ }
3536
+ let out = {
3537
+ id: block.id,
3538
+ type: blockType,
3539
+ content: [],
3540
+ props: {
3541
+ revision: block.revision
3542
+ },
3543
+ children: []
3544
+ };
3545
+ const attributes = block.attributes || {};
3546
+ if ("childrenType" in attributes && attributes.childrenType) {
3547
+ const childrenType = attributes.childrenType;
3548
+ if (childrenType === "Group" || childrenType === "Ordered" || childrenType === "Unordered" || childrenType === "Blockquote" || childrenType === "Grid") {
3549
+ ;
3550
+ out.props.childrenType = childrenType;
3551
+ }
3552
+ if (childrenType === "Grid" && attributes.columnCount != null) {
3553
+ ;
3554
+ out.props.columnCount = String(attributes.columnCount);
3555
+ }
3556
+ }
3557
+ if (["code-block", "video", "image", "file", "button", "embed", "web-embed", "math", "nostr"].includes(blockType)) {
3558
+ if (block.link) {
3559
+ ;
3560
+ out.props.url = block.link;
3561
+ }
3562
+ if (blockType == "code-block") {
3563
+ out.type = "code-block";
3564
+ }
3565
+ if (block.attributes) {
3566
+ Object.entries(block.attributes).forEach(([key, value]) => {
3567
+ if (value !== void 0) {
3568
+ if (key == "width" || key == "size") {
3569
+ if (typeof value == "number") {
3570
+ ;
3571
+ out.props[key] = String(value);
3572
+ }
3573
+ } else {
3574
+ ;
3575
+ out.props[key] = value;
3576
+ }
3577
+ }
3578
+ });
3579
+ }
3580
+ }
3581
+ if (block.type === "Query") {
3582
+ const queryProps = out.props;
3583
+ queryProps.style = (_a = block.attributes) == null ? void 0 : _a.style;
3584
+ queryProps.columnCount = String(((_b = block.attributes) == null ? void 0 : _b.columnCount) || "");
3585
+ queryProps.queryIncludes = JSON.stringify(((_d = (_c = block.attributes) == null ? void 0 : _c.query) == null ? void 0 : _d.includes) || []);
3586
+ queryProps.querySort = JSON.stringify(((_f = (_e = block.attributes) == null ? void 0 : _e.query) == null ? void 0 : _f.sort) || {});
3587
+ queryProps.banner = ((_g = block.attributes) == null ? void 0 : _g.banner) ? "true" : "false";
3588
+ queryProps.queryLimit = String(((_i = (_h = block.attributes) == null ? void 0 : _h.query) == null ? void 0 : _i.limit) || "");
3589
+ }
3590
+ const blockText = block.text || "";
3591
+ const leaves = out.content;
3592
+ let leaf = null;
3593
+ let inlineBlockContent = null;
3594
+ let textStart = 0;
3595
+ let i = 0;
3596
+ const stopPoint = block.text ? block.text.length - 1 : 0;
3597
+ let pos = 0;
3598
+ const leafAnnotations = /* @__PURE__ */ new Set();
3599
+ if (blockText == "") {
3600
+ leaves.push({ type: "text", text: blockText, styles: {} });
3601
+ return out;
3602
+ }
3603
+ while (i < blockText.length) {
3604
+ let ul = 1;
3605
+ let annotationsChanged = trackPosAnnotations(pos);
3606
+ let surrogate = isSurrogate(blockText, i);
3607
+ if (surrogate) {
3608
+ ul++;
3609
+ let onlyOneSurrogate = pos + ul;
3610
+ if (onlyOneSurrogate == blockText.length) {
3611
+ if (!leaf) {
3612
+ startLeaf(leafAnnotations);
3613
+ }
3614
+ finishLeaf(textStart, i + 2);
3615
+ if (inlineBlockContent) {
3616
+ const lastLeaf = leaves[leaves.length - 1];
3617
+ if (lastLeaf && !isText(lastLeaf)) {
3618
+ }
3619
+ leaves.push(inlineBlockContent);
3620
+ inlineBlockContent = null;
3621
+ }
3622
+ return out;
3623
+ }
3624
+ }
3625
+ if (stopPoint < 0) {
3626
+ console.warn("STOP IS LESS THAN ZERO", block);
3627
+ }
3628
+ if (i == stopPoint) {
3629
+ if (annotationsChanged) {
3630
+ if (leaf) {
3631
+ finishLeaf(textStart, i);
3632
+ }
3633
+ startLeaf(leafAnnotations);
3634
+ } else {
3635
+ startLeaf(leafAnnotations);
3636
+ }
3637
+ finishLeaf(textStart, i + 1);
3638
+ if (inlineBlockContent) {
3639
+ const lastLeaf = leaves[leaves.length - 1];
3640
+ if (lastLeaf && !isText(lastLeaf)) {
3641
+ }
3642
+ leaves.push(inlineBlockContent);
3643
+ inlineBlockContent = null;
3644
+ }
3645
+ return out;
3646
+ }
3647
+ if (!leaf) {
3648
+ startLeaf(leafAnnotations);
3649
+ advance(ul);
3650
+ continue;
3651
+ }
3652
+ if (annotationsChanged) {
3653
+ finishLeaf(textStart, i);
3654
+ startLeaf(leafAnnotations);
3655
+ }
3656
+ advance(ul);
3657
+ if (i == blockText.length) {
3658
+ finishLeaf(textStart, i);
3659
+ return out;
3660
+ }
3661
+ }
3662
+ throw Error("BUG: should not get here");
3663
+ function advance(codeUnits) {
3664
+ pos++;
3665
+ i += codeUnits;
3666
+ }
3667
+ function startLeaf(posAnnotations) {
3668
+ const newLeaf = {
3669
+ type: "text",
3670
+ text: "",
3671
+ styles: {}
3672
+ };
3673
+ leaf = newLeaf;
3674
+ let linkAnnotation = null;
3675
+ for (const l of Array.from(posAnnotations)) {
3676
+ const annotationData = l;
3677
+ if (annotationData.type === "Link") {
3678
+ linkAnnotation = {
3679
+ type: "Link",
3680
+ href: annotationData.link || ""
3681
+ };
3682
+ }
3683
+ if (annotationData.type === "Embed") {
3684
+ linkAnnotation = {
3685
+ type: "Embed",
3686
+ link: annotationData.link || ""
3687
+ };
3688
+ }
3689
+ if (["Bold", "Italic", "Strike", "Underline", "Code", "Range"].includes(annotationData.type)) {
3690
+ const styleKey = annotationData.type.toLowerCase();
3691
+ newLeaf.styles[styleKey] = true;
3692
+ }
3693
+ }
3694
+ if (linkAnnotation) {
3695
+ if (linkAnnotation.type === "Embed") {
3696
+ leaves.push({
3697
+ type: "inline-embed",
3698
+ styles: {},
3699
+ link: linkAnnotation.link || ""
3700
+ });
3701
+ textStart = i + 1;
3702
+ } else if (inlineBlockContent) {
3703
+ if (linkChangedIdentity(linkAnnotation)) {
3704
+ leaves.push(inlineBlockContent);
3705
+ if (linkAnnotation.type === "Link") {
3706
+ inlineBlockContent = {
3707
+ type: "link",
3708
+ content: [],
3709
+ href: linkAnnotation.href || ""
3710
+ };
3711
+ } else {
3712
+ inlineBlockContent = {
3713
+ type: "inline-embed",
3714
+ styles: {},
3715
+ link: linkAnnotation.link || ""
3716
+ };
3717
+ }
3718
+ }
3719
+ } else {
3720
+ if (linkAnnotation.type === "Link") {
3721
+ inlineBlockContent = {
3722
+ type: "link",
3723
+ content: [],
3724
+ href: linkAnnotation.href || ""
3725
+ };
3726
+ } else {
3727
+ inlineBlockContent = {
3728
+ type: "inline-embed",
3729
+ styles: {},
3730
+ link: linkAnnotation.link || ""
3731
+ };
3732
+ }
3733
+ }
3734
+ } else {
3735
+ if (inlineBlockContent) {
3736
+ leaves.push(inlineBlockContent);
3737
+ inlineBlockContent = null;
3738
+ }
3739
+ }
3740
+ }
3741
+ function linkChangedIdentity(annotation) {
3742
+ if (!inlineBlockContent) return false;
3743
+ let currentLink = inlineBlockContent.link || inlineBlockContent.href;
3744
+ return currentLink != annotation.link && currentLink != annotation.href;
3745
+ }
3746
+ function finishLeaf(low, high) {
3747
+ let newValue = blockText.substring(low, high);
3748
+ if (leaf) leaf.text = newValue;
3749
+ textStart = high;
3750
+ if (inlineBlockContent) {
3751
+ if (leaf && inlineBlockContent.type == "link") {
3752
+ ;
3753
+ inlineBlockContent.content.push(leaf);
3754
+ } else if (inlineBlockContent.type == "inline-embed" && leaf) {
3755
+ } else if (leaf) {
3756
+ const typedLeaf = {
3757
+ type: "text",
3758
+ text: "",
3759
+ styles: leaf.styles
3760
+ };
3761
+ inlineBlockContent.content.push(typedLeaf);
3762
+ }
3763
+ } else {
3764
+ if (leaf && !(leaf.type === "text" && leaf.text === "" && Object.keys(leaf.styles).length === 0)) {
3765
+ leaves.push(leaf);
3766
+ }
3767
+ }
3768
+ }
3769
+ function trackPosAnnotations(pos2) {
3770
+ let annotationsChanged = false;
3771
+ if (!block.annotations) {
3772
+ return false;
3773
+ }
3774
+ const blockAnnotations = block.annotations;
3775
+ blockAnnotations.forEach((l) => {
3776
+ let spanIdx = annotationContains(l, pos2);
3777
+ if (spanIdx === -1) {
3778
+ if (leafAnnotations.delete(l)) {
3779
+ annotationsChanged = true;
3780
+ }
3781
+ return;
3782
+ }
3783
+ if (leafAnnotations.has(l)) {
3784
+ return;
3785
+ }
3786
+ leafAnnotations.add(l);
3787
+ annotationsChanged = true;
3788
+ });
3789
+ return annotationsChanged;
3790
+ }
3791
+ }
3792
+ function annotationContains(annotation, pos) {
3793
+ let low = 0;
3794
+ let high = annotation.starts.length - 1;
3795
+ let mid = 0;
3796
+ while (low <= high) {
3797
+ mid = Math.floor((low + high) / 2);
3798
+ const endAtMid = annotation.ends[mid];
3799
+ if (endAtMid === void 0) break;
3800
+ if (endAtMid <= pos) {
3801
+ low = mid + 1;
3802
+ } else {
3803
+ high = mid - 1;
3804
+ }
3805
+ }
3806
+ if (low == annotation.starts.length) {
3807
+ return -1;
3808
+ }
3809
+ const startAtLow = annotation.starts[low];
3810
+ const endAtLow = annotation.ends[low];
3811
+ if (startAtLow !== void 0 && endAtLow !== void 0 && startAtLow <= pos && pos < endAtLow) {
3812
+ return low;
3813
+ }
3814
+ return -1;
3815
+ }
3816
+ function isText(entry) {
3817
+ return (entry == null ? void 0 : entry.type) && entry.type == "text" && typeof entry.text == "string";
3818
+ }
3143
3819
  export {
3820
+ AnnotationSet,
3144
3821
  DEFAULT_GROBID_URL,
3145
3822
  HYPERMEDIA_SCHEME,
3146
3823
  SeedClientError,
3147
3824
  SeedNetworkError,
3148
3825
  SeedValidationError,
3826
+ addSpanToAnnotation,
3827
+ annotationContains,
3149
3828
  autoLinkChildToParent,
3150
3829
  blocksToMarkdown,
3151
3830
  codePointLength,
@@ -3170,6 +3849,9 @@ export {
3170
3849
  deleteContact,
3171
3850
  documentContainsLinkToChild,
3172
3851
  documentHasSelfQuery,
3852
+ draftFilename,
3853
+ editorBlockToHMBlock,
3854
+ editorBlocksToHMBlockNodes,
3173
3855
  embeddedPdfToBlocks,
3174
3856
  emitFrontmatter,
3175
3857
  entityQueryPathToHmIdPath,
@@ -3179,25 +3861,31 @@ export {
3179
3861
  getHMQueryString,
3180
3862
  hasFileLinks,
3181
3863
  hmBlockNodeToBlockNode,
3864
+ hmBlockToEditorBlock,
3865
+ hmBlocksToEditorContent,
3182
3866
  hmIdPathToEntityQueryPath,
3183
3867
  isGrobidAvailable,
3184
3868
  isSurrogate,
3869
+ markdownBlockNodesToHMBlockNodes,
3185
3870
  matchBlockIds,
3186
3871
  packBaseId,
3187
3872
  packHmId,
3188
3873
  parseCustomURL,
3874
+ parseDraftFilename,
3189
3875
  parseFragment,
3190
3876
  parseFrontmatter,
3191
3877
  parseInlineFormatting,
3192
3878
  parseMarkdown,
3193
3879
  pdfToBlocks,
3194
3880
  processFulltextDocument,
3881
+ pushSpanToAnnotation,
3195
3882
  resolveDocumentState,
3196
3883
  resolveFileLinksInBlocks,
3197
3884
  serializeBlockRange,
3198
3885
  shouldAutoLinkParent,
3199
3886
  signDocumentChange,
3200
3887
  signPreparedChange,
3888
+ slugify,
3201
3889
  teiToBlocks,
3202
3890
  trimTrailingEmptyBlocks,
3203
3891
  unpackHmId,