jazz-tools 0.7.0-alpha.34 → 0.7.0-alpha.36

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. package/.turbo/turbo-build.log +6 -4
  2. package/CHANGELOG.md +21 -0
  3. package/dist/coValues/account.js +5 -4
  4. package/dist/coValues/account.js.map +1 -1
  5. package/dist/coValues/coList.js +2 -1
  6. package/dist/coValues/coList.js.map +1 -1
  7. package/dist/coValues/coMap.js +6 -4
  8. package/dist/coValues/coMap.js.map +1 -1
  9. package/dist/coValues/coStream.js +2 -2
  10. package/dist/coValues/coStream.js.map +1 -1
  11. package/dist/coValues/extensions/imageDef.js +1 -1
  12. package/dist/coValues/extensions/imageDef.js.map +1 -1
  13. package/dist/coValues/group.js +1 -1
  14. package/dist/coValues/group.js.map +1 -1
  15. package/dist/coValues/interfaces.js +16 -9
  16. package/dist/coValues/interfaces.js.map +1 -1
  17. package/dist/implementation/devtoolsFormatters.js +113 -0
  18. package/dist/implementation/devtoolsFormatters.js.map +1 -0
  19. package/dist/implementation/refs.js +33 -8
  20. package/dist/implementation/refs.js.map +1 -1
  21. package/dist/implementation/subscriptionScope.js +14 -1
  22. package/dist/implementation/subscriptionScope.js.map +1 -1
  23. package/dist/internal.js +1 -0
  24. package/dist/internal.js.map +1 -1
  25. package/package.json +3 -3
  26. package/src/coValues/account.ts +5 -4
  27. package/src/coValues/coList.ts +11 -8
  28. package/src/coValues/coMap.ts +12 -4
  29. package/src/coValues/coStream.ts +2 -2
  30. package/src/coValues/extensions/imageDef.ts +1 -1
  31. package/src/coValues/group.ts +1 -1
  32. package/src/coValues/interfaces.ts +33 -20
  33. package/src/implementation/devtoolsFormatters.ts +109 -0
  34. package/src/implementation/refs.ts +32 -10
  35. package/src/implementation/subscriptionScope.ts +17 -1
  36. package/src/internal.ts +3 -1
@@ -14,9 +14,11 @@ import {
14
14
  subscriptionsScopes,
15
15
  } from "../internal.js";
16
16
 
