socket-function 0.8.9 → 0.8.12

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.
@@ -6,7 +6,9 @@ export function promiseToObservable<T>(promise: Promise<T>): { value: T | undefi
6
6
  let error: unknown;
7
7
  let result: T | undefined;
8
8
 
9
- let isDoneTrigger = observable({ value: false });
9
+ let isDoneTrigger = observable({
10
+ value: false
11
+ });
10
12
  promise.then(
11
13
  r => {
12
14
  result = r;
@@ -32,21 +34,53 @@ export function promiseToObservable<T>(promise: Promise<T>): { value: T | undefi
32
34
  };
33
35
  }
34
36
 
35
- export function cacheLimitedAsyncObservable<Output, Key>(maxCount: number, getValue: (key: Key) => Promise<Output>): {
37
+ export function asyncObservable<Output, Key>(maxCount: number, getValue: (key: Key) => Promise<Output>): {
36
38
  (key: Key): Output | undefined;
37
39
  invalidate(key: Key): void;
40
+ invalidateAll(): void;
38
41
  } {
39
- let cache = cacheLimited(maxCount, (keyJSON: string) => {
40
- let key = keyJSON ? JSON.parse(keyJSON) : keyJSON;
41
- // We call inside another function so that synchronous errors still get wrapped in the observable
42
- let value = (async () => getValue(key))();
43
- return promiseToObservable(value);
44
- });
42
+ // NOTE: Not very efficient (invalidates too much), but... makes triggering invalidations much faster/easier,
43
+ // making an invalidate depend on the total render time, not the total cached state size.
44
+ let invalidateSeqNum = observable({ seqNum: 1 }, undefined, { deep: false, proxy: false });
45
+ let startingCalculating = new Set<string>();
46
+ let values = new Map<string, { value: Output | undefined }>();
47
+
45
48
  get["invalidate"] = (key: Key) => {
46
- cache.invalidate(JSON.stringify(key));
49
+ let hash = JSON.stringify(key);
50
+ let value = values.get(hash);
51
+ if (!value) return;
52
+ values.delete(hash);
53
+ startingCalculating.delete(hash);
54
+ invalidateSeqNum.seqNum++;
55
+ };
56
+ get["invalidateAll"] = () => {
57
+ startingCalculating.clear();
58
+ values.clear();
59
+ invalidateSeqNum.seqNum++;
47
60
  };
48
61
  function get(key: Key) {
49
- return cache(JSON.stringify(key)).value;
62
+ let hash = JSON.stringify(key);
63
+ let value = values.get(hash);
64
+ if (value) {
65
+ return value.value;
66
+ }
67
+ if (startingCalculating.has(hash)) {
68
+ throw new Error(`Cyclic access in cache`);
69
+ }
70
+ startingCalculating.add(hash);
71
+
72
+ // Not very efficient, but clearing the entire state is a lot easier to do then
73
+ // keep track of the order they are accessed (and it does make MOST accesses
74
+ // MUCH faster).
75
+ if (values.size >= maxCount) {
76
+ values.clear();
77
+ startingCalculating.clear();
78
+ }
79
+
80
+ // We call inside another function so that synchronous errors still get wrapped in the observable
81
+ value = promiseToObservable((async () => getValue(key))());
82
+ values.set(hash, value);
83
+ return value.value;
50
84
  }
51
85
  return get;
52
86
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "socket-function",
3
- "version": "0.8.9",
3
+ "version": "0.8.12",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "dependencies": {
package/src/caching.ts CHANGED
@@ -64,17 +64,10 @@ export function cacheLimited<Output, Key>(
64
64
  // calculating, keeping a consistent output can save (a considerable amount of) time in downstream caches.
65
65
  maxCount: number,
66
66
  getValue: (key: Key) => Output
67
- ): {
68
- (key: Key): Output;
69
- invalidate(key: Key): void;
70
- } {
67
+ ): (key: Key) => Output {
71
68
  let startingCalculating = new Set<Key>();
72
69
  let values = new Map<Key, Output>();
73
- get["invalidate"] = (key: Key) => {
74
- values.delete(key);
75
- startingCalculating.delete(key);
76
- };
77
- function get(input: Key) {
70
+ return (input) => {
78
71
  let key = input;
79
72
  if (values.has(key)) {
80
73
  return values.get(key) as any;
@@ -98,8 +91,7 @@ export function cacheLimited<Output, Key>(
98
91
  let value = getValue(input);
99
92
  values.set(key, value);
100
93
  return value;
101
- }
102
- return get;
94
+ };
103
95
  }
104
96
 
105
97
  export function cacheWeak<Output, Key extends object>(getValue: (key: Key) => Output): (key: Key) => Output {