jazz-tools 0.9.8 → 0.9.9

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.9.8 build /home/runner/work/jazz/jazz/packages/jazz-tools
2
+ > jazz-tools@0.9.9 build /home/runner/work/jazz/jazz/packages/jazz-tools
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: {"index.web":"src/index.web.ts","index.native":"src/index.native.ts","testing":"src/testing.ts"}
@@ -9,12 +9,12 @@
9
9
  CLI Target: es2021
10
10
  CLI Cleaning output folder
11
11
  ESM Build start
12
- ESM dist/index.web.js 1.15 KB
13
12
  ESM dist/index.native.js 1.14 KB
14
13
  ESM dist/testing.js 2.30 KB
15
- ESM dist/chunk-YD32FKHW.js 93.48 KB
16
- ESM dist/index.web.js.map 273.00 B
17
- ESM dist/index.native.js.map 283.00 B
14
+ ESM dist/chunk-VQZOWIPU.js 96.39 KB
18
15
  ESM dist/testing.js.map 4.89 KB
19
- ESM dist/chunk-YD32FKHW.js.map 231.35 KB
20
- ESM ⚡️ Build success in 115ms
16
+ ESM dist/index.web.js 1.15 KB
17
+ ESM dist/index.native.js.map 283.00 B
18
+ ESM dist/chunk-VQZOWIPU.js.map 238.27 KB
19
+ ESM dist/index.web.js.map 273.00 B
20
+ ESM ⚡️ Build success in 83ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # jazz-tools
2
2
 
3
+ ## 0.9.9
4
+
5
+ ### Patch Changes
6
+
7
+ - 8eb9247: Add CoRichText support
8
+ - Updated dependencies [8eb9247]
9
+ - cojson@0.9.9
10
+
3
11
  ## 0.9.8
4
12
 
5
13
  ### Patch Changes
@@ -36,13 +36,61 @@ var AnonymousJazzAgent = class {
36
36
  // src/coValues/interfaces.ts
37
37
  import { RawAccount as RawAccount2 } from "cojson";
38
38
 
39
+ // src/implementation/inspect.ts
40
+ var inspect = Symbol.for("nodejs.util.inspect.custom");
41
+
39
42
  // src/implementation/symbols.ts
40
43
  var SchemaInit = Symbol.for("SchemaInit");
41
44
  var ItemsSym = Symbol.for("items");
42
45
  var MembersSym = Symbol.for("members");
43
46
 
44
- // src/implementation/inspect.ts
45
- var inspect = Symbol.for("nodejs.util.inspect.custom");
47
+ // src/coValues/deepLoading.ts
48
+ function fulfillsDepth(depth, value) {
49
+ if (value._type === "CoMap" || value._type === "Group" || value._type === "Account") {
50
+ if (Array.isArray(depth) && depth.length === 1) {
51
+ return Object.entries(value).every(([key, item]) => {
52
+ return value._refs[key] ? item && fulfillsDepth(depth[0], item) : value._schema[ItemsSym].optional;
53
+ });
54
+ } else {
55
+ for (const key of Object.keys(depth)) {
56
+ const map = value;
57
+ if (!map._refs[key] && map._schema[key].optional) {
58
+ continue;
59
+ }
60
+ if (!map[key]) {
61
+ return false;
62
+ }
63
+ if (!fulfillsDepth(depth[key], map[key])) {
64
+ return false;
65
+ }
66
+ }
67
+ return true;
68
+ }
69
+ } else if (value._type === "CoList") {
70
+ if (depth.length === 0) {
71
+ return true;
72
+ } else {
73
+ const itemDepth = depth[0];
74
+ return value.every(
75
+ (item, i) => value._refs[i] ? item && fulfillsDepth(itemDepth, item) : value._schema[ItemsSym].optional
76
+ );
77
+ }
78
+ } else if (value._type === "CoStream") {
79
+ if (depth.length === 0) {
80
+ return true;
81
+ } else {
82
+ const itemDepth = depth[0];
83
+ return Object.values(value.perSession).every(
84
+ (entry) => entry.ref ? entry.value && fulfillsDepth(itemDepth, entry.value) : value._schema[ItemsSym].optional
85
+ );
86
+ }
87
+ } else if (value._type === "BinaryCoStream" || value._type === "CoPlainText") {
88
+ return true;
89
+ } else {
90
+ console.error(value);
91
+ throw new Error("Unexpected value type: " + value._type);
92
+ }
93
+ }
46
94
 
47
95
  // src/lib/cache.ts
48
96
  var weakMap = /* @__PURE__ */ new WeakMap();
@@ -356,54 +404,6 @@ var SubscriptionScope = class {
356
404
  }
357
405
  };
