@codemirror/state 0.19.5 → 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,11 @@
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
+
1
9
  ## 0.19.5 (2021-11-10)
2
10
 
3
11
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -1018,7 +1018,7 @@ function dynamicFacetSlot(addresses, facet, providers) {
1018
1018
  values.push(value);
1019
1019
  }
1020
1020
  let value = facet.combine(values);
1021
- if (facet.compare(value, oldVal))
1021
+ if (oldVal !== Uninitialized && facet.compare(value, oldVal))
1022
1022
  return 0;
1023
1023
  state.values[idx] = value;
1024
1024
  return 1 /* Changed */;
@@ -1219,9 +1219,11 @@ class Configuration {
1219
1219
  let address = Object.create(null);
1220
1220
  let staticValues = [];
1221
1221
  let dynamicSlots = [];
1222
+ let dynamicDeps = [];
1222
1223
  for (let field of fields) {
1223
1224
  address[field.id] = dynamicSlots.length << 1;
1224
1225
  dynamicSlots.push(a => field.slot(a));
1226
+ dynamicDeps.push([]);
1225
1227
  }
1226
1228
  for (let id in facets) {
1227
1229
  let providers = facets[id], facet = providers[0].facet;
@@ -1245,13 +1247,37 @@ class Configuration {
1245
1247
  else {
1246
1248
  address[p.id] = dynamicSlots.length << 1;
1247
1249
  dynamicSlots.push(a => p.dynamicSlot(a));
1250
+ dynamicDeps.push(p.dependencies.filter(d => typeof d != "string").map(d => d.id));
1248
1251
  }
1249
1252
  }
1250
1253
  address[facet.id] = dynamicSlots.length << 1;
1251
1254
  dynamicSlots.push(a => dynamicFacetSlot(a, facet, providers));
1255
+ dynamicDeps.push(providers.filter(p => p.type != 0 /* Static */).map(d => d.id));
1252
1256
  }
1253
1257
  }
1254
- return new Configuration(base, newCompartments, dynamicSlots.map(f => f(address)), address, staticValues);
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);
1275
+ }
1276
+ }
1277
+ return {
1278
+ configuration: new Configuration(base, newCompartments, dynamicSlots.map(f => f(address)), address, staticValues),
1279
+ values: dynamicValues
1280
+ };
1255
1281
  }
1256
1282
  }
1257
1283
  function flatten(extension, compartments, newCompartments) {
@@ -1905,15 +1931,9 @@ class EditorState {
1905
1931
  }
1906
1932
  let startValues;
1907
1933
  if (!conf) {
1908
- conf = Configuration.resolve(base, compartments, this);
1909
- let updatedValues = conf.dynamicSlots.map(_ => Uninitialized);
1910
- // Copy over old values for shared facets/fields
1911
- for (let id in conf.address) {
1912
- let cur = conf.address[id], prev = this.config.address[id];
1913
- if (prev != null && (cur & 1) == 0)
1914
- updatedValues[cur >> 1] = getAddr(this, prev);
1915
- }
1916
- let intermediateState = new EditorState(conf, this.doc, this.selection, updatedValues, null);
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);
1917
1937
  startValues = intermediateState.values;
1918
1938
  }
