querysub 0.174.0 → 0.176.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.174.0",
3
+ "version": "0.176.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",
@@ -24,7 +24,7 @@
24
24
  "node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6",
25
25
  "pako": "^2.1.0",
26
26
  "preact": "^10.11.3",
27
- "socket-function": "^0.121.0",
27
+ "socket-function": "^0.122.0",
28
28
  "terser": "^5.31.0",
29
29
  "typesafecss": "^0.15.0",
30
30
  "yaml": "^2.5.0",
@@ -218,8 +218,8 @@ export type SyncWatcher = {
218
218
 
219
219
  dispose: () => void;
220
220
  disposed?: boolean;
221
- // Reset every time the function is committed, so that inner callbacks can know when the dispose
222
- // happens, without having to dedupe their callback function.
221
+ // Reset every time the function is run, so this can be subscribed to every run, but will
222
+ // only be called once the final commit.
223
223
  onInnerDisposed: (() => void)[];
224
224
  // Runs after any trigger happens (usually multiple triggers are required for a commit)
225
225
  onAfterTriggered: (() => void)[];
@@ -1082,6 +1082,8 @@ export class PathValueProxyWatcher {
1082
1082
 
1083
1083
  watcher.pendingAccesses.clear();
1084
1084
  watcher.pendingEpochAccesses.clear();
1085
+ // IMPORTANT! Reset onInnerDisposed, so onCommitFinished doesn't result in a callback
1086
+ // per time we wan the watcher!
1085
1087
  watcher.onInnerDisposed = [];
1086
1088
 
1087
1089
  // NOTE: If runAtTime is undefined, the writeTime will be undefined, causing us to read the latest data.
@@ -388,6 +388,13 @@ export class Querysub {
388
388
  });
389
389
  }
390
390
 
391
+ public static afterAllRendersFinished(callback: () => void) {
392
+ // onCommitFinished prevents duplicates, as well as only running when we are actually done
393
+ Querysub.onCommitFinished(() => {
394
+ void clientWatcher.waitForTriggerFinished()?.finally(callback);
395
+ });
396
+ }
397
+
391
398
  /** Solely for use to prevent local writes from occuring before predictions. We MIGHT make this a framework thing,
392
399
  * or just not bother with it (as after a prediction is run once the code will be loaded allowing it to always
393
400
  * run before the next frame).
@@ -0,0 +1,83 @@
1
+ // true => ""
2
+ // "" => JSON.stringify("")
3
+
4
+ export const niceStringifyTrue = "";
5
+ // Starting/ending with a JSON character means anything string that looks like this
6
+ // will be encoded like: `"{Nan`, and it is impossible for an object to serialize to look like this.
7
+ export const niceStringifyNan = `{NaN}`;
8
+ export const niceStringifyUndefined = `{Undefined}`;
9
+
10
+
11
+ // BUG: This is actually broken for hex strings. Hex strings may sometimes be entirely numbers,
12
+ // which means they will randomly change type.
13
+ function looksLikeJSON(str: string) {
14
+ return (
15
+ str === "null"
16
+ || str === "true"
17
+ || str === "false"
18
+ || str[0] === `"` && str[str.length - 1] === `"`
19
+ || str[0] === `[` && str[str.length - 1] === `]`
20
+ || str[0] === `{` && str[str.length - 1] === `}`
21
+ || (48 <= str.charCodeAt(0) && str.charCodeAt(0) <= 57)
22
+ || str.length > 1 && str[0] === "-" && (48 <= str.charCodeAt(1) && str.charCodeAt(1) <= 57)
23
+ || str === niceStringifyTrue
24
+ || str === niceStringifyUndefined
25
+ );
26
+ }
27
+
28
+ export function niceStringify(value: unknown): string {
29
+ if (value === undefined) {
30
+ return niceStringifyUndefined;
31
+ }
32
+ if (value === true) return niceStringifyTrue;
33
+ if (Number.isNaN(value)) return niceStringifyNan;
34
+
35
+ // Any strings that don't look like JSON, don't need to encoded as JSON, and can instead
36
+ // just be stored as strings.
37
+ if (typeof value === "string" && !looksLikeJSON(value)) {
38
+ return value;
39
+ }
40
+
41
+
42
+ let str = JSON.stringify(value);
43
+ if (typeof value !== "object") {
44
+ let testParse = niceParse(str);
45
+ if (testParse !== value) {
46
+ console.log(`niceStringify did not reverse correctly. Should have received ${JSON.stringify(value)}, did received ${JSON.stringify(testParse)}`);
47
+ debugger;
48
+ }
49
+ }
50
+
51
+ return str;
52
+ }
53
+
54
+ export function niceParse(str: string | undefined, noSpecialTrue = false): unknown {
55
+ if (str === undefined) {
56
+ return undefined;
57
+ }
58
+ if (str === niceStringifyTrue && !noSpecialTrue) return true;
59
+ if (str === niceStringifyNan) return Number.NaN;
60
+ if (str === niceStringifyUndefined) return undefined;
61
+ if (str === "") return str;
62
+
63
+ if (looksLikeJSON(str)) {
64
+ try {
65
+ return JSON.parse(str);
66
+ } catch { }
67
+ }
68
+ return str;
69
+ }
70
+
71
+ /*
72
+
73
+ function setFromUrlValue(key: string, valueJSON: string) {
74
+ if(isMaybeJSON(valueJSON)) {
75
+ try {
76
+ values[key] = JSON.parse(valueJSON);
77
+ return;
78
+ } catch { }
79
+ }
80
+ // Always set it, if it isn't JSON, just assume it is raw text.
81
+ values[key] = valueJSON;
82
+ }
83
+ */