querysub 0.15.0 → 0.16.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.15.0",
3
+ "version": "0.16.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",
@@ -318,7 +318,10 @@ export class ClientWatcher {
318
318
  void Promise.resolve().finally(() => { throw e; });
319
319
  }
320
320
  this.activeWatchSpec = undefined;
321
- if (Date.now() - time > ClientWatcher.MAX_TRIGGER_TIME) {
321
+ if (
322
+ Date.now() - time > ClientWatcher.MAX_TRIGGER_TIME
323
+ && !isDevDebugbreak()
324
+ ) {
322
325
  stoppedEarly = true;
323
326
  break;
324
327
  }
@@ -12,7 +12,7 @@ import { getThreadKeyCert } from "../-a-auth/certs";
12
12
  import { ActionsHistory } from "../diagnostics/ActionsHistory";
13
13
  import { registerResource } from "../diagnostics/trackResources";
14
14
  import { ClientWatcher, WatchSpecData, clientWatcher } from "../1-path-client/pathValueClientWatcher";
15
- import { createPathValueProxy, getProxyPath, isValueProxy, isValueProxy2 } from "./pathValueProxy";
15
+ import { createPathValueProxy, getPathFromProxy, getProxyPath, isValueProxy, isValueProxy2 } from "./pathValueProxy";
16
16
  import { authorityStorage, compareTime, ReadLock, epochTime, getNextTime, MAX_ACCEPTED_CHANGE_AGE, PathValue, Time, getCreatorId } from "../0-path-value-core/pathValueCore";
17
17
  import { runCodeWithDatabase, rawSchema } from "./pathDatabaseProxyBase";
18
18
  import { LOCAL_DOMAIN } from "../0-path-value-core/PathController";
@@ -364,6 +364,25 @@ export type PermissionsChecker = {
364
364
 
365
365
  class SyncWatcherTag { }
366
366
 
367
+ function isRecursiveMatch(paths: Set<string>, path: string): boolean {
368
+ if (paths.size === 0) return false;
369
+ if (paths.has(path)) return true;
370
+ for (let otherPath of paths) {
371
+ if (path.includes(otherPath) || otherPath.includes(path)) {
372
+ return true;
373
+ }
374
+ }
375
+ return false;
376
+ }
377
+ function removeMatches(paths: Set<string>, path: string): void {
378
+ paths.delete(path);
379
+ for (let otherPath of paths) {
380
+ if (path.includes(otherPath) || otherPath.includes(path)) {
381
+ paths.delete(otherPath);
382
+ }
383
+ }
384
+ }
385
+
367
386
  export class PathValueProxyWatcher {
368
387
  public static BREAK_ON_READS = new Set<string>();
369
388
  public static BREAK_ON_WRITES = new Set<string>();
@@ -474,7 +493,8 @@ export class PathValueProxyWatcher {
474
493
  };
475
494
  public getCallback = (pathStr: string, syncParentKeys?: "parentKeys", readTransparent?: "readTransparent"): { value: unknown } | undefined => {
476
495
  if (PathValueProxyWatcher.BREAK_ON_READS.size > 0 && proxyWatcher.isAllSynced()) {
477
- if (PathValueProxyWatcher.BREAK_ON_READS.has(pathStr)) {
496
+ if (isRecursiveMatch(PathValueProxyWatcher.BREAK_ON_READS, pathStr)) {
497
+ const unwatch = () => PathValueProxyWatcher.BREAK_ON_READS.delete(pathStr); unwatch;
478
498
  debugger;
479
499
  }
480
500
  }
@@ -548,13 +568,15 @@ export class PathValueProxyWatcher {
548
568
 
549
569
  private setCallback = (pathStr: string, value: unknown, inRecursion = false, allowSpecial = false): void => {
550
570
  if (PathValueProxyWatcher.BREAK_ON_WRITES.size > 0 && proxyWatcher.isAllSynced()) {
551
- if (PathValueProxyWatcher.BREAK_ON_WRITES.has(pathStr)) {
571
+ if (isRecursiveMatch(PathValueProxyWatcher.BREAK_ON_WRITES, pathStr)) {
572
+ let unwatch = () => PathValueProxyWatcher.BREAK_ON_WRITES.delete(pathStr); unwatch;
552
573
  debugger;
553
574
  }
554
575
  }
555
576
 
556
577
  if (PathValueProxyWatcher.SET_FUNCTION_WATCH_ON_WRITES.size > 0 && proxyWatcher.isAllSynced()) {
557
- if (PathValueProxyWatcher.SET_FUNCTION_WATCH_ON_WRITES.has(pathStr)) {
578
+ if (isRecursiveMatch(PathValueProxyWatcher.SET_FUNCTION_WATCH_ON_WRITES, pathStr)) {
579
+ let unwatch = () => PathValueProxyWatcher.SET_FUNCTION_WATCH_ON_WRITES.delete(pathStr); unwatch;
558
580
  PathValueProxyWatcher.BREAK_ON_CALL.add(
559
581
  getPathStr2(getCurrentCall().ModuleId, getCurrentCall().FunctionId)
560
582
  );
@@ -562,10 +584,9 @@ export class PathValueProxyWatcher {
562
584
  }
563
585
 
564
586
  if (PathValueProxyWatcher.LOG_WRITES_INCLUDES.size > 0 && proxyWatcher.isAllSynced()) {
565
- for (let log of PathValueProxyWatcher.LOG_WRITES_INCLUDES) {
566
- if (pathStr.includes(log)) {
567
- console.log(`Write path "${pathStr}" = ${value}`);
568
- }
587
+ if (isRecursiveMatch(PathValueProxyWatcher.LOG_WRITES_INCLUDES, pathStr)) {
588
+ let unwatch = () => PathValueProxyWatcher.LOG_WRITES_INCLUDES.delete(pathStr); unwatch;
589
+ console.log(`Write path "${pathStr}" = ${value}`);
569
590
  }
570
591
  }
571
592
  if (value === specialObjectWriteSymbol) {
@@ -1704,6 +1725,23 @@ export class PathValueProxyWatcher {
1704
1725
  watcher.pendingUnsyncedParentAccesses.delete(path);
1705
1726
  }
1706
1727
  }
1728
+
1729
+ public debug_breakOnWrite(proxy: unknown | (() => unknown)) {
1730
+ let path = typeof proxy === "function" ? getProxyPath(proxy as any) : getPathFromProxy(proxy);
1731
+ if (!path) {
1732
+ console.error(`Value is not a proxy, and so cannot get path. Either pass a proxy, or a getter for a value.`);
1733
+ return;
1734
+ }
1735
+ PathValueProxyWatcher.BREAK_ON_WRITES.add(path);
1736
+ }
1737
+ public debug_logOnWrite(proxy: unknown | (() => unknown)) {
1738
+ let path = typeof proxy === "function" ? getProxyPath(proxy as any) : getPathFromProxy(proxy);
1739
+ if (!path) {
1740
+ console.error(`Value is not a proxy, and so cannot get path. Either pass a proxy, or a getter for a value.`);
1741
+ return;
1742
+ }
1743
+ PathValueProxyWatcher.LOG_WRITES_INCLUDES.add(path);
1744
+ }
1707
1745
  }
1708
1746
 
1709
1747
  // gitHash => domainName => moduleId => schema
@@ -1729,13 +1767,17 @@ function getBaseMatchingSchema(pathStr: string): {
1729
1767
  schema: Schema2;
1730
1768
  nestedPath: string[];
1731
1769
  } | undefined {
1732
- let gitHash = getCurrentCallObj()?.fnc.gitRef || "ambient";
1770
+ let schemaForHash = (
1771
+ schemas.get(getCurrentCallObj()?.fnc.gitRef || "ambient")
1772
+ // Default to the ambient schema for clientside calls.
1773
+ || schemas.get("ambient")
1774
+ );
1733
1775
 
1734
1776
  if (_noAtomicSchema) return undefined;
1735
1777
  if (getPathIndex(pathStr, 3) !== "Data") return undefined;
1736
1778
  let domain = getPathIndex(pathStr, 0)!;
1737
1779
  let moduleId = getPathIndex(pathStr, 2)!;
1738
- let schema = schemas.get(gitHash)?.get(domain)?.get(moduleId);
1780
+ let schema = schemaForHash?.get(domain)?.get(moduleId);
1739
1781
  if (!schema) return undefined;
1740
1782
  let nestedPathStr = getPathSuffix(pathStr, 4);
1741
1783
  let nestedPath = getPathFromStr(nestedPathStr);
@@ -174,7 +174,7 @@ export function writeFunctionCall(config: {
174
174
  return callSpec;
175
175
  }
176
176
 
177
- export function parseArgs(call: CallSpec) {
177
+ export function parseArgs(call: CallSpec): unknown[] {
178
178
  return decodeCborx(Buffer.from(call.argsEncoded, "base64"));
179
179
  }
180
180
 
@@ -177,6 +177,10 @@ export class Querysub {
177
177
  public static unwatchCurrentFnc = () => PathValueProxyWatcher.BREAK_ON_CALL.delete(
178
178
  getPathStr2(getCurrentCall().ModuleId, getCurrentCall().FunctionId)
179
179
  );
180
+ public static watchWrites = (value: unknown) => proxyWatcher.debug_breakOnWrite(value);
181
+ public static debugWrites = (value: unknown) => proxyWatcher.debug_breakOnWrite(value);
182
+ public static breakOnWrite = (value: unknown) => proxyWatcher.debug_breakOnWrite(value);
183
+ public static logWrites = (value: unknown) => proxyWatcher.debug_logOnWrite(value);
180
184
 
181
185
  public static watchUnsyncedComponents = () => qreact.watchUnsyncedComponents();
182
186
  public static watchAnyUnsyncedComponents = () => qreact.watchUnsyncedComponents().size > 0;
@@ -317,12 +321,6 @@ export class Querysub {
317
321
  return isSynced(value);
318
322
  }
319
323
 
320
- public static watchWrites(get: () => unknown) {
321
- let path = getProxyPath(get);
322
- if (!path) throw new Error(`Failed to get path`);
323
- PathValueProxyWatcher.LOG_WRITES_INCLUDES.add(path);
324
- }
325
-
326
324
  public static assertDomainAllowed(path: string) {
327
325
  let domain = getPathIndexAssert(path, 0);
328
326
  if (!Querysub.trustedDomains.has(domain)) {
@@ -875,4 +873,4 @@ setImmediate(() => {
875
873
  registerGetCompressNetwork(() => Querysub.COMPRESS_NETWORK);
876
874
  registerGetCompressDisk(() => Querysub.COMPRESS_DISK);
877
875
 
878
- (global as any).Querysub = Querysub;
876
+ (globalThis as any).Querysub = Querysub;
@@ -486,7 +486,7 @@ export async function getCallWrites(config: {
486
486
  // throw new Error(`Module not found ${call.DomainName}.${call.ModuleId}`);
487
487
  // }
488
488
  let moduleObject = domainObject.PathFunctionRunner[call.ModuleId];
489
- if (!(call.FunctionId in moduleObject.Sources)) {
489
+ if (!(call.FunctionId in moduleObject.Sources) && Querysub.isAllSynced()) {
490
490
  throw new Error(`Function not found ${call.DomainName}.${call.ModuleId}.${call.FunctionId}`);
491
491
  }
492
492
  let functionSpec = atomicObjectRead(moduleObject.Sources[call.FunctionId]);
package/src/config.ts CHANGED
@@ -39,9 +39,14 @@ export function devDebugbreak() {
39
39
  debugbreak(2);
40
40
  debugger;
41
41
  }
42
+ let debuggedEnabled = false;
42
43
  export function isDevDebugbreak() {
43
- return yargObj.debugbreak;
44
+ return yargObj.debugbreak || !isNode() && location.hostname.startsWith("noproxy.") || debuggedEnabled;
44
45
  }
46
+ export function enableDebugging() {
47
+ debuggedEnabled = true;
48
+ }
49
+ (globalThis as any).enableDebugging = enableDebugging;
45
50
 
46
51
 
47
52
  export function authorityRaw() {