1919
1939
  else {
@@ -2043,7 +2063,7 @@ class EditorState {
2043
2063
  transactions.
2044
2064
  */
2045
2065
  static create(config = {}) {
2046
- let configuration = Configuration.resolve(config.extensions || [], new Map);
2066
+ let { configuration, values } = Configuration.resolve(config.extensions || [], new Map);
2047
2067
  let doc = config.doc instanceof text.Text ? config.doc
2048
2068
  : text.Text.of((config.doc || "").split(configuration.staticFacet(EditorState.lineSeparator) || DefaultSplit));
2049
2069
  let selection = !config.selection ? EditorSelection.single(0)
@@ -2052,7 +2072,7 @@ class EditorState {
2052
2072
  checkSelection(selection, doc.length);
2053
2073
  if (!configuration.staticFacet(allowMultipleSelections))
2054
2074
  selection = selection.asSingle();
2055
- return new EditorState(configuration, doc, selection, configuration.dynamicSlots.map(_ => Uninitialized));
2075
+ return new EditorState(configuration, doc, selection, values);
2056
2076
  }
2057
2077
  /**
2058
2078
  The size (in columns) of a tab in the document, determined by
package/dist/index.js CHANGED
@@ -1014,7 +1014,7 @@ function dynamicFacetSlot(addresses, facet, providers) {
1014
1014
  values.push(value);
1015
1015
  }
1016
1016
  let value = facet.combine(values);
1017
- if (facet.compare(value, oldVal))
1017
+ if (oldVal !== Uninitialized && facet.compare(value, oldVal))
1018
1018
  return 0;
1019
1019
  state.values[idx] = value;
1020
1020
  return 1 /* Changed */;
@@ -1215,9 +1215,11 @@ class Configuration {
1215
1215
  let address = Object.create(null);
1216
1216
  let staticValues = [];
1217
1217
  let dynamicSlots = [];
1218
+ let dynamicDeps = [];
1218
1219
  for (let field of fields) {
1219
1220
  address[field.id] = dynamicSlots.length << 1;
1220
1221
  dynamicSlots.push(a => field.slot(a));
1222
+ dynamicDeps.push([]);
1221
1223
  }
1222
1224
  for (let id in facets) {
1223
1225
  let providers = facets[id], facet = providers[0].facet;
@@ -1241,13 +1243,37 @@ class Configuration {
1241
1243
  else {
1242
1244
  address[p.id] = dynamicSlots.length << 1;
1243
1245
  dynamicSlots.push(a => p.dynamicSlot(a));
1246
+ dynamicDeps.push(p.dependencies.filter(d => typeof d != "string").map(d => d.id));
1244
1247
  }
1245
1248
  }
1246
1249
  address[facet.id] = dynamicSlots.length << 1;
1247
1250
  dynamicSlots.push(a => dynamicFacetSlot(a, facet, providers));
1251
+ dynamicDeps.push(providers.filter(p => p.type != 0 /* Static */).map(d => d.id));
1248
1252
  }
1249
1253
  }
1250
- return new Configuration(base, newCompartments, dynamicSlots.map(f => f(address)), address, staticValues);
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);
1271
+ }
1272
+ }
1273
+ return {
1274
+ configuration: new Configuration(base, newCompartments, dynamicSlots.map(f => f(address)), address, staticValues),
1275
+ values: dynamicValues
1276
+ };
1251
1277
  }
1252
1278
  }
1253
1279
  function flatten(extension, compartments, newCompartments) {
@@ -1900,15 +1926,9 @@ class EditorState {
1900
1926
  }
1901
1927
  let startValues;
1902
1928
  if (!conf) {
1903
- conf = Configuration.resolve(base, compartments, this);
1904
- let updatedValues = conf.dynamicSlots.map(_ => Uninitialized);
1905
- // Copy over old values for shared facets/fields
1906
- for (let id in conf.address) {
1907
- let cur = conf.address[id], prev = this.config.address[id];
1908
- if (prev != null && (cur & 1) == 0)
1909
- updatedValues[cur >> 1] = getAddr(this, prev);
1910
- }
1911
- let intermediateState = new EditorState(conf, this.doc, this.selection, updatedValues, null);
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);
1912
1932
  startValues = intermediateState.values;
1913
1933
  }
1914
1934
  else {
@@ -2038,7 +2058,7 @@ class EditorState {
2038
2058
  transactions.
2039
2059
  */
2040
2060
  static create(config = {}) {
2041
- let configuration = Configuration.resolve(config.extensions || [], new Map);
2061
+ let { configuration, values } = Configuration.resolve(config.extensions || [], new Map);
2042
2062
  let doc = config.doc instanceof Text ? config.doc
2043
2063
  : Text.of((config.doc || "").split(configuration.staticFacet(EditorState.lineSeparator) || DefaultSplit));
2044
2064
  let selection = !config.selection ? EditorSelection.single(0)
@@ -2047,7 +2067,7 @@ class EditorState {
2047
2067
  checkSelection(selection, doc.length);
2048
2068
  if (!configuration.staticFacet(allowMultipleSelections))
2049
2069
  selection = selection.asSingle();
2050
- return new EditorState(configuration, doc, selection, configuration.dynamicSlots.map(_ => Uninitialized));
2070
+ return new EditorState(configuration, doc, selection, values);
2051
2071
  }
2052
2072
  /**
2053
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.5",
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",