jazz-tools 0.13.10 → 0.13.11

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > jazz-tools@0.13.10 build /home/runner/_work/jazz/jazz/packages/jazz-tools
2
+ > jazz-tools@0.13.11 build /home/runner/_work/jazz/jazz/packages/jazz-tools
3
3
  > tsup && pnpm types
4
4
 
5
5
  CLI Building entry: {"index":"src/index.ts","testing":"src/testing.ts"}
@@ -9,14 +9,14 @@
9
9
  CLI Target: es2021
10
10
  CLI Cleaning output folder
11
11
  ESM Build start
12
- ESM dist/index.js 1.50 KB
12
+ ESM dist/index.js 1.48 KB
13
13
  ESM dist/testing.js 6.26 KB
14
- ESM dist/chunk-NFVKGXSH.js 128.03 KB
15
- ESM dist/index.js.map 259.00 B
14
+ ESM dist/chunk-I7NYAGLP.js 117.97 KB
15
+ ESM dist/index.js.map 258.00 B
16
16
  ESM dist/testing.js.map 12.37 KB
17
- ESM dist/chunk-NFVKGXSH.js.map 301.60 KB
18
- ESM ⚡️ Build success in 48ms
17
+ ESM dist/chunk-I7NYAGLP.js.map 276.92 KB
18
+ ESM ⚡️ Build success in 53ms
19
19
 
20
- > jazz-tools@0.13.10 types /home/runner/_work/jazz/jazz/packages/jazz-tools
20
+ > jazz-tools@0.13.11 types /home/runner/_work/jazz/jazz/packages/jazz-tools
21
21
  > tsc --outDir dist
22
22
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # jazz-tools
2
2
 
3
+ ## 0.13.11
4
+
5
+ ### Patch Changes
6
+
7
+ - 17273a6: CoRichText released
8
+ - Updated dependencies [17273a6]
9
+ - Updated dependencies [3396ed4]
10
+ - Updated dependencies [267ea4c]
11
+ - cojson@0.13.11
12
+
3
13
  ## 0.13.10
4
14
 
5
15
  ### Patch Changes
@@ -3215,6 +3215,7 @@ import {
3215
3215
  RawAccount as RawAccount7,
3216
3216
  stringifyOpID
3217
3217
  } from "cojson";
