@dxos/react-ui-editor 0.3.11-main.55b2292 → 0.3.11-main.56ff0ac

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.
Files changed (72) hide show
  1. package/dist/lib/browser/index.mjs +108 -283
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/TextEditor/TextEditor.d.ts +2 -2
  5. package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
  6. package/dist/types/src/extensions/awareness.d.ts +1 -3
  7. package/dist/types/src/extensions/awareness.d.ts.map +1 -1
  8. package/dist/types/src/extensions/basic.d.ts +2 -2
  9. package/dist/types/src/extensions/basic.d.ts.map +1 -1
  10. package/dist/types/src/extensions/comments.d.ts +3 -3
  11. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  12. package/dist/types/src/extensions/index.d.ts +0 -1
  13. package/dist/types/src/extensions/index.d.ts.map +1 -1
  14. package/dist/types/src/hooks/awareness-provider.d.ts +7 -4
  15. package/dist/types/src/hooks/awareness-provider.d.ts.map +1 -1
  16. package/dist/types/src/hooks/defs.d.ts +1 -4
  17. package/dist/types/src/hooks/defs.d.ts.map +1 -1
  18. package/dist/types/src/hooks/index.d.ts +1 -2
  19. package/dist/types/src/hooks/index.d.ts.map +1 -1
  20. package/dist/types/src/hooks/useTextEditor.d.ts +17 -0
  21. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -0
  22. package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
  23. package/package.json +24 -27
  24. package/src/components/TextEditor/MarkdownEditor.stories.tsx +1 -1
  25. package/src/components/TextEditor/TextEditor.tsx +11 -14
  26. package/src/components/TextEditor/comments.stories.tsx +5 -5
  27. package/src/extensions/awareness.ts +14 -31
  28. package/src/extensions/basic.ts +3 -3
  29. package/src/extensions/comments.ts +15 -15
  30. package/src/extensions/index.ts +0 -1
  31. package/src/hooks/awareness-provider.ts +24 -20
  32. package/src/hooks/defs.ts +1 -6
  33. package/src/hooks/index.ts +1 -2
  34. package/src/hooks/useTextEditor.ts +29 -0
  35. package/src/hooks/useTextModel.ts +46 -12
  36. package/dist/types/src/components/TextEditor/codemirror.stories.d.ts +0 -12
  37. package/dist/types/src/components/TextEditor/codemirror.stories.d.ts.map +0 -1
  38. package/dist/types/src/components/TextEditor/yjs.stories.d.ts +0 -12
  39. package/dist/types/src/components/TextEditor/yjs.stories.d.ts.map +0 -1
  40. package/dist/types/src/extensions/yjs/cursor.d.ts +0 -4
  41. package/dist/types/src/extensions/yjs/cursor.d.ts.map +0 -1
  42. package/dist/types/src/extensions/yjs/index.d.ts +0 -2
  43. package/dist/types/src/extensions/yjs/index.d.ts.map +0 -1
  44. package/dist/types/src/extensions/yjs/yjs.d.ts +0 -4
  45. package/dist/types/src/extensions/yjs/yjs.d.ts.map +0 -1
  46. package/dist/types/src/extensions/yjs/yjs.test.d.ts +0 -2
  47. package/dist/types/src/extensions/yjs/yjs.test.d.ts.map +0 -1
  48. package/dist/types/src/hooks/automerge.d.ts +0 -4
  49. package/dist/types/src/hooks/automerge.d.ts.map +0 -1
  50. package/dist/types/src/hooks/yjs.d.ts +0 -28
  51. package/dist/types/src/hooks/yjs.d.ts.map +0 -1
  52. package/dist/types/src/testing/index.d.ts +0 -3
  53. package/dist/types/src/testing/index.d.ts.map +0 -1
  54. package/dist/types/src/testing/proto/gen/schema.d.ts +0 -15
  55. package/dist/types/src/testing/proto/gen/schema.d.ts.map +0 -1
  56. package/dist/types/src/testing/proto/index.d.ts +0 -2
  57. package/dist/types/src/testing/proto/index.d.ts.map +0 -1
  58. package/dist/types/src/testing/replicator.d.ts +0 -45
  59. package/dist/types/src/testing/replicator.d.ts.map +0 -1
  60. package/src/components/TextEditor/codemirror.stories.ts +0 -115
  61. package/src/components/TextEditor/yjs.stories.tsx +0 -56
  62. package/src/extensions/yjs/cursor.ts +0 -22
  63. package/src/extensions/yjs/index.ts +0 -5
  64. package/src/extensions/yjs/yjs.test.ts +0 -35
  65. package/src/extensions/yjs/yjs.ts +0 -16
  66. package/src/hooks/automerge.ts +0 -53
  67. package/src/hooks/yjs.ts +0 -157
  68. package/src/testing/index.ts +0 -6
  69. package/src/testing/proto/gen/schema.ts +0 -49
  70. package/src/testing/proto/index.ts +0 -5
  71. package/src/testing/proto/schema.proto +0 -15
  72. package/src/testing/replicator.ts +0 -184