17
- export class Ref<out V extends CoValue> {
18
- private cachedValue: V | undefined;
17
+ const refCache = new WeakMap<RawCoValue, CoValue>();
18
+
19
+ const TRACE_ACCESSES = false;
19
20
 
21
+ export class Ref<out V extends CoValue> {
20
22
  constructor(
21
23
  readonly id: ID<V>,
22
24
  readonly controlledAccount: Account & Me,
@@ -28,15 +30,18 @@ export class Ref<out V extends CoValue> {
28
30
  }
29
31
 
30
32
  get value() {
31
- if (this.cachedValue) return this.cachedValue;
32
- // TODO: cache it for object identity!!!
33
33
  const raw = this.controlledAccount._raw.core.node.getLoaded(
34
34
  this.id as unknown as CoID<RawCoValue>
35
35
  );
36
36
  if (raw) {
37
- const value = instantiateRefEncoded(this.schema, raw);
38
- this.cachedValue = value;
39
- return value;
37
+ let value = refCache.get(raw);
38
+ if (value) {
39
+ // console.log("Using cached value for " + this.id);
40
+ } else {
41
+ value = instantiateRefEncoded(this.schema, raw);
42
+ refCache.set(raw, value);
43
+ }
44
+ return value as V;
40
45
  } else {
41
46
  return null;
42
47
  }
@@ -83,16 +88,33 @@ export class Ref<out V extends CoValue> {
83
88
  }
84
89
  }
85
90
 
86
- accessFrom(fromScopeValue: CoValue): V | null {
91
+ accessFrom(fromScopeValue: CoValue, key: string | number | symbol): V | null {
87
92
  const subScope = subscriptionsScopes.get(fromScopeValue);
88
93
 
89
- subScope?.onRefAccessedOrSet(this.id);
94
+ subScope?.onRefAccessedOrSet(fromScopeValue.id, this.id);
95
+ TRACE_ACCESSES && console.log(subScope?.scopeID, "accessing", fromScopeValue, key, this.id);
90
96
 
91
97
  if (this.value && subScope) {
92
98
  subscriptionsScopes.set(this.value, subScope);
93
99
  }
94
100
 
95
- return this.value;
101
+ if (subScope) {
102
+ const cached = subScope.cachedValues[this.id];
103
+ if (cached) {
104
+ TRACE_ACCESSES && console.log("cached", cached);
105
+ return cached as V;
106
+ } else if (this.value !== null) {
107
+ const freshValueInstance = instantiateRefEncoded(this.schema, this.value?._raw);
108
+ TRACE_ACCESSES && console.log("freshValueInstance", freshValueInstance);
109
+ subScope.cachedValues[this.id] = freshValueInstance;
110
+ subscriptionsScopes.set(freshValueInstance, subScope);
111
+ return freshValueInstance as V;
112
+ } else {
113
+ return null
114
+ }
115
+ } else {
116
+ return this.value;
117
+ }
96
118
  }
97
119
  }
98
120
 
@@ -6,6 +6,8 @@ export const subscriptionsScopes = new WeakMap<
6
6
  SubscriptionScope<any>
7
7
  >();
8
8
 
9
+ const TRACE_INVALIDATIONS = false;
10
+
9
11
  export class SubscriptionScope<
10
12
  Root extends CoValue
11
13
  > {
@@ -23,6 +25,8 @@ export class SubscriptionScope<
23
25
  };
24
26
  onUpdate: (newRoot: Root) => void;
25
27
  scheduledUpdate: boolean = false;
28
+ cachedValues: {[id: ID<CoValue>]: CoValue} = {};
29
+ parents: {[id: ID<CoValue>]: Set<ID<CoValue>>} = {};
26
30
 
27
31
  constructor(
28
32
  root: Root,
@@ -63,12 +67,15 @@ export class SubscriptionScope<
63
67
  }
64
68
  }
65
69
 
66
- onRefAccessedOrSet(accessedOrSetId: ID<CoValue> | undefined) {
70
+ onRefAccessedOrSet(fromId: ID<CoValue>, accessedOrSetId: ID<CoValue> | undefined) {
67
71
  // console.log("onRefAccessedOrSet", this.scopeID, accessedOrSetId);
68
72
  if (!accessedOrSetId) {
69
73
  return;
70
74
  }
71
75
 
76
+ this.parents[accessedOrSetId] = this.parents[accessedOrSetId] || new Set();
77
+ this.parents[accessedOrSetId]!.add(fromId);
78
+
72
79
  if (!this.entries.has(accessedOrSetId)) {
73
80
  const loadingEntry = {
74
81
  state: "loading",
@@ -94,6 +101,7 @@ export class SubscriptionScope<
94
101
  const rawUnsub = core.subscribe((rawUpdate) => {
95
102
  // console.log("ref update", this.scopeID, accessedOrSetId, JSON.stringify(rawUpdate))
96
103
  if (!rawUpdate) return;
104
+ this.invalidate(accessedOrSetId);
97
105
  this.scheduleUpdate();
98
106
  });
99
107
 
@@ -103,6 +111,14 @@ export class SubscriptionScope<
103
111
  }
104
112
  }
105
113
 
114
+ invalidate(id: ID<CoValue>, fromChild?: ID<CoValue>) {
115
+ TRACE_INVALIDATIONS && console.log("invalidating", fromChild, "->", id, this.cachedValues[id]);
116
+ delete this.cachedValues[id];
117
+ for (const parent of this.parents[id] || []) {
118
+ this.invalidate(parent, id);
119
+ }
120
+ }
121
+
106
122
  unsubscribeAll() {
107
123
  for (const entry of this.entries.values()) {
108
124
  if (entry.state === "loaded") {
package/src/internal.ts CHANGED
@@ -13,4 +13,6 @@ export * from "./implementation/refs.js";
13
13
  export * from "./implementation/schema.js";
14
14
  export * from "./implementation/subscriptionScope.js";
15
15
 
16
- export * from "./coValues/extensions/imageDef.js";
16
+ export * from "./coValues/extensions/imageDef.js";
17
+
18
+ import "./implementation/devtoolsFormatters.js"