3218
+ import { calcPatch as calcPatch2 } from "fast-myers-diff";
3218
3219
  var CoPlainText = class extends String {
3219
3220
  get _owner() {
3220
3221
  return this._raw.group instanceof RawAccount7 ? Account.fromRaw(this._raw.group) : Group.fromRaw(this._raw.group);
@@ -3223,7 +3224,7 @@ var CoPlainText = class extends String {
3223
3224
  return Account.fromNode(this._raw.core.node);
3224
3225
  }
3225
3226
  constructor(options) {
3226
- super();
3227
+ super("fromRaw" in options ? options.fromRaw.toString() : options.text);
3227
3228
  let raw;
3228
3229
  if ("fromRaw" in options) {
3229
3230
  raw = options.fromRaw;
@@ -3254,6 +3255,9 @@ var CoPlainText = class extends String {
3254
3255
  [inspect]() {
3255
3256
  return this.toJSON();
3256
3257
  }
3258
+ insertBefore(idx, text) {
3259
+ this._raw.insertBefore(idx, text);
3260
+ }
3257
3261
  insertAfter(idx, text) {
3258
3262
  this._raw.insertAfter(idx, text);
3259
3263
  }
@@ -3275,6 +3279,22 @@ var CoPlainText = class extends String {
3275
3279
  static fromRaw(raw) {
3276
3280
  return new this({ fromRaw: raw });
3277
3281
  }
3282
+ /**
3283
+ * Apply text, modifying the text in place. Calculates the diff and applies it to the CoValue.
3284
+ *
3285
+ * @category Mutation
3286
+ */
3287
+ applyDiff(other) {
3288
+ const current = this._raw.toString();
3289
+ for (const [from, to, insert] of [...calcPatch2(current, other)].reverse()) {
3290
+ if (to > from) {
3291
+ this.deleteRange({ from, to });
3292
+ }
3293
+ if (insert.length > 0) {
3294
+ this.insertBefore(from, insert);
3295
+ }
3296
+ }
3297
+ }
3278
3298
  /**
3279
3299
  * Load a `CoPlainText` with a given ID, as a given account.
3280
3300
  *
@@ -3302,401 +3322,7 @@ var CoPlainText = class extends String {
3302
3322
  };
3303
3323
 
3304
3324
  // src/coValues/coRichText.ts
3305
- var Mark = class extends CoMap {
3306
- constructor() {
3307
- super(...arguments);
3308
- this.startAfter = co.json();
3309
- this.startBefore = co.json();
3310
- this.endAfter = co.json();
3311
- this.endBefore = co.json();
3312
- this.tag = co.string;
3313
- }
3314
- /**
3315
- * Validates and clamps mark positions to ensure they are in the correct order
3316
- * @returns Normalized positions or null if invalid
3317
- */
3318
- validatePositions(textLength, idxAfter, idxBefore) {
3319
- if (!textLength) {
3320
- console.error("Cannot validate positions for empty text");
3321
- return null;
3322
- }
3323
- const positions = {
3324
- startAfter: this.startAfter ? idxBefore(this.startAfter) ?? 0 : 0,
3325
- startBefore: this.startBefore ? idxAfter(this.startBefore) ?? 0 : 0,
3326
- endAfter: this.endAfter ? idxBefore(this.endAfter) ?? textLength : textLength,
3327
- endBefore: this.endBefore ? idxAfter(this.endBefore) ?? textLength : textLength
3328
- };
3329
- return {
3330
- startAfter: Math.max(0, positions.startAfter),
3331
- startBefore: Math.max(positions.startAfter + 1, positions.startBefore),
3332
- endAfter: Math.min(textLength - 1, positions.endAfter),
3333
- endBefore: Math.min(textLength, positions.endBefore)
3334
- };
3335
- }
3336
- };
3337
- var CoRichText = class extends CoMap {
3338
- constructor() {
3339
- super(...arguments);
3340
- this.text = co.ref(CoPlainText);
3341
- this.marks = co.ref(CoList.Of(co.ref(Mark)));
3342
- }
3343
- /**
3344
- * Create a CoRichText from plain text.
3345
- */
3346
- static createFromPlainText(text, options) {
3347
- return this.create(
3348
- {
3349
- text: CoPlainText.create(text, { owner: options.owner }),
3350
- marks: CoList.Of(co.ref(Mark)).create([], {
3351
- owner: options.owner
3352
- })
3353
- },
3354
- { owner: options.owner }
3355
- );
3356
- }
3357
- /**
3358
- * Create a CoRichText from plain text and a mark.
3359
- */
3360
- static createFromPlainTextAndMark(text, WrapIn, extraArgs, options) {
3361
- const richtext = this.createFromPlainText(text, options);
3362
- richtext.insertMark(0, text.length, WrapIn, extraArgs);
3363
- return richtext;
3364
- }
3365
- /**
3366
- * Insert text at a specific index.
3367
- */
3368
- insertAfter(idx, text) {
3369
- if (!this.text)
3370
- throw new Error("Cannot insert into a CoRichText without loaded text");
3371
- this.text.insertAfter(idx, text);
3372
- }
3373
- /**
3374
- * Delete a range of text.
3375
- */
3376
- deleteRange(range) {
3377
- if (!this.text)
3378
- throw new Error("Cannot delete from a CoRichText without loaded text");
3379
- this.text.deleteRange(range);
3380
- }
3381
- /**
3382
- * Get the position of a specific index.
3383
- */
3384
- posBefore(idx) {
3385
- if (!this.text)
3386
- throw new Error(
3387
- "Cannot get posBefore in a CoRichText without loaded text"
3388
- );
3389
- return this.text.posBefore(idx);
3390
- }
3391
- /**
3392
- * Get the position of a specific index.
3393
- */
3394
- posAfter(idx) {
3395
- if (!this.text)
3396
- throw new Error(
3397
- "Cannot get posAfter in a CoRichText without loaded text"
3398
- );
3399
- return this.text.posAfter(idx);
3400
- }
3401
- /**
3402
- * Get the index of a specific position.
3403
- */
3404
- idxBefore(pos) {
3405
- if (!this.text)
3406
- throw new Error(
3407
- "Cannot get idxBefore in a CoRichText without loaded text"
3408
- );
3409
- return this.text.idxBefore(pos);
3410
- }
3411
- /**
3412
- * Get the index of a specific position.
3413
- */
3414
- idxAfter(pos) {
3415
- if (!this.text)
3416
- throw new Error(
3417
- "Cannot get idxAfter in a CoRichText without loaded text"
3418
- );
3419
- return this.text.idxAfter(pos);
3420
- }
3421
- /**
3422
- * Insert a mark at a specific range.
3423
- */
3424
- insertMark(start, end, RangeClass, extraArgs, options) {
3425
- if (!this.text || !this.marks) {
3426
- throw new Error("Cannot insert a range without loaded ranges");
3427
- }
3428
- const textLength = this.length;
3429
- start = Math.max(start, 0);
3430
- end = Math.min(end, textLength);
3431
- const owner = options?.markOwner || this._owner;
3432
- if (!owner) {
3433
- throw new Error("No owner specified for mark");
3434
- }
3435
- const range = RangeClass.create(
3436
- {
3437
- ...extraArgs,
3438
- startAfter: this.posBefore(start),
3439
- startBefore: this.posAfter(start),
3440
- endAfter: this.posBefore(end),
3441
- endBefore: this.posAfter(end)
3442
- },
3443
- { owner }
3444
- );
3445
- this.marks.push(range);
3446
- }
3447
- /**
3448
- * Remove a mark at a specific range.
3449
- */
3450
- removeMark(start, end, RangeClass, options) {
3451
- if (!this.marks) {
3452
- throw new Error("Cannot remove marks without loaded marks");
3453
- }
3454
- const resolvedMarks = this.resolveMarks();
3455
- for (const mark of resolvedMarks) {
3456
- if (mark.endBefore < start || mark.startAfter > end) {
3457
- continue;
3458
- }
3459
- if (options.tag && mark.sourceMark.tag !== options.tag) {
3460
- continue;
3461
- }
3462
- const markIndex = this.marks.findIndex((m) => m === mark.sourceMark);
3463
- if (markIndex === -1) {
3464
- continue;
3465
- }
3466
- if (mark.startBefore >= start && mark.endAfter <= end) {
3467
- this.marks.splice(markIndex, 1);
3468
- continue;
3469
- }
3470
- if (mark.startBefore < start && mark.endAfter >= start && mark.endAfter <= end) {
3471
- const endAfterPos = this.posBefore(start);
3472
- const endBeforePos = this.posBefore(start);
3473
- if (endAfterPos && endBeforePos) {
3474
- mark.sourceMark.endAfter = endAfterPos;
3475
- mark.sourceMark.endBefore = endBeforePos;
3476
- }
3477
- continue;
3478
- }
3479
- if (mark.startBefore >= start && mark.startBefore <= end && mark.endAfter > end) {
3480
- const startAfterPos = this.posAfter(end);
3481
- const startBeforePos = this.posAfter(end);
3482
- if (startAfterPos && startBeforePos) {
3483
- mark.sourceMark.startAfter = startAfterPos;
3484
- mark.sourceMark.startBefore = startBeforePos;
3485
- }
3486
- continue;
3487
- }
3488
- if (mark.startBefore <= start && mark.endAfter >= end) {
3489
- const endAfterPos = this.posBefore(start);
3490
- const endBeforePos = this.posBefore(start);
3491
- if (endAfterPos && endBeforePos) {
3492
- mark.sourceMark.endAfter = endAfterPos;
3493
- mark.sourceMark.endBefore = endBeforePos;
3494
- }
3495
- this.insertMark(
3496
- end + 1,
3497
- mark.endBefore,
3498
- RangeClass,
3499
- // @ts-ignore Some Typescript versions flag this as an error
3500
- {},
3501
- {
3502
- markOwner: mark.sourceMark._owner || this._owner
3503
- }
3504
- );
3505
- continue;
3506
- }
3507
- }
3508
- }
3509
- /**
3510
- * Resolve the positions of all marks.
3511
- */
3512
- resolveMarks() {
3513
- if (!this.text || !this.marks) {
3514
- throw new Error("Cannot resolve ranges without loaded text and ranges");
3515
- }
3516
- const textLength = this.length;
3517
- return this.marks.flatMap((mark) => {
3518
- if (!mark) return [];
3519
- const positions = mark.validatePositions(
3520
- textLength,
3521
- (pos) => this.idxAfter(pos),
3522
- (pos) => this.idxBefore(pos)
3523
- );
3524
- if (!positions) return [];
3525
- return [
3526
- {
3527
- sourceMark: mark,
3528
- ...positions,
3529
- tag: mark.tag
3530
- }
3531
- ];
3532
- });
3533
- }
3534
- /**
3535
- * Resolve and diffuse the positions of all marks.
3536
- */
3537
- resolveAndDiffuseMarks() {
3538
- return this.resolveMarks().flatMap((range) => [
3539
- ...range.startAfter < range.startBefore - 1 ? [
3540
- {
3541
- start: range.startAfter,
3542
- end: range.startBefore - 1,
3543
- side: "uncertainStart",
3544
- sourceMark: range.sourceMark
3545
- }
3546
- ] : [],
3547
- {
3548
- start: range.startBefore - 1,
3549
- end: range.endAfter + 1,
3550
- side: "certainMiddle",
3551
- sourceMark: range.sourceMark
3552
- },
3553
- ...range.endAfter + 1 < range.endBefore ? [
3554
- {
3555
- start: range.endAfter + 1,
3556
- end: range.endBefore,
3557
- side: "uncertainEnd",
3558
- sourceMark: range.sourceMark
3559
- }
3560
- ] : []
3561
- ]);
3562
- }
3563
- /**
3564
- * Resolve, diffuse, and focus the positions of all marks.
3565
- */
3566
- resolveAndDiffuseAndFocusMarks() {
3567
- return this.resolveAndDiffuseMarks().filter(
3568
- (range) => range.side === "certainMiddle"
3569
- );
3570
- }
3571
- /**
3572
- * Convert a CoRichText to a tree structure useful for client libraries.
3573
- */
3574
- toTree(tagPrecedence) {
3575
- const ranges = this.resolveAndDiffuseAndFocusMarks();
3576
- const text = this.text?.toString() || "";
3577
- let currentNodes = [
3578
- {
3579
- type: "leaf",
3580
- start: 0,
3581
- end: text.length
3582
- }
3583
- ];
3584
- const rangesSortedLowToHighPrecedence = ranges.sort((a, b) => {
3585
- const aPrecedence = tagPrecedence.indexOf(a.sourceMark.tag);
3586
- const bPrecedence = tagPrecedence.indexOf(b.sourceMark.tag);
3587
- return bPrecedence - aPrecedence;
3588
- });
3589
- for (const range of rangesSortedLowToHighPrecedence) {
3590
- const newNodes = currentNodes.flatMap((node) => {
3591
- const [before, inOrAfter] = splitNode(node, range.start);
3592
- const [inside, after] = inOrAfter ? splitNode(inOrAfter, range.end) : [void 0, void 0];
3593
- return [
3594
- ...before ? [before] : [],
3595
- ...inside ? [
3596
- {
3597
- type: "node",
3598
- tag: range.sourceMark.tag,
3599
- start: inside.start,
3600
- end: inside.end,
3601
- children: [inside]
3602
- }
3603
- ] : [],
3604
- ...after ? [after] : []
3605
- ];
3606
- });
3607
- currentNodes = newNodes;
3608
- }
3609
- return {
3610
- type: "node",
3611
- tag: "root",
3612
- start: 0,
3613
- end: text.length,
3614
- children: currentNodes
3615
- };
3616
- }
3617
- get length() {
3618
- return this.text?.toString().length || 0;
3619
- }
3620
- /**
3621
- * Convert a CoRichText to plain text.
3622
- */
3623
- toString() {
3624
- if (!this.text) return "";
3625
- return this.text.toString();
3626
- }
3627
- };
3628
- function splitNode(node, at) {
3629
- if (node.type === "leaf") {
3630
- return [
3631
- at > node.start ? {
3632
- type: "leaf",
3633
- start: node.start,
3634
- end: Math.min(at, node.end)
3635
- } : void 0,
3636
- at < node.end ? {
3637
- type: "leaf",
3638
- start: Math.max(at, node.start),
3639
- end: node.end
3640
- } : void 0
3641
- ];
3642
- } else {
3643
- const children = node.children;
3644
- return [
3645
- at > node.start ? {
3646
- type: "node",
3647
- tag: node.tag,
3648
- start: node.start,
3649
- end: Math.min(at, node.end),
3650
- children: children.map((child) => splitNode(child, at)[0]).filter((c) => !!c)
3651
- } : void 0,
3652
- at < node.end ? {
3653
- type: "node",
3654
- tag: node.tag,
3655
- start: Math.max(at, node.start),
3656
- end: node.end,
3657
- children: children.map((child) => splitNode(child, at)[1]).filter((c) => !!c)
3658
- } : void 0
3659
- ];
3660
- }
3661
- }
3662
- var Heading = class extends Mark {
3663
- constructor() {
3664
- super(...arguments);
3665
- this.tag = co.literal("heading");
3666
- this.level = co.number;
3667
- }
3668
- };
3669
- var Paragraph = class extends Mark {
3670
- constructor() {
3671
- super(...arguments);
3672
- this.tag = co.literal("paragraph");
3673
- }
3674
- };
3675
- var Link = class extends Mark {
3676
- constructor() {
3677
- super(...arguments);
3678
- this.tag = co.literal("link");
3679
- this.url = co.string;
3680
- }
3681
- };
3682
- var Strong = class extends Mark {
3683
- constructor() {
3684
- super(...arguments);
3685
- this.tag = co.literal("strong");
3686
- }
3687
- };
3688
- var Em = class extends Mark {
3689
- constructor() {
3690
- super(...arguments);
3691
- this.tag = co.literal("em");
3692
- }
3693
- };
3694
- var Marks = {
3695
- Heading,
3696
- Paragraph,
3697
- Link,
3698
- Strong,
3699
- Em
3325
+ var CoRichText = class extends CoPlainText {
3700
3326
  };
3701
3327
 
3702
3328
  // src/coValues/extensions/imageDef.ts
@@ -4442,7 +4068,6 @@ export {
4442
4068
  Group,
4443
4069
  CoPlainText,
4444
4070
  CoRichText,
4445
- Marks,
4446
4071
  ImageDefinition,
4447
4072
  SchemaUnion,
4448
4073
  KvStoreContext,
@@ -4456,4 +4081,4 @@ export {
4456
4081
  consumeInviteLink
4457
4082
  };
4458
4083
  /* istanbul ignore file -- @preserve */
4459
- //# sourceMappingURL=chunk-NFVKGXSH.js.map
4084
+ //# sourceMappingURL=chunk-I7NYAGLP.js.map