@codemirror/state 0.19.2 → 0.19.6

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/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ## 0.19.6 (2021-11-19)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix a bug that caused facet compare functions to be called with an invalid value in some situations.
6
+
7
+ Fix a bug that caused dynamic facet values to be incorrectly kept unchanged when reconfiguration changed one of their dependencies.
8
+
9
+ ## 0.19.5 (2021-11-10)
10
+
11
+ ### Bug fixes
12
+
13
+ Fix a bug that would cause dynamic facet values influenced by a state reconfiguration to not properly recompute.
14
+
15
+ ## 0.19.4 (2021-11-05)
16
+
17
+ ### Bug fixes
18
+
19
+ When reconfiguring a state, effects from the reconfiguring transaction can now be seen by newly added state fields.
20
+
21
+ ## 0.19.3 (2021-11-03)
22
+
23
+ ### New features
24
+
25
+ The precedence levels (under `Prec`) now have more generic names, because their 'meaningful' names were entirely inappropriate in many situations.
26
+
1
27
  ## 0.19.2 (2021-09-13)
2
28
 
3
29
  ### New features
package/dist/index.cjs CHANGED
@@ -967,21 +967,23 @@ class FacetProvider {
967
967
  depAddrs.push(addresses[dep.id]);
968
968
  }
969
969
  return (state, tr) => {
970
- if (!tr || tr.reconfigured) {
970
+ let oldVal = state.values[idx];
971
+ if (oldVal === Uninitialized) {
971
972
  state.values[idx] = getter(state);
972
973
  return 1 /* Changed */;
973
974
  }
974
- else {
975
+ if (tr) {
975
976
  let depChanged = (depDoc && tr.docChanged) || (depSel && (tr.docChanged || tr.selection)) ||
976
977
  depAddrs.some(addr => (ensureAddr(state, addr) & 1 /* Changed */) > 0);
977
- if (!depChanged)
978
- return 0;
979
- let newVal = getter(state), oldVal = tr.startState.values[idx];
980
- if (multi ? compareArray(newVal, oldVal, compare) : compare(newVal, oldVal))
981
- return 0;
982
- state.values[idx] = newVal;
983
- return 1 /* Changed */;
978
+ if (depChanged) {
979
+ let newVal = getter(state);
980
+ if (multi ? !compareArray(newVal, oldVal, compare) : !compare(newVal, oldVal)) {
981
+ state.values[idx] = newVal;
982
+ return 1 /* Changed */;
983
+ }
984
+ }
984
985
  }
986
+ return 0;
985
987
  };
986
988
  }
987
989
  }
@@ -999,8 +1001,7 @@ function dynamicFacetSlot(addresses, facet, providers) {
999
1001
  let dynamic = providerAddrs.filter(p => !(p & 1));
1000
1002
  let idx = addresses[facet.id] >> 1;
1001
1003
  return (state, tr) => {
1002
- let oldAddr = !tr ? null : tr.reconfigured ? tr.startState.config.address[facet.id] : idx << 1;
1003
- let changed = oldAddr == null;
1004
+ let oldVal = state.values[idx], changed = oldVal === Uninitialized || !tr;
1004
1005
  for (let dynAddr of dynamic) {
1005
1006
  if (ensureAddr(state, dynAddr) & 1 /* Changed */)
1006
1007
  changed = true;
@@ -1016,17 +1017,13 @@ function dynamicFacetSlot(addresses, facet, providers) {
1016
1017
  else
1017
1018
  values.push(value);
1018
1019
  }
1019
- let newVal = facet.combine(values);
1020
- if (oldAddr != null && facet.compare(newVal, getAddr(tr.startState, oldAddr)))
1020
+ let value = facet.combine(values);
1021
+ if (oldVal !== Uninitialized && facet.compare(value, oldVal))
1021
1022
  return 0;
1022
- state.values[idx] = newVal;
1023
+ state.values[idx] = value;
1023
1024
  return 1 /* Changed */;
1024
1025
  };
1025
1026
  }
1026
- function maybeIndex(state, id) {
1027
- let found = state.config.address[id];
1028
- return found == null ? null : found >> 1;
1029
- }
1030
1027
  const initField = Facet.define({ static: true });
1031
1028
  /**
1032
1029
  Fields can store additional information in an editor state, and
@@ -1071,24 +1068,19 @@ class StateField {
1071
1068
  slot(addresses) {
1072
1069
  let idx = addresses[this.id] >> 1;
1073
1070
  return (state, tr) => {
1074
- if (!tr || (tr.reconfigured && maybeIndex(tr.startState, this.id) == null)) {
1071
+ let oldVal = state.values[idx];
1072
+ if (oldVal === Uninitialized) {
1075
1073
  state.values[idx] = this.create(state);
1076
1074
  return 1 /* Changed */;
1077
1075
  }
