querysub 0.147.0 → 0.148.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "querysub",
3
- "version": "0.147.0",
3
+ "version": "0.148.0",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
@@ -580,8 +580,10 @@ class AuthorityPathValueStorage {
580
580
  childPaths.add(path);
581
581
  }
582
582
 
583
- /** Called by PathWatcher / ourself when paths are unwatched / destroyed */
584
- public markPathAsUnwatched(path: string) {
583
+ /** Called by PathWatcher / ourself when paths are unwatched / destroyed, to free memory.
584
+ * NOOPS if we are the authority of the path.
585
+ */
586
+ public destroyPath(path: string) {
585
587
  // If we are the authority we:
586
588
  // 1) Need to maintain the values for other nodes
587
589
  // 2) Don't need to worry about the values getting out of date,
@@ -1096,7 +1098,7 @@ class AuthorityPathValueStorage {
1096
1098
 
1097
1099
  if (pathsToClear.size > 0) {
1098
1100
  for (let path of pathsToClear) {
1099
- this.markPathAsUnwatched(path);
1101
+ this.destroyPath(path);
1100
1102
  // I'm not sure if removing it as a parent is needed, or... maybe it is needed,
1101
1103
  // and this isn't enough of a check?
1102
1104
  this.markParentPathAsUnwatched(path);
@@ -1322,27 +1324,6 @@ class PathWatcher {
1322
1324
 
1323
1325
  let pathsWatched = this.watchersToPaths.get(callback);
1324
1326
 
1325
- for (let path of config.paths) {
1326
- if (pathsWatched) {
1327
- pathsWatched.paths.delete(path);
1328
- }
1329
-
1330
- let watchers = this.watchers.get(path);
1331
- if (!watchers) continue;
1332
- watchers.watchers.delete(callback);
1333
- if (watchers.watchers.size === 0) {
1334
- this.watchers.delete(path);
1335
-
1336
- let parentPath = getParentPathStr(path);
1337
- let parentWatchers = this.watcherParentToPath.get(parentPath);
1338
- if (parentWatchers) {
1339
- parentWatchers.delete(path);
1340
- }
1341
-
1342
- fullyUnwatched.paths.push(path);
1343
- authorityStorage.markPathAsUnwatched(path);
1344
- }
1345
- }
1346
1327
  for (let path of config.parentPaths) {
1347
1328
  if (pathsWatched) {
1348
1329
  pathsWatched.parents.delete(path);
@@ -1364,6 +1345,46 @@ class PathWatcher {
1364
1345
 
1365
1346
  if (watchersObj.size === 0) {
1366
1347
  this.parentWatchers.delete(unpackedPath);
1348
+
1349
+ let childPaths = authorityStorage.getPathsFromParent(unpackedPath);
1350
+ // Destroy values that now have no watchers (no value watchers, and now no parent watcher
1351
+ if (childPaths) {
1352
+ for (let childPath of childPaths) {
1353
+ if (!this.watchers.has(childPath)) {
1354
+ authorityStorage.destroyPath(childPath);
1355
+ }
1356
+ }
1357
+ }
1358
+ }
1359
+ }
1360
+ }
1361
+
1362
+ // NOTE: Unwatch parents, then values, as parent paths might keep alive value path watches.
1363
+ for (let path of config.paths) {
1364
+ if (pathsWatched) {
1365
+ pathsWatched.paths.delete(path);
1366
+ }
1367
+
1368
+ let watchers = this.watchers.get(path);
1369
+ if (!watchers) continue;
1370
+ watchers.watchers.delete(callback);
1371
+ if (watchers.watchers.size === 0) {
1372
+ this.watchers.delete(path);
1373
+
1374
+ let parentPath = getParentPathStr(path);
1375
+ let parentWatchers = this.watcherParentToPath.get(parentPath);
1376
+ if (parentWatchers) {
1377
+ parentWatchers.delete(path);
1378
+ }
1379
+
1380
+ fullyUnwatched.paths.push(path);
1381
+ // NOTE: If the parent is being watched, don't destroy the value.
1382
+ // - The fact that we only do the check here does mean that if the path is unwatched
1383
+ // first and then later the parent path is unwatched we will fail to properly destroy
1384
+ // the path. However, in practice, either both are unwatched at the same time, or more
1385
+ // likely, the value watch only goes away because it's made redundant by the parent watch.
1386
+ if (!this.parentWatchers.has(parentPath)) {
1387
+ authorityStorage.destroyPath(path);
1367
1388
  }
1368
1389
  }
1369
1390
  }