358
406
 
359
- // src/coValues/deepLoading.ts
360
- function fulfillsDepth(depth, value) {
361
- if (value._type === "CoMap" || value._type === "Group" || value._type === "Account") {
362
- if (Array.isArray(depth) && depth.length === 1) {
363
- return Object.entries(value).every(([key, item]) => {
364
- return value._refs[key] ? item && fulfillsDepth(depth[0], item) : value._schema[ItemsSym].optional;
365
- });
366
- } else {
367
- for (const key of Object.keys(depth)) {
368
- const map = value;
369
- if (!map._refs[key] && map._schema[key].optional) {
370
- continue;
371
- }
372
- if (!map[key]) {
373
- return false;
374
- }
375
- if (!fulfillsDepth(depth[key], map[key])) {
376
- return false;
377
- }
378
- }
379
- return true;
380
- }
381
- } else if (value._type === "CoList") {
382
- if (depth.length === 0) {
383
- return true;
384
- } else {
385
- const itemDepth = depth[0];
386
- return value.every(
387
- (item, i) => value._refs[i] ? item && fulfillsDepth(itemDepth, item) : value._schema[ItemsSym].optional
388
- );
389
- }
390
- } else if (value._type === "CoStream") {
391
- if (depth.length === 0) {
392
- return true;
393
- } else {
394
- const itemDepth = depth[0];
395
- return Object.values(value.perSession).every(
396
- (entry) => entry.ref ? entry.value && fulfillsDepth(itemDepth, entry.value) : value._schema[ItemsSym].optional
397
- );
398
- }
399
- } else if (value._type === "BinaryCoStream" || value._type === "CoPlainText") {
400
- return true;
401
- } else {
402
- console.error(value);
403
- throw new Error("Unexpected value type: " + value._type);
404
- }
405
- }
406
-
407
407
  // src/implementation/createContext.ts