1078
- let oldVal, changed = 0;
1079
- if (tr.reconfigured) {
1080
- oldVal = tr.startState.values[maybeIndex(tr.startState, this.id)];
1081
- changed = 1 /* Changed */;
1082
- }
1083
- else {
1084
- oldVal = tr.startState.values[idx];
1076
+ if (tr) {
1077
+ let value = this.updateF(oldVal, tr);
1078
+ if (!this.compareF(oldVal, value)) {
1079
+ state.values[idx] = value;
1080
+ return 1 /* Changed */;
1081
+ }
1085
1082
  }
1086
- let value = this.updateF(oldVal, tr);
1087
- if (!changed && !this.compareF(oldVal, value))
1088
- changed = 1 /* Changed */;
1089
- if (changed)
1090
- state.values[idx] = value;
1091
- return changed;
1083
+ return 0;
1092
1084
  };
1093
1085
  }
1094
1086
  /**
@@ -1106,7 +1098,7 @@ class StateField {
1106
1098
  */
1107
1099
  get extension() { return this; }
1108
1100
  }
1109
- const Prec_ = { fallback: 3, default: 2, extend: 1, override: 0 };
1101
+ const Prec_ = { lowest: 4, low: 3, default: 2, high: 1, highest: 0 };
1110
1102
  function prec(value) {
1111
1103
  return (ext) => new PrecExtension(ext, value);
1112
1104
  }
@@ -1122,23 +1114,42 @@ precedence and then by order within each precedence.
1122
1114
  */
1123
1115
  const Prec = {
1124
1116
  /**
1125
- A precedence below the default precedence, which will cause
1126
- default-precedence extensions to override it even if they are
1127
- specified later in the extension ordering.
1117
+ The lowest precedence level. Meant for things that should end up
1118
+ near the end of the extension order.
1119
+ */
1120
+ lowest: prec(Prec_.lowest),
1121
+ /**
1122
+ A lower-than-default precedence, for extensions.
1128
1123
  */
1129
- fallback: prec(Prec_.fallback),
1124
+ low: prec(Prec_.low),
1130
1125
  /**
1131
- The regular default precedence.
1126
+ The default precedence, which is also used for extensions
1127
+ without an explicit precedence.
1132
1128
  */
1133
1129
  default: prec(Prec_.default),
1134
1130
  /**
1135
- A higher-than-default precedence.
1131
+ A higher-than-default precedence, for extensions that should
1132
+ come before those with default precedence.
1133
+ */
1134
+ high: prec(Prec_.high),
1135
+ /**
1136
+ The highest precedence level, for extensions that should end up
1137
+ near the start of the precedence ordering.
1138
+ */
1139
+ highest: prec(Prec_.highest),
1140
+ // FIXME Drop these in some future breaking version
1141
+ /**
1142
+ Backwards-compatible synonym for `Prec.lowest`.
1136
1143
  */
1137
- extend: prec(Prec_.extend),
1144
+ fallback: prec(Prec_.lowest),
1138
1145
  /**
1139
- Precedence above the `default` and `extend` precedences.
1146
+ Backwards-compatible synonym for `Prec.high`.
1140
1147
  */
1141
- override: prec(Prec_.override)
1148
+ extend: prec(Prec_.high),
1149
+ /**
1150
+ Backwards-compatible synonym for `Prec.highest`.
1151
+ */
1152
+ override: prec(Prec_.highest)
1142
1153
  };
