@nerd-bible/wordgard 0.5.3-beta7 → 0.6.2-beta10

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/state.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Leaf, ValidationError, Pos, ChangeSet, Plot, SchemaError, parse, Schema } from 'wordgard/doc';
1
+ import { Leaf, ValidationError, Slice, Pos, ChangeSet, Plot, SchemaError, parse, Schema, Node } from 'wordgard/doc';
2
2
  import { findClusterBreak } from '@marijn/find-cluster-break';
3
3
 
4
4
  function dec(str) {
@@ -444,8 +444,20 @@ class TextblockMap {
444
444
  return off;
445
445
  }
446
446
  moveVisually(start, side, forward, skipped) {
447
- let startIndex = this.toIndex(start), { order, ltr } = this;
448
- let spanI = BidiSpan.find(order, startIndex, side);
447
+ if (!this.text.length)
448
+ return null;
449
+ let startIndex = this.toIndex(start), { order, ltr } = this, spanI;
450
+ if (startIndex == 0 && side < 0) { if (!forward)
451
+ return null;
452
+ startIndex = order[spanI = 0].side(false, this.ltr);
453
+ }
454
+ else if (startIndex == this.text.length && side > 0) { if (forward)
455
+ return null;
456
+ startIndex = order[spanI = order.length - 1].side(true, this.ltr);
457
+ }
458
+ else {
459
+ spanI = BidiSpan.find(order, startIndex, side);
460
+ }
449
461
  let span = order[spanI], spanEnd = span.side(forward, ltr);
450
462
  if (startIndex == spanEnd) {
451
463
  let nextI = spanI += forward ? 1 : -1;
@@ -463,8 +475,14 @@ class TextblockMap {
463
475
  if (skipped)
464
476
  skipped[0] = this.text.slice(Math.min(startIndex, nextIndex), Math.max(startIndex, nextIndex));
465
477
  let nextSpan = spanI == (forward ? order.length - 1 : 0) ? null : order[spanI + (forward ? 1 : -1)];
466
- if (nextSpan && nextIndex == spanEnd && nextSpan.level + (forward ? 0 : 1) < span.level)
467
- return { pos: this.fromIndex(nextSpan.side(!forward, ltr)), side: nextSpan.forward(forward, ltr) ? 1 : -1 };
478
+ if (nextIndex == spanEnd) {
479
+ if (!nextSpan)
480
+ return forward ? { pos: this.start + this.node.contentLength, side: 1 }
481
+ : { pos: this.start, side: -1 };
482
+ if (nextSpan.level + (forward ? 0 : 1) < span.level)
483
+ return { pos: this.fromIndex(nextSpan.side(!forward, this.ltr)),
484
+ side: nextSpan.forward(forward, this.ltr) ? 1 : -1 };
485
+ }
468
486
  return { pos: this.fromIndex(nextIndex), side: nextIndex != spanEnd ? 1 : span.forward(forward, ltr) ? -1 : 1 };
469
487
  }
470
488
  skipWord(start, side, forward, visually) {
@@ -500,18 +518,6 @@ class TextblockMap {
500
518
  return cur; let segments = [...new Intl.Segmenter(undefined, { granularity: "word" }).segment(word)];
501
519
  return history.get(segments[forward ? 0 : segments.length - 1].segment.length) || cur;
502
520
  }
503
- visualSide(start) {
504
- let pos, side;
505
- if (start) {
506
- let span = this.order[0];
507
- [pos, side] = span.ltr == this.ltr ? [span.from, 1] : [span.to, -1];
508
- }
509
- else {
510
- let span = this.order[this.order.length - 1];
511
- [pos, side] = span.ltr == this.ltr ? [span.to, -1] : [span.from, 1];
512
- }
513
- return { pos: this.fromIndex(pos), side };
514
- }
515
521
  moveLogically(start, forward) {
516
522
  let index = this.toIndex(start);
517
523
  let next = findClusterBreak(this.text, index, forward);
@@ -550,6 +556,14 @@ class GardSelection {
550
556
  get ranges() { return [this]; }
551
557
  get replacementRange() { return this; }
552
558
  get domSelection() { return this; }
559
+ toSlice(doc) {
560
+ let slice;
561
+ for (let range of this.ranges) {
562
+ let cur = Slice.get(doc, range.from, range.to);
563
+ slice = slice ? slice.concat(cur) : cur;
564
+ }
565
+ return slice;
566
+ }
553
567
  get headSide() { return this.head > this.anchor ? -1 : 1; }
554
568
  get anchorSide() { return this.anchor > this.head ? -1 : 1; }
555
569
  eqPos(other) {
@@ -580,14 +594,17 @@ class GardSelection {
580
594
  return type.fromJSON(doc, json);
581
595
  }
582
596
  static cursor(pos, side, goalColumn) {
583
- return GardSelection.Text.createInner(pos, pos, side, goalColumn);
597
+ return GardSelection.Text.createInner(pos, pos, side, true, goalColumn);
584
598
  }
585
599
  static near(cx, pos, side = 1, goalColumn) {
586
600
  let norm = findNormalAt(cx, pos, side);
587
601
  return GardSelection.cursor(norm.pos, norm.side, goalColumn);
588
602
  }
589
603
  static range(anchor, head, headSide, goalColumn) {
590
- return GardSelection.Text.createInner(anchor, head ?? anchor, headSide, goalColumn);
604
+ return GardSelection.Text.createInner(anchor, head ?? anchor, headSide, true, goalColumn);
605
+ }
606
+ static undirectionalRange(from, to) {
607
+ return GardSelection.Text.createInner(from, to, 1, false);
591
608
  }
592
609
  static node(pos, node, goalColumn) {
593
610
  return GardSelection.Node.create(pos, node, goalColumn);
@@ -604,9 +621,8 @@ class GardSelection {
604
621
  return cursorAtStart(cx, block);
605
622
  }
606
623
  static atEnd(cx, block) {
607
- let found = block
608
- ? TextblockMap.get(cx, block.start, block.node).visualSide(false)
609
- : cx.doc.inlineContent ? TextblockMap.get(cx, 0, cx.doc).visualSide(false)
624
+ let found = block ? { pos: block.end, side: 1 }
625
+ : cx.doc.inlineContent ? { pos: cx.doc.length, side: 1 }
610
626
  : findNormalAt(cx, cx.doc.length, -1);
611
627
  return GardSelection.cursor(found.pos, found.side);
612
628
  }
@@ -618,15 +634,18 @@ class GardSelection {
618
634
  GardSelection.define = define;
619
635
  class Text extends GardSelection {
620
636
  _headSide;
637
+ directional;
621
638
  marks;
622
- constructor(anchor, head, _headSide, goalColumn,
639
+ constructor(anchor, head, _headSide,
640
+ directional, goalColumn,
623
641
  marks) {
624
642
  super(anchor, head, goalColumn);
625
643
  this._headSide = _headSide;
644
+ this.directional = directional;
626
645
  this.marks = marks;
627
646
  }
628
- static createInner(anchor, head, side, goalColumn, marks) {
629
- return new Text(anchor, head, side ?? (head > anchor ? -1 : 1), goalColumn, marks);
647
+ static createInner(anchor, head, side, directional, goalColumn, marks) {
648
+ return new Text(anchor, head, side ?? (head > anchor ? -1 : 1), directional, goalColumn, marks);
630
649
  }
631
650
  get headSide() {
632
651
  return this._headSide;
@@ -636,7 +655,7 @@ class GardSelection {
636
655
  }
637
656
  static create(spec) {
638
657
  let { anchor, head = anchor } = spec;
639
- return Text.createInner(anchor, head, spec.headSide, spec.goalColumn, spec.marks);
658
+ return Text.createInner(anchor, head, spec.headSide, spec.directional !== false, spec.goalColumn, spec.marks);
640
659
  }
641
660
  map(change, cx, assoc = -1) {
642
661
  let from, to;
@@ -647,7 +666,7 @@ class GardSelection {
647
666
  from = change.mapPos(this.from, 1);
648
667
  to = Math.max(from, change.mapPos(this.to, -1));
649
668
  }
650
- return Text.createInner(from, to, this.headSide, this.goalColumn, this.marks);
669
+ return Text.createInner(from, to, this.headSide, this.directional, this.goalColumn, this.marks);
651
670
  }
652
671
  eq(other) {
653
672
  return other instanceof Text && this.eqPos(other) && this.headSide == other.headSide &&
@@ -674,7 +693,7 @@ class GardSelection {
674
693
  throw new ValidationError("Invalid JSON representation for GardSelection.Text");
675
694
  let anchor = json.anchor, head = typeof json.head == "number" ? json.head : anchor;
676
695
  let marks = json.marks ? doc.schema.marksFromJSON(json.marks) : undefined;
677
- return Text.createInner(anchor, head, json.side == 1 || json.side == -1 ? json.side : undefined, undefined, marks);
696
+ return Text.createInner(anchor, head, json.side == 1 || json.side == -1 ? json.side : undefined, json.directional !== false, undefined, marks);
678
697
  }));
679
698
  })(Text = GardSelection.Text || (GardSelection.Text = {}));
680
699
  class Node extends GardSelection {
@@ -744,8 +763,8 @@ class GardSelection {
744
763
  ;return GardSelection})(GardSelection);
745
764
  function cursorAtStart(cx, block) {
746
765
  let found = block
747
- ? TextblockMap.get(cx, block.start, block.node).visualSide(true)
748
- : cx.doc.inlineContent ? TextblockMap.get(cx, 0, cx.doc).visualSide(true)
766
+ ? { pos: block.start, side: -1 }
767
+ : cx.doc.inlineContent ? { pos: 0, side: -1 }
749
768
  : findNormalAt(cx, 0, 1);
750
769
  return GardSelection.cursor(found.pos, found.side);
751
770
  }
@@ -790,11 +809,8 @@ function scanNormalFrom(cx, from, side, forward) {
790
809
  let bottom = pos.pos, step = forward ? 1 : -1;
791
810
  for (let { parent, index } = pos, p = pos.pos;;) {
792
811
  let { node, parent: next } = parent;
793
- if (node.inlineContent) {
794
- if (cx.config.visualCursorMotion)
795
- return TextblockMap.get(cx, parent.start, parent.node).visualSide(forward);
796
- return { pos: p, side: forward ? 1 : -1 };
797
- }
812
+ if (node.inlineContent)
813
+ return { pos: p, side: forward ? -1 : 1 };
798
814
  if (index == (forward ? node.content.length : 0)) {
799
815
  let barrier = !next || isBarrier(cx, node);
800
816
  if ((bottom != from) && pastBarrier && barrier)
@@ -857,10 +873,8 @@ function findNormalAt(cx, pos, bias) {
857
873
  let nextIndex = index + (dir > 0 ? 0 : -1), next = parent.node.content[nextIndex];
858
874
  if (next.isLeaf || isBarrier(cx, next))
859
875
  break;
860
- if (!parent.node.inlineContent && next.inlineContent && cx.config.visualCursorMotion) {
861
- let startPos = curPos - (dir > 0 ? 0 : next.length) + 1;
862
- return TextblockMap.get(cx, startPos, next).visualSide(dir > 0);
863
- }
876
+ if (!parent.node.inlineContent && next.inlineContent)
877
+ return { pos: curPos + dir, side: -dir };
864
878
  parent = Pos.Plot.create(parent, next, curPos, nextIndex);
865
879
  index = dir > 0 ? 0 : next.content.length;
866
880
  curPos += dir;
@@ -886,8 +900,7 @@ function skipWord(cx, start, side, forward) {
886
900
  return next;
887
901
  if (!block.parent)
888
902
  return last;
889
- let end = visually ? map.visualSide(!forward)
890
- : forward ? { pos: block.end, side: -1 } : { pos: block.start, side: 1 };
903
+ let end = forward ? { pos: block.end, side: 1 } : { pos: block.start, side: -1 };
891
904
  if (end.pos != start)
892
905
  last = end;
893
906
  pos = forward ? block.after : block.before;
@@ -897,7 +910,7 @@ function skipWord(cx, start, side, forward) {
897
910
  function wordAt(state, pos, bias) {
898
911
  let res = state.doc.resolve(pos);
899
912
  if (!res.parent.node.inlineContent)
900
- return GardSelection.cursor(pos, bias);
913
+ return null;
901
914
  let start = pos, end = pos, text = "";
902
915
  scanBack: for (let i = res.index - (res.inText ? 0 : 1), cur = res.nodeBefore; cur;) {
903
916
  if (!cur.is(Leaf.Text))
@@ -932,13 +945,24 @@ function wordAt(state, pos, bias) {
932
945
  cur = res.parent.node.content[i++];
933
946
  }
934
947
  if (!Intl.Segmenter)
935
- return GardSelection.range(start, end);
948
+ return GardSelection.undirectionalRange(start, end);
936
949
  let best = null, local = pos - start;
937
950
  for (let segment of new Intl.Segmenter(undefined, { granularity: "word" }).segment(text)) {
938
951
  if (segment.isWordLike && segment.index <= local && segment.index + segment.segment.length >= local && (!best || bias > 0))
939
952
  best = segment;
940
953
  }
941
- return best ? GardSelection.range(start + best.index, start + best.index + best.segment.length) : GardSelection.cursor(pos, bias);
954
+ return best ? GardSelection.undirectionalRange(start + best.index, start + best.index + best.segment.length) : null;
955
+ }
956
+
957
+ function debugString(value) {
958
+ let tp = typeof value;
959
+ if (tp == "string")
960
+ return JSON.stringify(value);
961
+ if (tp == "function")
962
+ return /.*?\)/.exec(value.toString())?.[0] || value;
963
+ if (Array.isArray(value))
964
+ return `[${value.map(debugString)}]`;
965
+ return value;
942
966
  }
943
967
 
944
968
  class Transaction {
@@ -1031,20 +1055,28 @@ class Transaction {
1031
1055
  this.type = type;
1032
1056
  this.value = value;
1033
1057
  }
1034
- static define() { return new Transaction.Annotation.Type(); }
1058
+ static define(name) { return Transaction.Annotation.Type.new(name || null); }
1059
+ toString() { return `${this.type}(${debugString(this.value)})`; }
1035
1060
  }
1036
1061
  Transaction.Annotation = Annotation;
1037
1062
  (function (Annotation) {
1038
1063
  class Type {
1064
+ name;
1065
+ constructor(
1066
+ name) {
1067
+ this.name = name;
1068
+ }
1069
+ static new(name) { return new Type(name); }
1039
1070
  of(value) { return new Transaction.Annotation(this, value); }
1071
+ toString() { return "Annotation" + (this.name ? ":" + this.name : ""); }
1040
1072
  }
1041
1073
  Annotation.Type = Type;
1042
1074
  })(Annotation = Transaction.Annotation || (Transaction.Annotation = {}));
1043
- Transaction.time = Transaction.Annotation.define();
1044
- Transaction.userEvent = Annotation.define();
1045
- Transaction.addToHistory = Annotation.define();
1046
- Transaction.remote = Annotation.define();
1047
- Transaction.appended = Annotation.define();
1075
+ Transaction.time = Transaction.Annotation.define("time");
1076
+ Transaction.userEvent = Annotation.define("userEvent");
1077
+ Transaction.addToHistory = Annotation.define("addToHistory");
1078
+ Transaction.remote = Annotation.define("remote");
1079
+ Transaction.appended = Annotation.define("appended");
1048
1080
  class Effect {
1049
1081
  type;
1050
1082
  value;
@@ -1060,8 +1092,9 @@ class Transaction {
1060
1092
  }
1061
1093
  is(type) { return this.type == type; }
1062
1094
  static define(spec = {}) {
1063
- return new Transaction.Effect.Type(spec.map || (v => v));
1095
+ return Effect.Type.new(spec.map || (v => v), spec.name || null);
1064
1096
  }
1097
+ toString() { return `${this.type}(${debugString(this.value)})`; }
1065
1098
  }
1066
1099
  Transaction.Effect = Effect;
1067
1100
  (function (Effect) {
@@ -1079,11 +1112,18 @@ class Transaction {
1079
1112
  Effect.mapEffects = mapEffects;
1080
1113
  class Type {
1081
1114
  map;
1115
+ name;
1082
1116
  constructor(
1083
- map) {
1117
+ map,
1118
+ name) {
1084
1119
  this.map = map;
1120
+ this.name = name;
1121
+ }
1122
+ static new(map, name) {
1123
+ return new Type(map, name);
1085
1124
  }
1086
1125
  of(value) { return new Transaction.Effect(this, value); }
1126
+ toString() { return "Effect" + (this.name ? ":" + this.name : ""); }
1087
1127
  }
1088
1128
  Effect.Type = Type;
1089
1129
  })(Effect = Transaction.Effect || (Transaction.Effect = {}));
@@ -1240,7 +1280,7 @@ class GardState {
1240
1280
  if (addr == null) {
1241
1281
  if (require)
1242
1282
  throw new RangeError("Field is not present in this state");
1243
- return undefined;
1283
+ return field instanceof GardState.Field ? undefined : field.value(this);
1244
1284
  }
1245
1285
  let track = this.trackAccess;
1246
1286
  if (track) {
@@ -1352,8 +1392,8 @@ class GardState {
1352
1392
  wordAt(pos, bias = 1) {
1353
1393
  return wordAt(this, pos, bias);
1354
1394
  }
1355
- static reconfigure = /*@__PURE__*/Transaction.Effect.define();
1356
- static appendConfig = /*@__PURE__*/Transaction.Effect.define();
1395
+ static reconfigure = /*@__PURE__*/Transaction.Effect.define({ name: "reconfigure" });
1396
+ static appendConfig = /*@__PURE__*/Transaction.Effect.define({ name: "appendConfig" });
1357
1397
  }
1358
1398
  ;GardState = /*@__PURE__*/(function (GardState) {
1359
1399
  class Field {
@@ -1371,13 +1411,15 @@ class GardState {
1371
1411
  this.updateF = updateF;
1372
1412
  this.compareF = compareF;
1373
1413
  this.spec = spec;
1414
+ this.name = spec.name || null;
1374
1415
  }
1375
1416
  static define(config) {
1376
- let field = new GardState.Field(nextID++, config.create, config.update, config.compare || ((a, b) => a === b), config);
1417
+ let field = new Field(nextID++, config.create, config.update, config.compare || ((a, b) => a === b), config);
1377
1418
  if (config.provide)
1378
1419
  field.provides = config.provide(field);
1379
1420
  return field;
1380
1421
  }
1422
+ name;
1381
1423
  create(state) {
1382
1424
  let init = state.facet(initField).find(i => i.field == this);
1383
1425
  return (init?.create || this.createF)(state);
@@ -1411,13 +1453,78 @@ class GardState {
1411
1453
  init(create) {
1412
1454
  return [this, initField.of({ field: this, create })];
1413
1455
  }
1456
+ toString() { return "Field" + (this.name ? ":" + this.name : ""); }
1414
1457
  }
1415
1458
  GardState.Field = Field;
1459
+ (function (Field) {
1460
+ class Derived {
1461
+ value;
1462
+ compareF;
1463
+ name;
1464
+ id = nextID++;
1465
+ dependencies = [];
1466
+ constructor(
1467
+ value, compareF,
1468
+ name) {
1469
+ this.value = value;
1470
+ this.compareF = compareF;
1471
+ this.name = name;
1472
+ }
1473
+ static define(compute, spec = {}) {
1474
+ return new Derived(compute, spec.compare || ((a, b) => a === b), spec.name || null);
1475
+ }
1476
+ get extension() { return this; }
1477
+ slot(addresses) {
1478
+ let idx = addresses[this.id] >> 1;
1479
+ let depSet = new DependencySet;
1480
+ return {
1481
+ create: state => {
1482
+ state.values[idx] = state.recordAccess(this.dependencies, this.value);
1483
+ return 1;
1484
+ },
1485
+ update: (state, tr) => {
1486
+ depSet.update(this.dependencies, addresses);
1487
+ if ((depSet.doc && tr.docChanged) || (depSet.sel && (tr.docChanged || tr.selection)) ||
1488
+ (depSet.schema && tr.startState.schema != state.schema) || ensureAll(state, depSet.addrs)) {
1489
+ let newVal = state.recordAccess(this.dependencies, this.value);
1490
+ if (!this.compareF(newVal, state.values[idx])) {
1491
+ state.values[idx] = newVal;
1492
+ return 1;
1493
+ }
1494
+ }
1495
+ return 0;
1496
+ },
1497
+ reconfigure: (state, oldState) => {
1498
+ let newVal, oldAddr = oldState.config.address[this.id];
1499
+ if (oldAddr != null) {
1500
+ let oldVal = getAddr(oldState, oldAddr);
1501
+ if (this.dependencies.every(dep => {
1502
+ return dep instanceof GardState.Facet ? oldState.facet(dep) === state.facet(dep)
1503
+ : dep instanceof GardState.Field ? oldState.field(dep, false) == state.field(dep, false)
1504
+ : true;
1505
+ }) || this.compareF(newVal = state.recordAccess(this.dependencies, this.value), oldVal)) {
1506
+ state.values[idx] = oldVal;
1507
+ return 0;
1508
+ }
1509
+ }
1510
+ else {
1511
+ newVal = state.recordAccess(this.dependencies, this.value);
1512
+ }
1513
+ state.values[idx] = newVal;
1514
+ return 1;
1515
+ }
1516
+ };
1517
+ }
1518
+ toString() { return "Field.Derived" + (this.name ? ":" + this.name : ""); }
1519
+ }
1520
+ Field.Derived = Derived;
1521
+ })(Field = GardState.Field || (GardState.Field = {}));
1416
1522
  class Facet {
1417
1523
  combine;
1418
1524
  compareInput;
1419
1525
  compare;
1420
1526
  isStatic;
1527
+ name;
1421
1528
  id = nextID++;
1422
1529
  default;
1423
1530
  extensions;
@@ -1425,39 +1532,44 @@ class GardState {
1425
1532
  combine,
1426
1533
  compareInput,
1427
1534
  compare,
1428
- isStatic, enables) {
1535
+ isStatic, enables,
1536
+ name) {
1429
1537
  this.combine = combine;
1430
1538
  this.compareInput = compareInput;
1431
1539
  this.compare = compare;
1432
1540
  this.isStatic = isStatic;
1541
+ this.name = name;
1433
1542
  this.default = combine(none);
1434
1543
  this.extensions = typeof enables == "function" ? enables(this) : enables;
1435
1544
  }
1436
1545
  get reader() { return this; }
1437
1546
  static define(config = {}) {
1438
- return new GardState.Facet(config.combine || ((a) => a), config.compareInput || ((a, b) => a === b), config.compare || (!config.combine ? sameArray : (a, b) => a === b), !!config.static, config.enables);
1547
+ return new GardState.Facet(config.combine || ((a) => a), config.compareInput || ((a, b) => a === b), config.compare || (!config.combine ? sameArray : (a, b) => a === b), !!config.static, config.enables, config.name || null);
1439
1548
  }
1440
1549
  of(value) {
1441
- return new FacetProvider(none, this, 1, value);
1550
+ return new FacetProvider(this, nextID++, 1, value);
1442
1551
  }
1443
- compute(get) {
1552
+ derive(get) {
1444
1553
  if (this.isStatic)
1445
- throw new Error("Can't compute a static facet");
1446
- return new FacetProvider([], this, 4, get);
1554
+ throw new Error("Can't derive a static facet");
1555
+ let field = Field.Derived.define(get, { compare: this.compareInput });
1556
+ return [field, new FacetProvider(this, field.id, 0, null)];
1447
1557
  }
1448
- computeN(get) {
1558
+ deriveN(get) {
1449
1559
  if (this.isStatic)
1450
- throw new Error("Can't compute a static facet");
1451
- return new FacetProvider([], this, 2 | 4, get);
1560
+ throw new Error("Can't derive a static facet");
1561
+ let field = Field.Derived.define(get, { compare: (a, b) => compareArray(a, b, this.compareInput) });
1562
+ return [field, new FacetProvider(this, field.id, 2, null)];
1452
1563
  }
1453
1564
  from(field, get) {
1454
1565
  if (this.isStatic)
1455
- throw new Error("Can't compute a static facet");
1566
+ throw new Error("Can't derive a static facet");
1456
1567
  if (!get)
1457
- get = x => x;
1458
- return new FacetProvider([field], this, 0, state => get(state.field(field)));
1568
+ return new FacetProvider(this, field.id, 0, null);
1569
+ return this.derive(s => get(s.field(field)));
1459
1570
  }
1460
1571
  tag;
1572
+ toString() { return "Facet" + (this.name ? ":" + this.name : ""); }
1461
1573
  }
1462
1574
  GardState.Facet = Facet;
1463
1575
  (function (Facet) {
@@ -1547,10 +1659,6 @@ class GardState {
1547
1659
  address[p.id] = (staticValues.length << 1) | 1;
1548
1660
  staticValues.push(p.value);
1549
1661
  }
1550
- else {
1551
- address[p.id] = dynamicSlots.length << 1;
1552
- dynamicSlots.push(a => p.dynamicSlot(a));
1553
- }
1554
1662
  }
1555
1663
  address[facet.id] = dynamicSlots.length << 1;
1556
1664
  dynamicSlots.push(a => dynamicFacetSlot(a, facet, providers));
@@ -1617,6 +1725,9 @@ class GardState {
1617
1725
  if (ext.provides)
1618
1726
  inner(ext.provides, prec);
1619
1727
  }
1728
+ else if (ext instanceof GardState.Field.Derived) {
1729
+ result[prec].push(ext);
1730
+ }
1620
1731
  else if (ext instanceof FacetProvider) {
1621
1732
  result[prec].push(ext);
1622
1733
  if (ext.facet.extensions)
@@ -1633,15 +1744,19 @@ class GardState {
1633
1744
  return result.reduce((a, b) => a.concat(b));
1634
1745
  }
1635
1746
  GardState.prec = {
1636
- highest: mkPrec(0),
1637
- high: mkPrec(1),
1638
- default: mkPrec(2),
1639
- low: mkPrec(3),
1640
- lowest: mkPrec(4)
1747
+ highest: mkPrec(0, "Highest"),
1748
+ high: mkPrec(1, "High"),
1749
+ default: mkPrec(2, "Default"),
1750
+ low: mkPrec(3, "Low"),
1751
+ lowest: mkPrec(4, "Lowest")
1641
1752
  };
1642
1753
  class Compartment {
1643
- constructor() { }
1644
- static define() { return new Compartment; }
1754
+ name;
1755
+ constructor(
1756
+ name) {
1757
+ this.name = name;
1758
+ }
1759
+ static define(name) { return new Compartment(name || null); }
1645
1760
  of(ext) { return new CompartmentInstance(this, ext); }
1646
1761
  reconfigure(content) {
1647
1762
  return GardState.Compartment.reconfigureCompartment.of({ compartment: this, extension: content });
@@ -1649,28 +1764,35 @@ class GardState {
1649
1764
  get(state) {
1650
1765
  return state.config.compartments.get(this);
1651
1766
  }
1652
- static reconfigureCompartment = Transaction.Effect.define();
1767
+ static reconfigureCompartment = Transaction.Effect.define({ name: "reconfigureCompartment" });
1768
+ toString() { return "Compartment" + (this.name ? ":" + this.name : ""); }
1653
1769
  }
1654
1770
  GardState.Compartment = Compartment;
1655
1771
  GardState.schemaElement = GardState.Facet.define({
1772
+ name: "schemaElement",
1656
1773
  combine: values => values.reduce((set, elt) => set.concat(elt), none),
1657
1774
  static: true
1658
1775
  });
1659
1776
  GardState.readOnly = GardState.Facet.define({
1777
+ name: "readOnly",
1660
1778
  combine: values => values.length ? values[0] : false
1661
1779
  });
1662
1780
  GardState.textLTR = GardState.Facet.define({
1781
+ name: "textLTR",
1663
1782
  combine: values => values.length ? values[0] : true,
1664
1783
  static: true
1665
1784
  });
1666
1785
  GardState.textblockLTR = GardState.Facet.define({
1786
+ name: "textblockLTR",
1667
1787
  static: true
1668
1788
  });
1669
1789
  GardState.visualCursorMotion = GardState.Facet.define({
1790
+ name: "visualCursorMotion",
1670
1791
  combine(values) { return !values.length ? true : values[0]; },
1671
1792
  static: true
1672
1793
  });
1673
1794
  GardState.isAtom = GardState.Facet.define({
1795
+ name: "isAtom",
1674
1796
  static: true,
1675
1797
  combine(inputs) {
1676
1798
  let map = new Map();
@@ -1680,22 +1802,28 @@ class GardState {
1680
1802
  }
1681
1803
  });
1682
1804
  ;return GardState})(GardState);
1683
- const initField = /*@__PURE__*/GardState.Facet.define({ static: true });
1805
+ const initField = /*@__PURE__*/GardState.Facet.define({
1806
+ name: "init",
1807
+ static: true
1808
+ });
1684
1809
  function addValue(set, value) {
1685
1810
  if (set.indexOf(value) < 0)
1686
1811
  set.push(value);
1687
1812
  }
1688
- function mkPrec(value) {
1689
- return (ext) => new PrecExtension(ext, value);
1813
+ function mkPrec(value, name) {
1814
+ return (ext) => new PrecExtension(ext, value, name);
1690
1815
  }
1691
1816
  class PrecExtension {
1692
1817
  inner;
1693
1818
  prec;
1694
- constructor(inner, prec) {
1819
+ name;
1820
+ constructor(inner, prec, name) {
1695
1821
  this.inner = inner;
1696
1822
  this.prec = prec;
1823
+ this.name = name;
1697
1824
  }
1698
1825
  extension;
1826
+ toString() { return `Prec.${this.name}(${this.inner})`; }
1699
1827
  }
1700
1828
  function sameArray(a, b) {
1701
1829
  return a == b || a.length == b.length && a.every((e, i) => e === b[i]);
@@ -1722,61 +1850,18 @@ class DependencySet {
1722
1850
  }
1723
1851
  class FacetProvider {
1724
1852
  facet;
1853
+ id;
1725
1854
  flags;
1726
1855
  value;
1727
- id = nextID++;
1728
- extension; dependencies;
1729
- constructor(dependencies, facet, flags, value) {
1856
+ extension; constructor(facet,
1857
+ id, flags,
1858
+ value) {
1730
1859
  this.facet = facet;
1860
+ this.id = id;
1731
1861
  this.flags = flags;
1732
1862
  this.value = value;
1733
- this.dependencies = dependencies; }
1734
- dynamicSlot(addresses) {
1735
- let getter = this.value;
1736
- let compare = this.facet.compareInput;
1737
- let id = this.id, idx = addresses[id] >> 1;
1738
- let multi = this.flags & 2;
1739
- let dependencies = this.dependencies;
1740
- let auto = this.flags & 4 ? dependencies : null;
1741
- let depSet = new DependencySet;
1742
- return {
1743
- create(state) {
1744
- state.values[idx] = state.recordAccess(auto, getter);
1745
- return 1;
1746
- },
1747
- update(state, tr) {
1748
- depSet.update(dependencies, addresses);
1749
- if ((depSet.doc && tr.docChanged) || (depSet.sel && (tr.docChanged || tr.selection)) ||
1750
- (depSet.schema && tr.startState.schema != state.schema) || ensureAll(state, depSet.addrs)) {
1751
- let newVal = state.recordAccess(auto, getter);
1752
- if (multi ? !compareArray(newVal, state.values[idx], compare) : !compare(newVal, state.values[idx])) {
1753
- state.values[idx] = newVal;
1754
- return 1;
1755
- }
1756
- }
1757
- return 0;
1758
- },
1759
- reconfigure(state, oldState) {
1760
- let newVal, oldAddr = oldState.config.address[id];
1761
- if (oldAddr != null) {
1762
- let oldVal = getAddr(oldState, oldAddr);
1763
- if (dependencies.every(dep => {
1764
- return dep instanceof GardState.Facet ? oldState.facet(dep) === state.facet(dep)
1765
- : dep instanceof GardState.Field ? oldState.field(dep, false) == state.field(dep, false)
1766
- : true;
1767
- }) || (multi ? compareArray(newVal = getter(state), oldVal, compare) : compare(newVal = getter(state), oldVal))) {
1768
- state.values[idx] = oldVal;
1769
- return 0;
1770
- }
1771
- }
1772
- else {
1773
- newVal = state.recordAccess(auto, getter);
1774
- }
1775
- state.values[idx] = newVal;
1776
- return 1;
1777
- }
1778
- };
1779
1863
  }
1864
+ toString() { return `${this.facet}(${this.flags & 1 ? debugString(this.value) : "dynamic"})`; }
1780
1865
  }
1781
1866
  function compareArray(a, b, compare) {
1782
1867
  if (a.length != b.length)
@@ -1866,8 +1951,10 @@ class CompartmentInstance {
1866
1951
  this.inner = inner;
1867
1952
  }
1868
1953
  extension;
1954
+ toString() { return `${this.compartment}(${this.inner})`; }
1869
1955
  }
1870
1956
  GardSelection = /*@__PURE__*/(GardSelection => {GardSelection.selectionType = GardState.Facet.define({
1957
+ name: "selectionType",
1871
1958
  combine(values) {
1872
1959
  let types = [GardSelection.Text.type, GardSelection.Node.type, ...values];
1873
1960
  for (let i = 0; i < types.length; i++)
@@ -1879,8 +1966,8 @@ GardSelection = /*@__PURE__*/(GardSelection => {GardSelection.selectionType = Ga
1879
1966
  },
1880
1967
  static: true
1881
1968
  }); return GardSelection})(GardSelection);
1882
- Transaction = /*@__PURE__*/(Transaction => {Transaction.extender = GardState.Facet.define(); return Transaction})(Transaction);
1883
- Transaction = /*@__PURE__*/(Transaction => {Transaction.appender = GardState.Facet.define(); return Transaction})(Transaction);
1969
+ Transaction = /*@__PURE__*/(Transaction => {Transaction.extender = GardState.Facet.define({ name: "extender" }); return Transaction})(Transaction);
1970
+ Transaction = /*@__PURE__*/(Transaction => {Transaction.appender = GardState.Facet.define({ name: "appender" }); return Transaction})(Transaction);
1884
1971
 
1885
1972
  function scanChanges(changes, doc, corrections) {
1886
1973
  let buckets = [[], [], []], [childList, content, marks] = buckets;
@@ -1973,7 +2060,7 @@ function scanChanges(changes, doc, corrections) {
1973
2060
  }
1974
2061
  return plan;
1975
2062
  }
1976
- const corrections = /*@__PURE__*/GardState.Facet.define();
2063
+ const corrections = /*@__PURE__*/GardState.Facet.define({ name: "corrections" });
1977
2064
  const planCache = /*@__PURE__*/(() => new WeakMap())();
1978
2065
  class Correction {
1979
2066
  event;
@@ -2042,6 +2129,7 @@ class Correction {
2042
2129
  }
2043
2130
  return changed.length ? ChangeSet.create(doc, changed) : null;
2044
2131
  }
2132
+ toString() { return `Correction(${Node.queryToString(this.query)})`; }
2045
2133
  }
2046
2134
 
2047
2135
  export { BidiSpan, Correction, GardSelection, GardState, TextblockMap, Transaction };