408
408
  import {
409
409
  ControlledAgent,
@@ -2798,6 +2798,9 @@ var CoPlainText = class extends String {
2798
2798
  static create(text, options) {
2799
2799
  return new this({ text, owner: options.owner });
2800
2800
  }
2801
+ get length() {
2802
+ return this._raw.toString().length;
2803
+ }
2801
2804
  toString() {
2802
2805
  return this._raw.toString();
2803
2806
  }
@@ -2881,9 +2884,9 @@ var CoPlainText = class extends String {
2881
2884
  // return subscribeToCoValueEf(this, id, []);
2882
2885
  // }
2883
2886
  /**
2884
- * Given an already loaded `CoMap`, subscribe to updates to the `CoMap` and ensure that the specified fields are loaded to the specified depth.
2887
+ * Given an already loaded `CoPlainText`, subscribe to updates to the `CoPlainText` and ensure that the specified fields are loaded to the specified depth.
2885
2888
  *
2886
- * Works like `CoMap.subscribe()`, but you don't need to pass the ID or the account to load as again.
2889
+ * Works like `CoPlainText.subscribe()`, but you don't need to pass the ID or the account to load as again.
2887
2890
  *
2888
2891
  * Returns an unsubscribe function that you should call when you no longer need updates.
2889
2892
  *
@@ -2904,6 +2907,28 @@ var Mark = class extends CoMap {
2904
2907
  this.endBefore = co.json();
2905
2908
  this.tag = co.string;
2906
2909
  }
2910
+ /**
2911
+ * Validates and clamps mark positions to ensure they are in the correct order
2912
+ * @returns Normalized positions or null if invalid
2913
+ */
2914
+ validatePositions(textLength, idxAfter, idxBefore) {
2915
+ if (!textLength) {
2916
+ console.error("Cannot validate positions for empty text");
2917
+ return null;
2918
+ }
2919
+ const positions = {
2920
+ startAfter: this.startAfter ? idxBefore(this.startAfter) ?? 0 : 0,
2921
+ startBefore: this.startBefore ? idxAfter(this.startBefore) ?? 0 : 0,
2922
+ endAfter: this.endAfter ? idxBefore(this.endAfter) ?? textLength : textLength,
2923
+ endBefore: this.endBefore ? idxAfter(this.endBefore) ?? textLength : textLength
2924
+ };
2925
+ return {
2926
+ startAfter: Math.max(0, positions.startAfter),
2927
+ startBefore: Math.max(positions.startAfter + 1, positions.startBefore),
2928
+ endAfter: Math.min(textLength - 1, positions.endAfter),
2929
+ endBefore: Math.min(textLength, positions.endBefore)
2930
+ };
2931
+ }
2907
2932
  };
2908
2933
  var CoRichText = class extends CoMap {
2909
2934
  constructor() {
@@ -2993,9 +3018,16 @@ var CoRichText = class extends CoMap {
2993
3018
  * Insert a mark at a specific range.
2994
3019
  */
2995
3020
  insertMark(start, end, RangeClass, extraArgs, options) {
2996
- if (!this.marks) {
3021
+ if (!this.text || !this.marks) {
2997
3022
  throw new Error("Cannot insert a range without loaded ranges");
2998
3023
  }
3024
+ const textLength = this.length;
3025
+ start = Math.max(start, 0);
3026
+ end = Math.min(end, textLength);
3027
+ const owner = options?.markOwner || this._owner;
3028
+ if (!owner) {
3029
+ throw new Error("No owner specified for mark");
3030
+ }
2999
3031
  const range = RangeClass.create(
3000
3032
  {
3001
3033
  ...extraArgs,
@@ -3004,10 +3036,71 @@ var CoRichText = class extends CoMap {
3004
3036
  endAfter: this.posBefore(end),
3005
3037
  endBefore: this.posAfter(end)
3006
3038
  },
3007
- { owner: options?.markOwner || this._owner }
3039
+ { owner }
3008
3040
  );
3009
3041
  this.marks.push(range);
3010
3042
  }
3043
+ /**
3044
+ * Remove a mark at a specific range.
3045
+ */
3046
+ removeMark(start, end, RangeClass, options) {
3047
+ if (!this.marks) {
3048
+ throw new Error("Cannot remove marks without loaded marks");
3049
+ }
3050
+ const resolvedMarks = this.resolveMarks();
3051
+ for (const mark of resolvedMarks) {
3052
+ if (mark.endBefore < start || mark.startAfter > end) {
3053
+ continue;
3054
+ }
3055
+ if (options.tag && mark.sourceMark.tag !== options.tag) {
3056
+ continue;
3057
+ }
3058
+ const markIndex = this.marks.findIndex((m) => m === mark.sourceMark);
3059
+ if (markIndex === -1) {
3060
+ continue;
3061
+ }
3062
+ if (mark.startBefore >= start && mark.endAfter <= end) {
3063
+ this.marks.splice(markIndex, 1);
3064
+ continue;
3065
+ }
3066
+ if (mark.startBefore < start && mark.endAfter >= start && mark.endAfter <= end) {
3067
+ const endAfterPos = this.posBefore(start);
3068
+ const endBeforePos = this.posBefore(start);
3069
+ if (endAfterPos && endBeforePos) {
3070
+ mark.sourceMark.endAfter = endAfterPos;
3071
+ mark.sourceMark.endBefore = endBeforePos;
3072
+ }
3073
+ continue;
3074
+ }
3075
+ if (mark.startBefore >= start && mark.startBefore <= end && mark.endAfter > end) {
3076
+ const startAfterPos = this.posAfter(end);
3077
+ const startBeforePos = this.posAfter(end);
3078
+ if (startAfterPos && startBeforePos) {
3079
+ mark.sourceMark.startAfter = startAfterPos;
3080
+ mark.sourceMark.startBefore = startBeforePos;
3081
+ }
3082
+ continue;
3083
+ }
3084
+ if (mark.startBefore <= start && mark.endAfter >= end) {
3085
+ const endAfterPos = this.posBefore(start);
3086
+ const endBeforePos = this.posBefore(start);
3087
+ if (endAfterPos && endBeforePos) {
3088
+ mark.sourceMark.endAfter = endAfterPos;
3089
+ mark.sourceMark.endBefore = endBeforePos;
3090
+ }
3091
+ this.insertMark(
3092
+ end + 1,
3093
+ mark.endBefore,
3094
+ RangeClass,
3095
+ {},
3096
+ {
3097
+ markOwner: mark.sourceMark._owner || this._owner
3098
+ }
3099
+ );
3100
+ continue;
3101
+ }
3102
+ }
3103
+ }
3011
3104
  /**
3012
3105
  * Resolve the positions of all marks.
3013
3106
  */
@@ -3015,31 +3108,23 @@ var CoRichText = class extends CoMap {
3015
3108
  if (!this.text || !this.marks) {
3016
3109
  throw new Error("Cannot resolve ranges without loaded text and ranges");
3017
3110
  }
3018
- const ranges = this.marks.flatMap((mark) => {
3111
+ const textLength = this.length;
3112
+ return this.marks.flatMap((mark) => {
3019
3113
  if (!mark) return [];
3020
- const startBefore = this.idxAfter(mark.startBefore);
3021
- const endAfter = this.idxAfter(mark.endAfter);
3022
- if (startBefore === void 0 || endAfter === void 0) {
3023
- return [];
3024
- }
3025
- const startAfter = mark.startAfter ? this.idxAfter(mark.startAfter) : startBefore - 1;
3026
- const endBefore = mark.endBefore ? this.idxAfter(mark.endBefore) : endAfter + 1;
3027
- if (startAfter === void 0 || endBefore === void 0) {
3028
- return [];
3029
- }
3114
+ const positions = mark.validatePositions(
3115
+ textLength,
3116
+ (pos) => this.idxAfter(pos),
3117
+ (pos) => this.idxBefore(pos)
3118
+ );
3119
+ if (!positions) return [];
3030
3120
  return [
3031
3121
  {
3032
3122
  sourceMark: mark,
3033
- startAfter,
3034
- startBefore,
3035
- endAfter,
3036
- endBefore,
3037
- tag: mark.tag,
3038
- from: mark
3123
+ ...positions,
3124
+ tag: mark.tag
3039
3125
  }
3040
3126
  ];
3041
3127
  });
3042
- return ranges;
3043
3128
  }
3044
3129
  /**
3045
3130
  * Resolve and diffuse the positions of all marks.
@@ -3124,6 +3209,9 @@ var CoRichText = class extends CoMap {
3124
3209
  children: currentNodes
3125
3210
  };
3126
3211
  }
3212
+ get length() {
3213
+ return this.text?.toString().length || 0;
3214
+ }
3127
3215
  /**
3128
3216
  * Convert a CoRichText to plain text.
3129
3217
  */
@@ -3329,4 +3417,4 @@ export {
3329
3417
  SchemaUnion
3330
3418
  };
3331
3419
  /* istanbul ignore file -- @preserve */
3332
- //# sourceMappingURL=chunk-YD32FKHW.js.map
3420
+ //# sourceMappingURL=chunk-VQZOWIPU.js.map