1143
1154
  class PrecExtension {
1144
1155
  constructor(inner, prec) {
@@ -1189,7 +1200,7 @@ class Configuration {
1189
1200
  this.staticValues = staticValues;
1190
1201
  this.statusTemplate = [];
1191
1202
  while (this.statusTemplate.length < dynamicSlots.length)
1192
- this.statusTemplate.push(0 /* Uninitialized */);
1203
+ this.statusTemplate.push(0 /* Unresolved */);
1193
1204
  }
1194
1205
  staticFacet(facet) {
1195
1206
  let addr = this.address[facet.id];
@@ -1208,9 +1219,11 @@ class Configuration {
1208
1219
  let address = Object.create(null);
1209
1220
  let staticValues = [];
1210
1221
  let dynamicSlots = [];
1222
+ let dynamicDeps = [];
1211
1223
  for (let field of fields) {
1212
1224
  address[field.id] = dynamicSlots.length << 1;
1213
1225
  dynamicSlots.push(a => field.slot(a));
1226
+ dynamicDeps.push([]);
1214
1227
  }
1215
1228
  for (let id in facets) {
1216
1229
  let providers = facets[id], facet = providers[0].facet;
@@ -1234,17 +1247,41 @@ class Configuration {
1234
1247
  else {
1235
1248
  address[p.id] = dynamicSlots.length << 1;
1236
1249
  dynamicSlots.push(a => p.dynamicSlot(a));
1250
+ dynamicDeps.push(p.dependencies.filter(d => typeof d != "string").map(d => d.id));
1237
1251
  }
1238
1252
  }
1239
1253
  address[facet.id] = dynamicSlots.length << 1;
1240
1254
  dynamicSlots.push(a => dynamicFacetSlot(a, facet, providers));
1255
+ dynamicDeps.push(providers.filter(p => p.type != 0 /* Static */).map(d => d.id));
1256
+ }
1257
+ }
1258
+ let dynamicValues = dynamicSlots.map(_ => Uninitialized);
1259
+ if (oldState) {
1260
+ let canReuse = (id, depth) => {
1261
+ if (depth > 7)
1262
+ return false;
1263
+ let addr = address[id];
1264
+ if (!(addr & 1))
1265
+ return dynamicDeps[addr >> 1].every(id => canReuse(id, depth + 1));
1266
+ let oldAddr = oldState.config.address[id];
1267
+ return oldAddr != null && getAddr(oldState, oldAddr) == staticValues[addr >> 1];
1268
+ };
1269
+ // Copy over old values for shared facets/fields, if we can
1270
+ // prove that they don't need to be recomputed.
1271
+ for (let id in address) {
1272
+ let cur = address[id], prev = oldState.config.address[id];
1273
+ if (prev != null && (cur & 1) == 0 && canReuse(+id, 0))
1274
+ dynamicValues[cur >> 1] = getAddr(oldState, prev);
1241
1275
  }
1242
1276
  }
1243
- return new Configuration(base, newCompartments, dynamicSlots.map(f => f(address)), address, staticValues);
1277
+ return {
1278
+ configuration: new Configuration(base, newCompartments, dynamicSlots.map(f => f(address)), address, staticValues),
1279
+ values: dynamicValues
1280
+ };
1244
1281
  }
1245
1282
  }
1246
1283
  function flatten(extension, compartments, newCompartments) {
1247
- let result = [[], [], [], []];
1284
+ let result = [[], [], [], [], []];
1248
1285
  let seen = new Map();
1249
1286
  function inner(ext, prec) {
1250
1287
  let known = seen.get(ext);
@@ -1292,6 +1329,7 @@ function flatten(extension, compartments, newCompartments) {
1292
1329
  inner(extension, Prec_.default);
1293
1330
  return result.reduce((a, b) => a.concat(b));
1294
1331
  }
1332
+ const Uninitialized = {};
1295
1333
  function ensureAddr(state, addr) {
1296
1334
  if (addr & 1)
1297
1335
  return 2 /* Computed */;
@@ -1576,7 +1614,7 @@ class Transaction {
1576
1614
  */
1577
1615
  isUserEvent(event) {
1578
1616
  let e = this.annotation(Transaction.userEvent);
1579
- return e && (e == event || e.length > event.length && e.slice(0, event.length) == event && e[event.length] == ".");
1617
+ return !!(e && (e == event || e.length > event.length && e.slice(0, event.length) == event && e[event.length] == "."));
1580
1618
  }
1581
1619
  }
1582
1620
  /**
@@ -1817,28 +1855,20 @@ class EditorState {
1817
1855
  /**
1818
1856
  The current selection.
1819
1857
  */
1820
- selection, tr = null) {
1858
+ selection,
1859
+ /**
1860
+ @internal
1861
+ */
1862
+ values, tr = null) {
1821
1863
  this.config = config;
1822
1864
  this.doc = doc;
1823
1865
  this.selection = selection;
1866
+ this.values = values;
1824
1867
  /**
1825
1868
  @internal
1826
1869
  */
1827
1870
  this.applying = null;
1828
1871
  this.status = config.statusTemplate.slice();
1829
- if (tr && tr.startState.config == config) {
1830
- this.values = tr.startState.values.slice();
1831
- }
1832
- else {
1833
- this.values = config.dynamicSlots.map(_ => null);
1834
- // Copy over old values for shared facets/fields if this is a reconfigure
1835
- if (tr)
1836
- for (let id in config.address) {
1837
- let cur = config.address[id], prev = tr.startState.config.address[id];
1838
- if (prev != null && (cur & 1) == 0)
1839
- this.values[cur >> 1] = getAddr(tr.startState, prev);
1840
- }
1841
- }
1842
1872
  this.applying = tr;
1843
1873
  // Fill in the computed state immediately, so that further queries
1844
1874
  // for it made during the update return this state
@@ -1899,7 +1929,17 @@ class EditorState {
1899
1929
  base = asArray(base).concat(effect.value);
1900
1930
  }
1901
1931
  }
1902
- new EditorState(conf || Configuration.resolve(base, compartments, this), tr.newDoc, tr.newSelection, tr);
1932
+ let startValues;
1933
+ if (!conf) {
1934
+ let resolved = Configuration.resolve(base, compartments, this);
1935
+ conf = resolved.configuration;
1936
+ let intermediateState = new EditorState(conf, this.doc, this.selection, resolved.values, null);
1937
+ startValues = intermediateState.values;
1938
+ }
1939
+ else {
1940
+ startValues = tr.startState.values.slice();
1941
+ }
1942
+ new EditorState(conf, tr.newDoc, tr.newSelection, startValues, tr);
1903
1943
  }
1904
1944
  /**
1905
1945
  Create a [transaction spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec) that
@@ -2023,7 +2063,7 @@ class EditorState {
2023
2063
  transactions.
2024
2064
  */
2025
2065
  static create(config = {}) {
2026
- let configuration = Configuration.resolve(config.extensions || [], new Map);
2066
+ let { configuration, values } = Configuration.resolve(config.extensions || [], new Map);
2027
2067
  let doc = config.doc instanceof text.Text ? config.doc
2028
2068
  : text.Text.of((config.doc || "").split(configuration.staticFacet(EditorState.lineSeparator) || DefaultSplit));
2029
2069
  let selection = !config.selection ? EditorSelection.single(0)
@@ -2032,7 +2072,7 @@ class EditorState {
2032
2072
  checkSelection(selection, doc.length);
2033
2073
  if (!configuration.staticFacet(allowMultipleSelections))
2034
2074
  selection = selection.asSingle();
2035
- return new EditorState(configuration, doc, selection);
2075
+ return new EditorState(configuration, doc, selection, values);
2036
2076
  }
2037
2077
  /**
2038
2078
  The size (in columns) of a tab in the document, determined by
package/dist/index.d.ts CHANGED
@@ -509,21 +509,39 @@ precedence and then by order within each precedence.
509
509
  */
510
510
  declare const Prec: {
511
511
  /**
512
- A precedence below the default precedence, which will cause
513
- default-precedence extensions to override it even if they are
514
- specified later in the extension ordering.
512
+ The lowest precedence level. Meant for things that should end up
513
+ near the end of the extension order.
515
514
  */
516
- fallback: (ext: Extension) => Extension;
515
+ lowest: (ext: Extension) => Extension;
516
+ /**
517
+ A lower-than-default precedence, for extensions.
518
+ */
519
+ low: (ext: Extension) => Extension;
517
520
  /**
518
- The regular default precedence.
521
+ The default precedence, which is also used for extensions
522
+ without an explicit precedence.
519
523
  */
520
524
  default: (ext: Extension) => Extension;
521
525
  /**
522
- A higher-than-default precedence.
526
+ A higher-than-default precedence, for extensions that should
527
+ come before those with default precedence.
528
+ */
529
+ high: (ext: Extension) => Extension;
530
+ /**
531
+ The highest precedence level, for extensions that should end up
532
+ near the start of the precedence ordering.
533
+ */
534
+ highest: (ext: Extension) => Extension;
535
+ /**
536
+ Backwards-compatible synonym for `Prec.lowest`.
537
+ */
538
+ fallback: (ext: Extension) => Extension;
539
+ /**
540
+ Backwards-compatible synonym for `Prec.high`.
523
541
  */
524
542
  extend: (ext: Extension) => Extension;
525
543
  /**
526
- Precedence above the `default` and `extend` precedences.
544
+ Backwards-compatible synonym for `Prec.highest`.
527
545
  */
528
546
  override: (ext: Extension) => Extension;
529
547
  };
@@ -783,7 +801,7 @@ declare class Transaction {
783
801
  has `"select.pointer"` as user event, `"select"` and
784
802
  `"select.pointer"` will match it.
785
803
  */
786
- isUserEvent(event: string): boolean | "" | undefined;
804
+ isUserEvent(event: string): boolean;
787
805
  /**
788
806
  Annotation used to store transaction timestamps.
789
807
  */
package/dist/index.js CHANGED
@@ -963,21 +963,23 @@ class FacetProvider {
963
963
  depAddrs.push(addresses[dep.id]);
964
964
  }
965
965
  return (state, tr) => {
966
- if (!tr || tr.reconfigured) {
966
+ let oldVal = state.values[idx];
967
+ if (oldVal === Uninitialized) {
967
968
  state.values[idx] = getter(state);
968
969
  return 1 /* Changed */;
969
970
  }
970
- else {
971
+ if (tr) {
971
972
  let depChanged = (depDoc && tr.docChanged) || (depSel && (tr.docChanged || tr.selection)) ||
972
973
  depAddrs.some(addr => (ensureAddr(state, addr) & 1 /* Changed */) > 0);
973
- if (!depChanged)
974
- return 0;
975
- let newVal = getter(state), oldVal = tr.startState.values[idx];
976
- if (multi ? compareArray(newVal, oldVal, compare) : compare(newVal, oldVal))
977
- return 0;
978
- state.values[idx] = newVal;
979
- return 1 /* Changed */;
974
+ if (depChanged) {
975
+ let newVal = getter(state);
976
+ if (multi ? !compareArray(newVal, oldVal, compare) : !compare(newVal, oldVal)) {
977
+ state.values[idx] = newVal;
978
+ return 1 /* Changed */;
979
+ }
980
+ }
980
981
  }
982
+ return 0;
981
983
  };
982
984
  }
983
985
  }
@@ -995,8 +997,7 @@ function dynamicFacetSlot(addresses, facet, providers) {
995
997
  let dynamic = providerAddrs.filter(p => !(p & 1));
996
998
  let idx = addresses[facet.id] >> 1;
997
999
  return (state, tr) => {
998
- let oldAddr = !tr ? null : tr.reconfigured ? tr.startState.config.address[facet.id] : idx << 1;
999
- let changed = oldAddr == null;
1000
+ let oldVal = state.values[idx], changed = oldVal === Uninitialized || !tr;
1000
1001
  for (let dynAddr of dynamic) {
1001
1002
  if (ensureAddr(state, dynAddr) & 1 /* Changed */)
1002
1003
  changed = true;
@@ -1012,17 +1013,13 @@ function dynamicFacetSlot(addresses, facet, providers) {
1012
1013
  else
1013
1014
  values.push(value);
1014
1015
  }
1015
- let newVal = facet.combine(values);
1016
- if (oldAddr != null && facet.compare(newVal, getAddr(tr.startState, oldAddr)))
1016
+ let value = facet.combine(values);
1017
+ if (oldVal !== Uninitialized && facet.compare(value, oldVal))
1017
1018
  return 0;
1018
- state.values[idx] = newVal;
1019
+ state.values[idx] = value;
1019
1020
  return 1 /* Changed */;
1020
1021
  };
1021
1022
  }
1022
- function maybeIndex(state, id) {
1023
- let found = state.config.address[id];
1024
- return found == null ? null : found >> 1;
1025
- }
1026
1023
  const initField = /*@__PURE__*/Facet.define({ static: true });
1027
1024
  /**
1028
1025
  Fields can store additional information in an editor state, and
@@ -1067,24 +1064,19 @@ class StateField {
1067
1064
  slot(addresses) {
1068
1065
  let idx = addresses[this.id] >> 1;
1069
1066
  return (state, tr) => {
1070
- if (!tr || (tr.reconfigured && maybeIndex(tr.startState, this.id) == null)) {
1067
+ let oldVal = state.values[idx];
1068
+ if (oldVal === Uninitialized) {
1071
1069
  state.values[idx] = this.create(state);
1072
1070
  return 1 /* Changed */;
1073
1071
  }
1074
- let oldVal, changed = 0;
1075
- if (tr.reconfigured) {
1076
- oldVal = tr.startState.values[maybeIndex(tr.startState, this.id)];
1077
- changed = 1 /* Changed */;
1078
- }
1079
- else {
1080
- oldVal = tr.startState.values[idx];
1072
+ if (tr) {
1073
+ let value = this.updateF(oldVal, tr);
1074
+ if (!this.compareF(oldVal, value)) {
1075
+ state.values[idx] = value;
1076
+ return 1 /* Changed */;
1077
+ }
1081
1078
  }
1082
- let value = this.updateF(oldVal, tr);
1083
- if (!changed && !this.compareF(oldVal, value))
1084
- changed = 1 /* Changed */;
1085
- if (changed)
1086
- state.values[idx] = value;
1087
- return changed;
1079
+ return 0;
1088
1080
  };
1089
1081
  }
1090
1082
  /**
@@ -1102,7 +1094,7 @@ class StateField {
1102
1094
  */
1103
1095
  get extension() { return this; }
1104
1096
  }
1105
- const Prec_ = { fallback: 3, default: 2, extend: 1, override: 0 };
1097
+ const Prec_ = { lowest: 4, low: 3, default: 2, high: 1, highest: 0 };
1106
1098
  function prec(value) {
1107
1099
  return (ext) => new PrecExtension(ext, value);
1108
1100
  }
@@ -1118,23 +1110,42 @@ precedence and then by order within each precedence.
1118
1110
  */
1119
1111
  const Prec = {
1120
1112
  /**
1121
- A precedence below the default precedence, which will cause
1122
- default-precedence extensions to override it even if they are
1123
- specified later in the extension ordering.
1113
+ The lowest precedence level. Meant for things that should end up
1114
+ near the end of the extension order.
1115
+ */
1116
+ lowest: /*@__PURE__*/prec(Prec_.lowest),
1117
+ /**
1118
+ A lower-than-default precedence, for extensions.
1124
1119
  */
1125
- fallback: /*@__PURE__*/prec(Prec_.fallback),
1120
+ low: /*@__PURE__*/prec(Prec_.low),
1126
1121
  /**
1127
- The regular default precedence.
1122
+ The default precedence, which is also used for extensions
1123
+ without an explicit precedence.
1128
1124
  */
1129
1125
  default: /*@__PURE__*/prec(Prec_.default),
1130
1126
  /**
1131
- A higher-than-default precedence.
1127
+ A higher-than-default precedence, for extensions that should
1128
+ come before those with default precedence.
1129
+ */
1130
+ high: /*@__PURE__*/prec(Prec_.high),
1131
+ /**
1132
+ The highest precedence level, for extensions that should end up
1133
+ near the start of the precedence ordering.
1134
+ */
1135
+ highest: /*@__PURE__*/prec(Prec_.highest),
1136
+ // FIXME Drop these in some future breaking version
1137
+ /**
1138
+ Backwards-compatible synonym for `Prec.lowest`.
1132
1139
  */
1133
- extend: /*@__PURE__*/prec(Prec_.extend),
1140
+ fallback: /*@__PURE__*/prec(Prec_.lowest),
1134
1141
  /**
1135
- Precedence above the `default` and `extend` precedences.
1142
+ Backwards-compatible synonym for `Prec.high`.
1136
1143
  */
1137
- override: /*@__PURE__*/prec(Prec_.override)
1144
+ extend: /*@__PURE__*/prec(Prec_.high),
1145
+ /**
1146
+ Backwards-compatible synonym for `Prec.highest`.
1147
+ */
1148
+ override: /*@__PURE__*/prec(Prec_.highest)
1138
1149
  };
1139
1150
  class PrecExtension {
1140
1151
  constructor(inner, prec) {
@@ -1185,7 +1196,7 @@ class Configuration {
1185
1196
  this.staticValues = staticValues;
1186
1197
  this.statusTemplate = [];
1187
1198
  while (this.statusTemplate.length < dynamicSlots.length)
1188
- this.statusTemplate.push(0 /* Uninitialized */);
1199
+ this.statusTemplate.push(0 /* Unresolved */);
1189
1200
  }
1190
1201
  staticFacet(facet) {
1191
1202
  let addr = this.address[facet.id];
@@ -1204,9 +1215,11 @@ class Configuration {
1204
1215
  let address = Object.create(null);
1205
1216
  let staticValues = [];
1206
1217
  let dynamicSlots = [];
1218
+ let dynamicDeps = [];
1207
1219
  for (let field of fields) {
1208
1220
  address[field.id] = dynamicSlots.length << 1;
1209
1221
  dynamicSlots.push(a => field.slot(a));
1222
+ dynamicDeps.push([]);
1210
1223
  }
1211
1224
  for (let id in facets) {
1212
1225
  let providers = facets[id], facet = providers[0].facet;
@@ -1230,17 +1243,41 @@ class Configuration {
1230
1243
  else {
1231
1244
  address[p.id] = dynamicSlots.length << 1;
1232
1245
  dynamicSlots.push(a => p.dynamicSlot(a));
1246
+ dynamicDeps.push(p.dependencies.filter(d => typeof d != "string").map(d => d.id));
1233
1247
  }
1234
1248
  }
1235
1249
  address[facet.id] = dynamicSlots.length << 1;
1236
1250
  dynamicSlots.push(a => dynamicFacetSlot(a, facet, providers));
1251
+ dynamicDeps.push(providers.filter(p => p.type != 0 /* Static */).map(d => d.id));
1252
+ }
1253
+ }
1254
+ let dynamicValues = dynamicSlots.map(_ => Uninitialized);
1255
+ if (oldState) {
1256
+ let canReuse = (id, depth) => {
1257
+ if (depth > 7)
1258
+ return false;
1259
+ let addr = address[id];
1260
+ if (!(addr & 1))
1261
+ return dynamicDeps[addr >> 1].every(id => canReuse(id, depth + 1));
1262
+ let oldAddr = oldState.config.address[id];
1263
+ return oldAddr != null && getAddr(oldState, oldAddr) == staticValues[addr >> 1];
1264
+ };
1265
+ // Copy over old values for shared facets/fields, if we can
1266
+ // prove that they don't need to be recomputed.
1267
+ for (let id in address) {
1268
+ let cur = address[id], prev = oldState.config.address[id];
1269
+ if (prev != null && (cur & 1) == 0 && canReuse(+id, 0))
1270
+ dynamicValues[cur >> 1] = getAddr(oldState, prev);
1237
1271
  }
1238
1272
  }
1239
- return new Configuration(base, newCompartments, dynamicSlots.map(f => f(address)), address, staticValues);
1273
+ return {
1274
+ configuration: new Configuration(base, newCompartments, dynamicSlots.map(f => f(address)), address, staticValues),
1275
+ values: dynamicValues
1276
+ };
1240
1277
  }
1241
1278
  }
1242
1279
  function flatten(extension, compartments, newCompartments) {
1243
- let result = [[], [], [], []];
1280
+ let result = [[], [], [], [], []];
1244
1281
  let seen = new Map();
1245
1282
  function inner(ext, prec) {
1246
1283
  let known = seen.get(ext);
@@ -1288,6 +1325,7 @@ function flatten(extension, compartments, newCompartments) {
1288
1325
  inner(extension, Prec_.default);
1289
1326
  return result.reduce((a, b) => a.concat(b));
1290
1327
  }
1328
+ const Uninitialized = {};
1291
1329
  function ensureAddr(state, addr) {
1292
1330
  if (addr & 1)
1293
1331
  return 2 /* Computed */;
@@ -1572,7 +1610,7 @@ class Transaction {
1572
1610
  */
1573
1611
  isUserEvent(event) {
1574
1612
  let e = this.annotation(Transaction.userEvent);
1575
- return e && (e == event || e.length > event.length && e.slice(0, event.length) == event && e[event.length] == ".");
1613
+ return !!(e && (e == event || e.length > event.length && e.slice(0, event.length) == event && e[event.length] == "."));
1576
1614
  }
1577
1615
  }
1578
1616
  /**
@@ -1812,28 +1850,20 @@ class EditorState {
1812
1850
  /**
1813
1851
  The current selection.
1814
1852
  */
1815
- selection, tr = null) {
1853
+ selection,
1854
+ /**
1855
+ @internal
1856
+ */
1857
+ values, tr = null) {
1816
1858
  this.config = config;
1817
1859
  this.doc = doc;
1818
1860
  this.selection = selection;
1861
+ this.values = values;
1819
1862
  /**
1820
1863
  @internal
1821
1864
  */
1822
1865
  this.applying = null;
1823
1866
  this.status = config.statusTemplate.slice();
1824
- if (tr && tr.startState.config == config) {
1825
- this.values = tr.startState.values.slice();
1826
- }
1827
- else {
1828
- this.values = config.dynamicSlots.map(_ => null);
1829
- // Copy over old values for shared facets/fields if this is a reconfigure
1830
- if (tr)
1831
- for (let id in config.address) {
1832
- let cur = config.address[id], prev = tr.startState.config.address[id];
1833
- if (prev != null && (cur & 1) == 0)
1834
- this.values[cur >> 1] = getAddr(tr.startState, prev);
1835
- }
1836
- }
1837
1867
  this.applying = tr;
1838
1868
  // Fill in the computed state immediately, so that further queries
1839
1869
  // for it made during the update return this state
@@ -1894,7 +1924,17 @@ class EditorState {
1894
1924
  base = asArray(base).concat(effect.value);
1895
1925
  }
1896
1926
  }
1897
- new EditorState(conf || Configuration.resolve(base, compartments, this), tr.newDoc, tr.newSelection, tr);
1927
+ let startValues;
1928
+ if (!conf) {
1929
+ let resolved = Configuration.resolve(base, compartments, this);
1930
+ conf = resolved.configuration;
1931
+ let intermediateState = new EditorState(conf, this.doc, this.selection, resolved.values, null);
1932
+ startValues = intermediateState.values;
1933
+ }
1934
+ else {
1935
+ startValues = tr.startState.values.slice();
1936
+ }
1937
+ new EditorState(conf, tr.newDoc, tr.newSelection, startValues, tr);
1898
1938
  }
1899
1939
  /**
1900
1940
  Create a [transaction spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec) that
@@ -2018,7 +2058,7 @@ class EditorState {
2018
2058
  transactions.
2019
2059
  */
2020
2060
  static create(config = {}) {
2021
- let configuration = Configuration.resolve(config.extensions || [], new Map);
2061
+ let { configuration, values } = Configuration.resolve(config.extensions || [], new Map);
2022
2062
  let doc = config.doc instanceof Text ? config.doc
2023
2063
  : Text.of((config.doc || "").split(configuration.staticFacet(EditorState.lineSeparator) || DefaultSplit));
2024
2064
  let selection = !config.selection ? EditorSelection.single(0)
@@ -2027,7 +2067,7 @@ class EditorState {
2027
2067
  checkSelection(selection, doc.length);
2028
2068
  if (!configuration.staticFacet(allowMultipleSelections))
2029
2069
  selection = selection.asSingle();
2030
- return new EditorState(configuration, doc, selection);
2070
+ return new EditorState(configuration, doc, selection, values);
2031
2071
  }
2032
2072
  /**
2033
2073
  The size (in columns) of a tab in the document, determined by
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/state",
3
- "version": "0.19.2",
3
+ "version": "0.19.6",
4
4
  "description": "Editor state data structures for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",