@@ -11,10 +11,10 @@ import { EditorView as EditorView13 } from "@codemirror/view";
11
11
  import { useFocusableGroup } from "@fluentui/react-tabster";
12
12
  import { vim } from "@replit/codemirror-vim";
13
13
  import defaultsDeep2 from "lodash.defaultsdeep";
14
- import React, { forwardRef, useCallback, useEffect as useEffect3, useImperativeHandle, useRef, useState } from "react";
14
+ import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState } from "react";
15
15
  import { log as log2 } from "@dxos/log";
16
- import { useThemeContext as useThemeContext2 } from "@dxos/react-ui";
17
- import { inputSurface, mx as mx3 } from "@dxos/react-ui-theme";
16
+ import { useThemeContext } from "@dxos/react-ui";
17
+ import { attentionSurface, mx as mx3 } from "@dxos/react-ui-theme";
18
18
 
19
19
  // packages/ui/react-ui-editor/src/extensions/autocomplete.ts
20
20
  import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
@@ -293,9 +293,9 @@ var Cursor = class _Cursor {
293
293
  }
294
294
  static {
295
295
  this.getCursorFromRange = (state, range) => {
296
- const cursorConverter3 = state.facet(_Cursor.converter);
297
- const from = cursorConverter3.toCursor(range.from);
298
- const to = cursorConverter3.toCursor(range.to, -1);
296
+ const cursorConverter2 = state.facet(_Cursor.converter);
297
+ const from = cursorConverter2.toCursor(range.from);
298
+ const to = cursorConverter2.toCursor(range.to, -1);
299
299
  return [
300
300
  from,
301
301
  to
@@ -304,10 +304,10 @@ var Cursor = class _Cursor {
304
304
  }
305
305
  static {
306
306
  this.getRangeFromCursor = (state, cursor) => {
307
- const cursorConverter3 = state.facet(_Cursor.converter);
307
+ const cursorConverter2 = state.facet(_Cursor.converter);
308
308
  const parts = cursor.split(":");
309
- const from = cursorConverter3.fromCursor(parts[0]);
310
- const to = cursorConverter3.fromCursor(parts[1]);
309
+ const from = cursorConverter2.fromCursor(parts[0]);
310
+ const to = cursorConverter2.fromCursor(parts[1]);
311
311
  return from !== void 0 && to !== void 0 ? {
312
312
  from,
313
313
  to
@@ -386,21 +386,17 @@ var automerge3 = ({ handle, path }) => {
386
386
  // packages/ui/react-ui-editor/src/extensions/awareness.ts
387
387
  import { Annotation as Annotation2, Facet as Facet2, RangeSet } from "@codemirror/state";
388
388
  import { Decoration, EditorView as EditorView2, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
389
- import { useEffect } from "react";
390
389
  import { Event } from "@dxos/async";
391
390
  import { Context } from "@dxos/context";
392
- import { generateName } from "@dxos/display-name";
393
- import { useThemeContext } from "@dxos/react-ui";
394
- import { getColorForValue } from "@dxos/react-ui-theme";
395
391
  var dummyProvider = {
396
392
  remoteStateChange: new Event(),
397
393
  open: () => {
398
394
  },
399
395
  close: () => {
400
396
  },
397
+ getRemoteStates: () => [],
401
398
  update: () => {
402
- },
403
- getRemoteStates: () => []
399
+ }
404
400
  };
405
401
  var AwarenessProvider = Facet2.define({
406
402
  combine: (providers) => providers[0] ?? dummyProvider
@@ -415,29 +411,6 @@ var awareness = (provider = dummyProvider) => {
415
411
  styles
416
412
  ];
417
413
  };
418
- var useAwareness = ({ awareness: awareness2, peer }) => {
419
- const { themeMode } = useThemeContext();
420
- useEffect(() => {
421
- if (awareness2 && peer) {
422
- awareness2.setLocalStateField("user", {
423
- name: peer.name ?? generateName(peer.id),
424
- color: getColorForValue({
425
- value: peer.id,
426
- type: "color"
427
- }),
428
- colorLight: getColorForValue({
429
- value: peer.id,
430
- themeMode,
431
- type: "highlight"
432
- })
433
- });
434
- }
435
- }, [
436
- awareness2,
437
- peer,
438
- themeMode
439
- ]);
440
- };
441
414
  var RemoteSelectionsDecorator = class {
442
415
  constructor(view) {
443
416
  this.decorations = RangeSet.of([]);
@@ -599,39 +572,41 @@ var styles = EditorView2.baseTheme({
599
572
  marginLeft: "-1px",
600
573
  marginRight: "-1px",
601
574
  boxSizing: "border-box",
602
- display: "inline"
575
+ display: "inline",
576
+ cursor: "pointer"
603
577
  },
604
578
  ".cm-collab-selectionCaretDot": {
605
579
  borderRadius: "50%",
606
580
  position: "absolute",
607
- width: ".4em",
608
- height: ".4em",
609
- top: "-.2em",
610
- left: "-.2em",
581
+ width: ".5em",
582
+ height: ".5em",
583
+ top: "-.25em",
584
+ left: "-.25em",
611
585
  backgroundColor: "inherit",
612
586
  transition: "transform .3s ease-in-out",
613
587
  boxSizing: "border-box"
614
588
  },
615
589
  ".cm-collab-selectionCaret:hover > .cm-collab-selectionCaretDot": {
616
- transformOrigin: "bottom center",
617
- transform: "scale(0)"
590
+ transform: "scale(0)",
591
+ transformOrigin: "center"
618
592
  },
619
593
  ".cm-collab-selectionInfo": {
620
594
  position: "absolute",
621
- top: "-1.05em",
622
- left: "-1px",
595
+ transform: "translate(-50%, 0)",
596
+ top: "-20px",
597
+ left: 0,
623
598
  fontSize: ".75em",
624
- fontFamily: "serif",
599
+ fontFamily: "sans-serif",
625
600
  fontStyle: "normal",
626
601
  fontWeight: "normal",
627
602
  lineHeight: "normal",
628
603
  userSelect: "none",
629
604
  color: "white",
630
- paddingLeft: "2px",
631
- paddingRight: "2px",
605
+ padding: "2px",
632
606
  zIndex: 101,
633
607
  transition: "opacity .3s ease-in-out",
634
608
  backgroundColor: "inherit",
609
+ borderRadius: "2px",
635
610
  // These should be separate.
636
611
  opacity: 0,
637
612
  transitionDelay: "0s",
@@ -649,8 +624,8 @@ import { history } from "@codemirror/commands";
649
624
  import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
650
625
  import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
651
626
  import { drawSelection, EditorView as EditorView3, highlightActiveLine, placeholder } from "@codemirror/view";
652
- var basicBundle = ({ themeMode, placeholder: _placeholder, multiline = true }) => [
653
- multiline ? EditorView3.lineWrapping : [],
627
+ var basicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping = true }) => [
628
+ lineWrapping ? EditorView3.lineWrapping : [],
654
629
  // https://codemirror.net/docs/ref/#codemirror.minimalSetup
655
630
  bracketMatching(),
656
631
  closeBrackets(),
@@ -1140,7 +1115,7 @@ var code2 = () => {
1140
1115
  import { StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
1141
1116
  import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView6 } from "@codemirror/view";
1142
1117
  import sortBy from "lodash.sortby";
1143
- import { useEffect as useEffect2 } from "react";
1118
+ import { useEffect } from "react";
1144
1119
  import { debounce } from "@dxos/async";
1145
1120
  import { invariant as invariant3 } from "@dxos/invariant";
1146
1121
  import { nonNullable } from "@dxos/util";
@@ -1186,7 +1161,7 @@ var styles3 = EditorView6.baseTheme({
1186
1161
  "& .cm-comment": {
1187
1162
  backgroundColor: getToken("extend.colors.yellow.50")
1188
1163
  },
1189
- "& .cm-comment-active": {
1164
+ "& .cm-comment-current": {
1190
1165
  backgroundColor: getToken("extend.colors.yellow.100")
1191
1166
  }
1192
1167
  });
@@ -1195,7 +1170,7 @@ var marks = {
1195
1170
  class: "cm-comment"
1196
1171
  }),
1197
1172
  highlightActive: Decoration3.mark({
1198
- class: "cm-comment-active"
1173
+ class: "cm-comment-current"
1199
1174
  })
1200
1175
  };
1201
1176
  var setFocus = (view, id, center = true) => {
@@ -1215,7 +1190,7 @@ var setFocus = (view, id, center = true) => {
1215
1190
  y: "center"
1216
1191
  } : void 0),
1217
1192
  setSelection.of({
1218
- active: id
1193
+ current: id
1219
1194
  })
1220
1195
  ]
1221
1196
  });
@@ -1263,14 +1238,14 @@ var commentsState = StateField2.define({
1263
1238
  var highlightDecorations = EditorView6.decorations.compute([
1264
1239
  commentsState
1265
1240
  ], (state) => {
1266
- const { selection: { active }, comments: comments2 } = state.field(commentsState);
1241
+ const { selection: { current }, comments: comments2 } = state.field(commentsState);
1267
1242
  const decorations = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
1268
1243
  const range = comment.range;
1269
1244
  if (!range || range.from === range.to) {
1270
1245
  console.warn("Invalid range:", range);
1271
1246
  return void 0;
1272
1247
  }
1273
- if (comment.comment.id === active) {
1248
+ if (comment.comment.id === current) {
1274
1249
  return marks.highlightActive.range(range.from, range.to);
1275
1250
  } else {
1276
1251
  return marks.highlight.range(range.from, range.to);
@@ -1366,7 +1341,7 @@ var comments = (options = {}) => {
1366
1341
  if (id) {
1367
1342
  view.dispatch({
1368
1343
  effects: setSelection.of({
1369
- active: id
1344
+ current: id
1370
1345
  }),
1371
1346
  selection: {
1372
1347
  anchor: from
@@ -1453,17 +1428,17 @@ var comments = (options = {}) => {
1453
1428
  //
1454
1429
  // Track selection/proximity.
1455
1430
  //
1456
- EditorView6.updateListener.of(({ view, state, changes }) => {
1431
+ EditorView6.updateListener.of(({ view, state }) => {
1457
1432
  let min = Infinity;
1458
- const { selection: { active, closest }, comments: comments2 } = state.field(commentsState);
1433
+ const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
1459
1434
  const { head } = state.selection.main;
1460
1435
  const selection = {};
1461
1436
  comments2.forEach(({ comment, range }) => {
1462
1437
  if (head >= range.from && head <= range.to) {
1463
- selection.active = comment.id;
1438
+ selection.current = comment.id;
1464
1439
  selection.closest = void 0;
1465
1440
  }
1466
- if (!selection.active) {
1441
+ if (!selection.current) {
1467
1442
  const d = Math.min(Math.abs(head - range.from), Math.abs(head - range.to));
1468
1443
  if (d < min) {
1469
1444
  selection.closest = comment.id;
@@ -1471,7 +1446,7 @@ var comments = (options = {}) => {
1471
1446
  }
1472
1447
  }
1473
1448
  });
1474
- if (selection.active !== active || selection.closest !== closest) {
1449
+ if (selection.current !== current || selection.closest !== closest) {
1475
1450
  view.dispatch({
1476
1451
  effects: setSelection.of(selection)
1477
1452
  });
@@ -1488,9 +1463,9 @@ var comments = (options = {}) => {
1488
1463
  options.onUpdate ? trackPastedComments(options.onUpdate) : []
1489
1464
  ];
1490
1465
  };
1491
- var useComments = (view, comments2) => {
1492
- useEffect2(() => {
1493
- if (view && comments2) {
1466
+ var useComments = (view, comments2 = []) => {
1467
+ useEffect(() => {
1468
+ if (view) {
1494
1469
  view.dispatch({
1495
1470
  effects: setComments.of(comments2)
1496
1471
  });
@@ -2317,27 +2292,6 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
2317
2292
  ];
2318
2293
  };
2319
2294
 
2320
- // packages/ui/react-ui-editor/src/extensions/yjs/yjs.ts
2321
- import { yCollab } from "y-codemirror.next";
2322
-
2323
- // packages/ui/react-ui-editor/src/extensions/yjs/cursor.ts
2324
- import * as Y from "yjs";
2325
- import { arrayToString, stringToArray } from "@dxos/util";
2326
- var cursorConverter2 = (text) => ({
2327
- toCursor: (index, assoc) => {
2328
- return arrayToString(Y.encodeRelativePosition(Y.createRelativePositionFromTypeIndex(text, index, assoc)));
2329
- },
2330
- fromCursor: (cursor) => {
2331
- return Y.createAbsolutePositionFromRelativePosition(Y.decodeRelativePosition(stringToArray(cursor)), text.doc)?.index ?? 0;
2332
- }
2333
- });
2334
-
2335
- // packages/ui/react-ui-editor/src/extensions/yjs/yjs.ts
2336
- var yjs = (content, awareness2) => [
2337
- Cursor.converter.of(cursorConverter2(content)),
2338
- yCollab(content, awareness2)
2339
- ];
2340
-
2341
2295
  // packages/ui/react-ui-editor/src/themes/default.ts
2342
2296
  import get3 from "lodash.get";
2343
2297
  var defaultTheme = {
@@ -2580,26 +2534,25 @@ var EditorModes = [
2580
2534
  "default",
2581
2535
  "vim"
2582
2536
  ];
2583
- var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autofocus, scrollTo, selection, editorMode, theme, slots = defaultSlots, extensions = [], debug }, forwardedRef) => {
2537
+ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo, selection, editorMode, theme, slots = defaultSlots, extensions = [], debug }, forwardedRef) => {
2584
2538
  const tabsterDOMAttribute = useFocusableGroup({
2585
2539
  tabBehavior: "limited"
2586
2540
  });
2587
- const { themeMode } = useThemeContext2();
2541
+ const { themeMode } = useThemeContext();
2588
2542
  const rootRef = useRef(null);
2589
2543
  const [view, setView] = useState(null);
2590
2544
  useImperativeHandle(forwardedRef, () => view, [
2591
2545
  view
2592
2546
  ]);
2593
- useEffect3(() => {
2594
- if (autofocus) {
2547
+ useEffect2(() => {
2548
+ if (autoFocus) {
2595
2549
  view?.focus();
2596
2550
  }
2597
2551
  }, [
2598
2552
  view,
2599
- autofocus
2553
+ autoFocus
2600
2554
  ]);
2601
- useAwareness(model);
2602
- useEffect3(() => {
2555
+ useEffect2(() => {
2603
2556
  if (!model || !rootRef.current) {
2604
2557
  return;
2605
2558
  }
@@ -2611,7 +2564,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autofocus, s
2611
2564
  EditorView13.exceptionSink.of((err) => {
2612
2565
  log2.catch(err, void 0, {
2613
2566
  F: __dxlog_file5,
2614
- L: 126,
2567
+ L: 123,
2615
2568
  S: void 0,
2616
2569
  C: (f, a) => f(...a)
2617
2570
  });
@@ -2692,8 +2645,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autofocus, s
2692
2645
  ref: rootRef
2693
2646
  });
2694
2647
  });
2695
- var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, multiline, theme = textTheme, slots, extensions = [], ...props }, forwardedRef) => {
2696
- const { themeMode } = useThemeContext2();
2648
+ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, lineWrapping, theme = textTheme, slots, extensions = [], ...props }, forwardedRef) => {
2649
+ const { themeMode } = useThemeContext();
2697
2650
  const updatedSlots = defaultsDeep2({}, slots, defaultTextSlots);
2698
2651
  return /* @__PURE__ */ React.createElement(BaseTextEditor, {
2699
2652
  ref: forwardedRef,
@@ -2702,7 +2655,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
2702
2655
  basicBundle({
2703
2656
  themeMode,
2704
2657
  placeholder: placeholder3,
2705
- multiline
2658
+ lineWrapping
2706
2659
  }),
2707
2660
  ...extensions
2708
2661
  ],
@@ -2712,7 +2665,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
2712
2665
  });
2713
2666
  });
2714
2667
  var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, theme = markdownTheme, slots, extensions = [], ...props }, forwardedRef) => {
2715
- const { themeMode } = useThemeContext2();
2668
+ const { themeMode } = useThemeContext();
2716
2669
  const updatedSlots = defaultsDeep2({}, slots, defaultMarkdownSlots);
2717
2670
  return /* @__PURE__ */ React.createElement(BaseTextEditor, {
2718
2671
  ref: forwardedRef,
@@ -2733,7 +2686,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
2733
2686
  var defaultSlots = {
2734
2687
  root: {
2735
2688
  // TODO(burdon): Add focusRing by default/as property?
2736
- className: mx3("flex flex-col grow overflow-y-auto", inputSurface)
2689
+ className: mx3("flex flex-col grow overflow-y-auto", attentionSurface)
2737
2690
  },
2738
2691
  editor: {
2739
2692
  className: "h-full p-2"
@@ -2746,11 +2699,6 @@ var defaultMarkdownSlots = {
2746
2699
  ...defaultSlots
2747
2700
  };
2748
2701
 
2749
- // packages/ui/react-ui-editor/src/hooks/automerge.ts
2750
- import get4 from "lodash.get";
2751
- import { getRawDoc } from "@dxos/echo-schema";
2752
- import { isNotNullOrUndefined } from "@dxos/util";
2753
-
2754
2702
  // packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
2755
2703
  import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
2756
2704
  import { Context as Context2 } from "@dxos/context";
@@ -2760,8 +2708,8 @@ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src
2760
2708
  var DEBOUNCE_INTERVAL = 100;
2761
2709
  var SpaceAwarenessProvider = class {
2762
2710
  constructor(params) {
2763
- this.remoteStateChange = new Event2();
2764
2711
  this._remoteStates = /* @__PURE__ */ new Map();
2712
+ this.remoteStateChange = new Event2();
2765
2713
  this._space = params.space;
2766
2714
  this._channel = params.channel;
2767
2715
  this._peerId = params.peerId;
@@ -2778,7 +2726,7 @@ var SpaceAwarenessProvider = class {
2778
2726
  await sleep(DEBOUNCE_INTERVAL);
2779
2727
  }
2780
2728
  });
2781
- const unsubscribe = this._space.listen(this._channel, (message) => {
2729
+ this._ctx.onDispose(this._space.listen(this._channel, (message) => {
2782
2730
  switch (message.payload.kind) {
2783
2731
  case "query": {
2784
2732
  this._handleQueryMessage();
@@ -2789,8 +2737,7 @@ var SpaceAwarenessProvider = class {
2789
2737
  break;
2790
2738
  }
2791
2739
  }
2792
- });
2793
- this._ctx.onDispose(unsubscribe);
2740
+ }));
2794
2741
  void this._space.postMessage(this._channel, {
2795
2742
  kind: "query"
2796
2743
  }).catch((err) => {
@@ -2798,7 +2745,7 @@ var SpaceAwarenessProvider = class {
2798
2745
  err
2799
2746
  }, {
2800
2747
  F: __dxlog_file6,
2801
- L: 85,
2748
+ L: 89,
2802
2749
  S: this,
2803
2750
  C: (f, a) => f(...a)
2804
2751
  });
@@ -2809,10 +2756,13 @@ var SpaceAwarenessProvider = class {
2809
2756
  this._ctx = void 0;
2810
2757
  this._postTask = void 0;
2811
2758
  }
2759
+ getRemoteStates() {
2760
+ return Array.from(this._remoteStates.values());
2761
+ }
2812
2762
  update(position) {
2813
2763
  invariant4(this._postTask, void 0, {
2814
2764
  F: __dxlog_file6,
2815
- L: 96,
2765
+ L: 104,
2816
2766
  S: this,
2817
2767
  A: [
2818
2768
  "this._postTask",
@@ -2826,13 +2776,10 @@ var SpaceAwarenessProvider = class {
2826
2776
  };
2827
2777
  this._postTask.schedule();
2828
2778
  }
2829
- getRemoteStates() {
2830
- return Array.from(this._remoteStates.values());
2831
- }
2832
2779
  _handleQueryMessage() {
2833
2780
  invariant4(this._postTask, void 0, {
2834
2781
  F: __dxlog_file6,
2835
- L: 111,
2782
+ L: 115,
2836
2783
  S: this,
2837
2784
  A: [
2838
2785
  "this._postTask",
@@ -2844,7 +2791,7 @@ var SpaceAwarenessProvider = class {
2844
2791
  _handlePostMessage(message) {
2845
2792
  invariant4(message.kind === "post", void 0, {
2846
2793
  F: __dxlog_file6,
2847
- L: 116,
2794
+ L: 120,
2848
2795
  S: this,
2849
2796
  A: [
2850
2797
  "message.kind === 'post'",
@@ -2863,8 +2810,47 @@ var modelState = StateField5.define({
2863
2810
  update: (model) => model
2864
2811
  });
2865
2812
 
2866
- // packages/ui/react-ui-editor/src/hooks/automerge.ts
2867
- var createAutomergeModel = ({ space, identity, text }) => {
2813
+ // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
2814
+ import { useState as useState2 } from "react";
2815
+ var useTextEditor = () => {
2816
+ const [view, setView] = useState2(null);
2817
+ return [
2818
+ (ref) => {
2819
+ setView(ref);
2820
+ },
2821
+ view
2822
+ ];
2823
+ };
2824
+
2825
+ // packages/ui/react-ui-editor/src/hooks/useTextModel.ts
2826
+ import get4 from "lodash.get";
2827
+ import { useEffect as useEffect3, useState as useState3 } from "react";
2828
+ import { generateName } from "@dxos/display-name";
2829
+ import { getRawDoc } from "@dxos/echo-schema";
2830
+ import { invariant as invariant5 } from "@dxos/invariant";
2831
+ import { isAutomergeObject } from "@dxos/react-client/echo";
2832
+ import { isNotNullOrUndefined } from "@dxos/util";
2833
+ var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
2834
+ var useTextModel = (props) => {
2835
+ const { identity, space, text } = props;
2836
+ const [model, setModel] = useState3();
2837
+ useEffect3(() => setModel(createModel(props)), [
2838
+ identity,
2839
+ space,
2840
+ text
2841
+ ]);
2842
+ return model;
2843
+ };
2844
+ var createModel = ({ space, identity, text }) => {
2845
+ invariant5(isAutomergeObject(text), void 0, {
2846
+ F: __dxlog_file7,
2847
+ L: 35,
2848
+ S: void 0,
2849
+ A: [
2850
+ "isAutomergeObject(text)",
2851
+ ""
2852
+ ]
2853
+ });
2868
2854
  const obj = text;
2869
2855
  const doc = getRawDoc(obj, [
2870
2856
  obj.field
@@ -2873,7 +2859,7 @@ var createAutomergeModel = ({ space, identity, text }) => {
2873
2859
  space,
2874
2860
  channel: `automerge.awareness.${obj.id}`,
2875
2861
  info: {
2876
- displayName: identity?.profile?.displayName ?? "",
2862
+ displayName: identity ? identity.profile?.displayName ?? generateName(identity.identityKey.toHex()) : void 0,
2877
2863
  color: cursorColor.color,
2878
2864
  lightColor: cursorColor.light
2879
2865
  },
@@ -2883,7 +2869,6 @@ var createAutomergeModel = ({ space, identity, text }) => {
2883
2869
  id: obj.id,
2884
2870
  content: doc,
2885
2871
  text: () => get4(doc.handle.docSync(), doc.path),
2886
- // TODO(burdon): https://automerge.org/automerge/api-docs/js/functions/next.getCursor.html
2887
2872
  extension: [
2888
2873
  modelState.init(() => model),
2889
2874
  automerge3({
@@ -2900,162 +2885,6 @@ var createAutomergeModel = ({ space, identity, text }) => {
2900
2885
  };
2901
2886
  return model;
2902
2887
  };
2903
-
2904
- // packages/ui/react-ui-editor/src/hooks/yjs.ts
2905
- import * as decoding from "lib0/decoding";
2906
- import * as encoding from "lib0/encoding";
2907
- import { Observable } from "lib0/observable";
2908
- import * as YP from "y-protocols/awareness";
2909
- import { invariant as invariant5 } from "@dxos/invariant";
2910
- import { log as log4 } from "@dxos/log";
2911
- var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/yjs.ts";
2912
- var createYjsModel = ({ identity, space, text }) => {
2913
- invariant5(text?.doc && text?.content, void 0, {
2914
- F: __dxlog_file7,
2915
- L: 22,
2916
- S: void 0,
2917
- A: [
2918
- "text?.doc && text?.content",
2919
- ""
2920
- ]
2921
- });
2922
- const provider = space ? new YAwarenessProvider({
2923
- space,
2924
- doc: text.doc,
2925
- channel: `yjs.awareness.${text.id}`
2926
- }) : void 0;
2927
- const model = {
2928
- id: text.doc.guid,
2929
- content: text.content,
2930
- text: () => text.content.toString(),
2931
- extension: [
2932
- modelState.init(() => model),
2933
- yjs(text.content, provider?.awareness)
2934
- ],
2935
- awareness: provider?.awareness,
2936
- peer: identity ? {
2937
- id: identity.identityKey.toHex(),
2938
- name: identity.profile?.displayName
2939
- } : void 0
2940
- };
2941
- return model;
2942
- };
2943
- var messageAwareness = 1;
2944
- var messageQueryAwareness = 3;
2945
- var YAwarenessProvider = class extends Observable {
2946
- constructor({ space, doc, channel, awareness: awareness2 }) {
2947
- super();
2948
- this._space = space;
2949
- this._awareness = awareness2 ?? new YP.Awareness(doc);
2950
- this._channel = channel;
2951
- this._clientId = doc.clientID;
2952
- this._awareness.on("update", this._handleAwarenessUpdate.bind(this));
2953
- this._space.listen(this._channel, this._handleSpaceMessage.bind(this));
2954
- if (typeof window !== "undefined") {
2955
- window.addEventListener("beforeunload", this._handleBeforeUnload.bind(this));
2956
- } else if (typeof process !== "undefined") {
2957
- process.on("exit", this._handleBeforeUnload.bind(this));
2958
- }
2959
- const encoderAwarenessQuery = encoding.createEncoder();
2960
- encoding.writeVarUint(encoderAwarenessQuery, messageQueryAwareness);
2961
- void this._space.postMessage(this._channel, encoding.toUint8Array(encoderAwarenessQuery));
2962
- const encoderAwarenessState = encoding.createEncoder();
2963
- encoding.writeVarUint(encoderAwarenessState, messageAwareness);
2964
- encoding.writeVarUint8Array(encoderAwarenessState, YP.encodeAwarenessUpdate(this.awareness, [
2965
- this._clientId
2966
- ]));
2967
- void this._space.postMessage(this._channel, encoding.toUint8Array(encoderAwarenessState));
2968
- }
2969
- get awareness() {
2970
- return this._awareness;
2971
- }
2972
- _handleAwarenessUpdate({ added, updated, removed }, origin) {
2973
- log4("awareness update", {
2974
- added,
2975
- updated,
2976
- removed,
2977
- origin
2978
- }, {
2979
- F: __dxlog_file7,
2980
- L: 101,
2981
- S: this,
2982
- C: (f, a) => f(...a)
2983
- });
2984
- const changedClients = added.concat(updated).concat(removed);
2985
- const encoderAwareness = encoding.createEncoder();
2986
- encoding.writeVarUint(encoderAwareness, messageAwareness);
2987
- encoding.writeVarUint8Array(encoderAwareness, YP.encodeAwarenessUpdate(this._awareness, changedClients));
2988
- void this._space.postMessage(this._channel, encoding.toUint8Array(encoderAwareness));
2989
- }
2990
- _handleSpaceMessage({ payload }) {
2991
- log4("space message", payload, {
2992
- F: __dxlog_file7,
2993
- L: 110,
2994
- S: this,
2995
- C: (f, a) => f(...a)
2996
- });
2997
- const data = new Uint8Array(Array.from(Object.values(payload)));
2998
- const encoder = this._readMessage(data);
2999
- if (encoder) {
3000
- void this._space.postMessage(this._channel, encoding.toUint8Array(encoder));
3001
- }
3002
- }
3003
- _readMessage(message) {
3004
- const decoder = decoding.createDecoder(message);
3005
- const encoder = encoding.createEncoder();
3006
- const messageType = decoding.readVarUint(decoder);
3007
- let sendReply = false;
3008
- switch (messageType) {
3009
- case messageAwareness: {
3010
- YP.applyAwarenessUpdate(this._awareness, decoding.readVarUint8Array(decoder), this);
3011
- break;
3012
- }
3013
- case messageQueryAwareness: {
3014
- encoding.writeVarUint(encoder, messageAwareness);
3015
- encoding.writeVarUint8Array(encoder, YP.encodeAwarenessUpdate(this._awareness, Array.from(this._awareness.getStates().keys())));
3016
- sendReply = true;
3017
- break;
3018
- }
3019
- default: {
3020
- console.error("Invalid message:", messageType);
3021
- return encoder;
3022
- }
3023
- }
3024
- if (!sendReply) {
3025
- return null;
3026
- }
3027
- return encoder;
3028
- }
3029
- _handleBeforeUnload() {
3030
- YP.removeAwarenessStates(this._awareness, [
3031
- this._clientId
3032
- ], "window unload");
3033
- }
3034
- };
3035
-
3036
- // packages/ui/react-ui-editor/src/hooks/useTextModel.ts
3037
- import { useEffect as useEffect4, useState as useState2 } from "react";
3038
- import { isAutomergeObject } from "@dxos/react-client/echo";
3039
- var useTextModel = (props) => {
3040
- const { identity, space, text } = props;
3041
- const [model, setModel] = useState2();
3042
- useEffect4(() => setModel(createModel(props)), [
3043
- identity,
3044
- space,
3045
- text
3046
- ]);
3047
- return model;
3048
- };
3049
- var createModel = (props) => {
3050
- const { text } = props;
3051
- if (isAutomergeObject(text)) {
3052
- return createAutomergeModel(props);
3053
- } else if (text?.doc) {
3054
- return createYjsModel(props);
3055
- } else {
3056
- return void 0;
3057
- }
3058
- };
3059
2888
  export {
3060
2889
  AwarenessProvider,
3061
2890
  BaseTextEditor,
@@ -3067,7 +2896,6 @@ export {
3067
2896
  SpaceAwarenessProvider,
3068
2897
  TextEditor,
3069
2898
  TextKind,
3070
- YAwarenessProvider,
3071
2899
  YText,
3072
2900
  YXmlFragment,
3073
2901
  autocomplete,
@@ -3079,8 +2907,6 @@ export {
3079
2907
  code2 as code,
3080
2908
  codeTheme,
3081
2909
  comments,
3082
- createAutomergeModel,
3083
- createYjsModel,
3084
2910
  defaultMarkdownSlots,
3085
2911
  defaultOptions,
3086
2912
  defaultSlots,
@@ -3108,9 +2934,8 @@ export {
3108
2934
  tasklist,
3109
2935
  textTheme,
3110
2936
  typewriter,
3111
- useAwareness,
3112
2937
  useComments,
3113
- useTextModel,
3114
- yjs
2938
+ useTextEditor,
2939
+ useTextModel
3115
2940
  };
3116
2941
  //# sourceMappingURL=index.mjs.map