@osdk/client 2.5.0-beta.5 → 2.5.0-beta.6

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.
Files changed (207) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/build/browser/MinimalClientContext.js.map +1 -1
  3. package/build/browser/actions/applyAction.js +4 -0
  4. package/build/browser/actions/applyAction.js.map +1 -1
  5. package/build/browser/createClient.js +2 -1
  6. package/build/browser/createClient.js.map +1 -1
  7. package/build/browser/createMinimalClient.js +2 -1
  8. package/build/browser/createMinimalClient.js.map +1 -1
  9. package/build/browser/object/aggregate.js +2 -0
  10. package/build/browser/object/aggregate.js.map +1 -1
  11. package/build/browser/object/fetchPage.js +5 -2
  12. package/build/browser/object/fetchPage.js.map +1 -1
  13. package/build/browser/observable/internal/AbstractHelper.js +4 -3
  14. package/build/browser/observable/internal/AbstractHelper.js.map +1 -1
  15. package/build/browser/observable/internal/BatchContext.js +2 -0
  16. package/build/browser/observable/internal/BatchContext.js.map +1 -0
  17. package/build/browser/observable/internal/CacheKeys.js +61 -36
  18. package/build/browser/observable/internal/CacheKeys.js.map +1 -1
  19. package/build/browser/observable/internal/Layer.js +0 -8
  20. package/build/browser/observable/internal/Layer.js.map +1 -1
  21. package/build/browser/observable/internal/Layers.js +151 -0
  22. package/build/browser/observable/internal/Layers.js.map +1 -0
  23. package/build/browser/observable/internal/ObservableClientImpl.js +3 -1
  24. package/build/browser/observable/internal/ObservableClientImpl.js.map +1 -1
  25. package/build/browser/observable/internal/Queries.js +40 -0
  26. package/build/browser/observable/internal/Queries.js.map +1 -0
  27. package/build/browser/observable/internal/Query.js +1 -0
  28. package/build/browser/observable/internal/Query.js.map +1 -1
  29. package/build/browser/observable/internal/Store.js +36 -225
  30. package/build/browser/observable/internal/Store.js.map +1 -1
  31. package/build/browser/observable/internal/Store.test.js +11 -9
  32. package/build/browser/observable/internal/Store.test.js.map +1 -1
  33. package/build/browser/observable/internal/SubjectPayload.js +2 -0
  34. package/build/browser/observable/internal/SubjectPayload.js.map +1 -0
  35. package/build/browser/observable/internal/Subjects.js +55 -0
  36. package/build/browser/observable/internal/Subjects.js.map +1 -0
  37. package/build/browser/observable/internal/actions/ActionApplication.js +2 -2
  38. package/build/browser/observable/internal/actions/ActionApplication.js.map +1 -1
  39. package/build/browser/observable/internal/actions/OptimisticJob.js +1 -1
  40. package/build/browser/observable/internal/actions/OptimisticJob.js.map +1 -1
  41. package/build/browser/observable/internal/base-list/BaseListQuery.js +6 -9
  42. package/build/browser/observable/internal/base-list/BaseListQuery.js.map +1 -1
  43. package/build/browser/observable/internal/base-list/createCollectionConnectable.js +2 -2
  44. package/build/browser/observable/internal/base-list/createCollectionConnectable.js.map +1 -1
  45. package/build/browser/observable/internal/base-list/createCollectionConnectable.test.js +23 -25
  46. package/build/browser/observable/internal/base-list/createCollectionConnectable.test.js.map +1 -1
  47. package/build/browser/observable/internal/base-list/removeDuplicates.js.map +1 -1
  48. package/build/browser/observable/internal/createInitEntry.js +25 -0
  49. package/build/browser/observable/internal/createInitEntry.js.map +1 -0
  50. package/build/browser/observable/internal/links/LinksHelper.js +5 -5
  51. package/build/browser/observable/internal/links/LinksHelper.js.map +1 -1
  52. package/build/browser/observable/internal/links/SpecificLinkQuery.js.map +1 -1
  53. package/build/browser/observable/internal/list/ListQuery.js +5 -5
  54. package/build/browser/observable/internal/list/ListQuery.js.map +1 -1
  55. package/build/browser/observable/internal/list/ListsHelper.js +5 -5
  56. package/build/browser/observable/internal/list/ListsHelper.js.map +1 -1
  57. package/build/browser/observable/internal/object/ObjectQuery.js.map +1 -1
  58. package/build/browser/observable/internal/object/ObjectsHelper.js +2 -2
  59. package/build/browser/observable/internal/object/ObjectsHelper.js.map +1 -1
  60. package/build/browser/observable/internal/sorting/SortingStrategy.js.map +1 -1
  61. package/build/browser/observable/internal/testUtils/invalidateList.js +2 -2
  62. package/build/browser/observable/internal/testUtils/invalidateList.js.map +1 -1
  63. package/build/browser/observable/internal/testUtils.js +1 -1
  64. package/build/browser/observable/internal/testUtils.js.map +1 -1
  65. package/build/browser/ontology/loadActionMetadata.js +3 -1
  66. package/build/browser/ontology/loadActionMetadata.js.map +1 -1
  67. package/build/browser/ontology/loadFullObjectMetadata.js +2 -1
  68. package/build/browser/ontology/loadFullObjectMetadata.js.map +1 -1
  69. package/build/browser/ontology/loadInterfaceMetadata.js +2 -1
  70. package/build/browser/ontology/loadInterfaceMetadata.js.map +1 -1
  71. package/build/browser/queries/applyQuery.js +2 -2
  72. package/build/browser/queries/applyQuery.js.map +1 -1
  73. package/build/browser/util/UserAgent.js +2 -2
  74. package/build/cjs/{chunk-KCMGIMVC.cjs → chunk-4GWXMQZE.cjs} +70 -60
  75. package/build/cjs/chunk-4GWXMQZE.cjs.map +1 -0
  76. package/build/cjs/{chunk-ELAA4C2C.cjs → chunk-5KDG5ZET.cjs} +9 -4
  77. package/build/cjs/chunk-5KDG5ZET.cjs.map +1 -0
  78. package/build/cjs/{createClient-BJo8T7Js.d.cts → createClient-mOlFts15.d.cts} +1 -0
  79. package/build/cjs/index.cjs +7 -7
  80. package/build/cjs/index.d.cts +1 -1
  81. package/build/cjs/public/internal.cjs +8 -8
  82. package/build/cjs/public/unstable-do-not-use.cjs +360 -300
  83. package/build/cjs/public/unstable-do-not-use.cjs.map +1 -1
  84. package/build/cjs/public/unstable-do-not-use.d.cts +1 -1
  85. package/build/esm/MinimalClientContext.js.map +1 -1
  86. package/build/esm/actions/applyAction.js +4 -0
  87. package/build/esm/actions/applyAction.js.map +1 -1
  88. package/build/esm/createClient.js +2 -1
  89. package/build/esm/createClient.js.map +1 -1
  90. package/build/esm/createMinimalClient.js +2 -1
  91. package/build/esm/createMinimalClient.js.map +1 -1
  92. package/build/esm/object/aggregate.js +2 -0
  93. package/build/esm/object/aggregate.js.map +1 -1
  94. package/build/esm/object/fetchPage.js +5 -2
  95. package/build/esm/object/fetchPage.js.map +1 -1
  96. package/build/esm/observable/internal/AbstractHelper.js +4 -3
  97. package/build/esm/observable/internal/AbstractHelper.js.map +1 -1
  98. package/build/esm/observable/internal/BatchContext.js +2 -0
  99. package/build/esm/observable/internal/BatchContext.js.map +1 -0
  100. package/build/esm/observable/internal/CacheKeys.js +61 -36
  101. package/build/esm/observable/internal/CacheKeys.js.map +1 -1
  102. package/build/esm/observable/internal/Layer.js +0 -8
  103. package/build/esm/observable/internal/Layer.js.map +1 -1
  104. package/build/esm/observable/internal/Layers.js +151 -0
  105. package/build/esm/observable/internal/Layers.js.map +1 -0
  106. package/build/esm/observable/internal/ObservableClientImpl.js +3 -1
  107. package/build/esm/observable/internal/ObservableClientImpl.js.map +1 -1
  108. package/build/esm/observable/internal/Queries.js +40 -0
  109. package/build/esm/observable/internal/Queries.js.map +1 -0
  110. package/build/esm/observable/internal/Query.js +1 -0
  111. package/build/esm/observable/internal/Query.js.map +1 -1
  112. package/build/esm/observable/internal/Store.js +36 -225
  113. package/build/esm/observable/internal/Store.js.map +1 -1
  114. package/build/esm/observable/internal/Store.test.js +11 -9
  115. package/build/esm/observable/internal/Store.test.js.map +1 -1
  116. package/build/esm/observable/internal/SubjectPayload.js +2 -0
  117. package/build/esm/observable/internal/SubjectPayload.js.map +1 -0
  118. package/build/esm/observable/internal/Subjects.js +55 -0
  119. package/build/esm/observable/internal/Subjects.js.map +1 -0
  120. package/build/esm/observable/internal/actions/ActionApplication.js +2 -2
  121. package/build/esm/observable/internal/actions/ActionApplication.js.map +1 -1
  122. package/build/esm/observable/internal/actions/OptimisticJob.js +1 -1
  123. package/build/esm/observable/internal/actions/OptimisticJob.js.map +1 -1
  124. package/build/esm/observable/internal/base-list/BaseListQuery.js +6 -9
  125. package/build/esm/observable/internal/base-list/BaseListQuery.js.map +1 -1
  126. package/build/esm/observable/internal/base-list/createCollectionConnectable.js +2 -2
  127. package/build/esm/observable/internal/base-list/createCollectionConnectable.js.map +1 -1
  128. package/build/esm/observable/internal/base-list/createCollectionConnectable.test.js +23 -25
  129. package/build/esm/observable/internal/base-list/createCollectionConnectable.test.js.map +1 -1
  130. package/build/esm/observable/internal/base-list/removeDuplicates.js.map +1 -1
  131. package/build/esm/observable/internal/createInitEntry.js +25 -0
  132. package/build/esm/observable/internal/createInitEntry.js.map +1 -0
  133. package/build/esm/observable/internal/links/LinksHelper.js +5 -5
  134. package/build/esm/observable/internal/links/LinksHelper.js.map +1 -1
  135. package/build/esm/observable/internal/links/SpecificLinkQuery.js.map +1 -1
  136. package/build/esm/observable/internal/list/ListQuery.js +5 -5
  137. package/build/esm/observable/internal/list/ListQuery.js.map +1 -1
  138. package/build/esm/observable/internal/list/ListsHelper.js +5 -5
  139. package/build/esm/observable/internal/list/ListsHelper.js.map +1 -1
  140. package/build/esm/observable/internal/object/ObjectQuery.js.map +1 -1
  141. package/build/esm/observable/internal/object/ObjectsHelper.js +2 -2
  142. package/build/esm/observable/internal/object/ObjectsHelper.js.map +1 -1
  143. package/build/esm/observable/internal/sorting/SortingStrategy.js.map +1 -1
  144. package/build/esm/observable/internal/testUtils/invalidateList.js +2 -2
  145. package/build/esm/observable/internal/testUtils/invalidateList.js.map +1 -1
  146. package/build/esm/observable/internal/testUtils.js +1 -1
  147. package/build/esm/observable/internal/testUtils.js.map +1 -1
  148. package/build/esm/ontology/loadActionMetadata.js +3 -1
  149. package/build/esm/ontology/loadActionMetadata.js.map +1 -1
  150. package/build/esm/ontology/loadFullObjectMetadata.js +2 -1
  151. package/build/esm/ontology/loadFullObjectMetadata.js.map +1 -1
  152. package/build/esm/ontology/loadInterfaceMetadata.js +2 -1
  153. package/build/esm/ontology/loadInterfaceMetadata.js.map +1 -1
  154. package/build/esm/queries/applyQuery.js +2 -2
  155. package/build/esm/queries/applyQuery.js.map +1 -1
  156. package/build/esm/util/UserAgent.js +2 -2
  157. package/build/types/MinimalClientContext.d.ts +1 -0
  158. package/build/types/MinimalClientContext.d.ts.map +1 -1
  159. package/build/types/actions/applyAction.d.ts.map +1 -1
  160. package/build/types/createClient.d.ts +1 -0
  161. package/build/types/createClient.d.ts.map +1 -1
  162. package/build/types/observable/internal/AbstractHelper.d.ts +3 -1
  163. package/build/types/observable/internal/AbstractHelper.d.ts.map +1 -1
  164. package/build/types/observable/internal/BatchContext.d.ts +11 -0
  165. package/build/types/observable/internal/BatchContext.d.ts.map +1 -0
  166. package/build/types/observable/internal/CacheKeys.d.ts +9 -9
  167. package/build/types/observable/internal/CacheKeys.d.ts.map +1 -1
  168. package/build/types/observable/internal/Layer.d.ts +1 -2
  169. package/build/types/observable/internal/Layer.d.ts.map +1 -1
  170. package/build/types/observable/internal/Layers.d.ts +26 -0
  171. package/build/types/observable/internal/Layers.d.ts.map +1 -0
  172. package/build/types/observable/internal/Queries.d.ts +9 -0
  173. package/build/types/observable/internal/Queries.d.ts.map +1 -0
  174. package/build/types/observable/internal/Query.d.ts +5 -1
  175. package/build/types/observable/internal/Query.d.ts.map +1 -1
  176. package/build/types/observable/internal/Store.d.ts +19 -34
  177. package/build/types/observable/internal/Store.d.ts.map +1 -1
  178. package/build/types/observable/internal/Store.test.d.ts.map +1 -1
  179. package/build/types/observable/internal/SubjectPayload.d.ts +5 -0
  180. package/build/types/observable/internal/SubjectPayload.d.ts.map +1 -0
  181. package/build/types/observable/internal/Subjects.d.ts +16 -0
  182. package/build/types/observable/internal/Subjects.d.ts.map +1 -0
  183. package/build/types/observable/internal/base-list/BaseListQuery.d.ts +2 -1
  184. package/build/types/observable/internal/base-list/BaseListQuery.d.ts.map +1 -1
  185. package/build/types/observable/internal/base-list/createCollectionConnectable.d.ts +3 -2
  186. package/build/types/observable/internal/base-list/createCollectionConnectable.d.ts.map +1 -1
  187. package/build/types/observable/internal/base-list/removeDuplicates.d.ts +1 -1
  188. package/build/types/observable/internal/base-list/removeDuplicates.d.ts.map +1 -1
  189. package/build/types/observable/internal/createInitEntry.d.ts +3 -0
  190. package/build/types/observable/internal/createInitEntry.d.ts.map +1 -0
  191. package/build/types/observable/internal/links/LinksHelper.d.ts +3 -1
  192. package/build/types/observable/internal/links/LinksHelper.d.ts.map +1 -1
  193. package/build/types/observable/internal/links/SpecificLinkQuery.d.ts +3 -1
  194. package/build/types/observable/internal/links/SpecificLinkQuery.d.ts.map +1 -1
  195. package/build/types/observable/internal/list/ListQuery.d.ts +3 -1
  196. package/build/types/observable/internal/list/ListQuery.d.ts.map +1 -1
  197. package/build/types/observable/internal/list/ListsHelper.d.ts +3 -1
  198. package/build/types/observable/internal/list/ListsHelper.d.ts.map +1 -1
  199. package/build/types/observable/internal/object/ObjectQuery.d.ts +3 -1
  200. package/build/types/observable/internal/object/ObjectQuery.d.ts.map +1 -1
  201. package/build/types/observable/internal/object/ObjectsHelper.d.ts.map +1 -1
  202. package/build/types/observable/internal/sorting/SortingStrategy.d.ts +1 -1
  203. package/build/types/observable/internal/sorting/SortingStrategy.d.ts.map +1 -1
  204. package/build/types/observable/internal/testUtils.d.ts.map +1 -1
  205. package/package.json +9 -9
  206. package/build/cjs/chunk-ELAA4C2C.cjs.map +0 -1
  207. package/build/cjs/chunk-KCMGIMVC.cjs.map +0 -1
@@ -14,47 +14,19 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { BehaviorSubject } from "rxjs";
18
17
  import invariant from "tiny-invariant";
19
18
  import { additionalContext } from "../../Client.js";
20
19
  import { DEBUG_REFCOUNTS } from "../DebugFlags.js";
21
20
  import { ActionApplication } from "./actions/ActionApplication.js";
22
21
  import { CacheKeys } from "./CacheKeys.js";
23
22
  import { createChangedObjects, DEBUG_ONLY__changesToString } from "./Changes.js";
24
- import { Entry, Layer } from "./Layer.js";
23
+ import { Layers } from "./Layers.js";
25
24
  import { LinksHelper } from "./links/LinksHelper.js";
26
25
  import { ListsHelper } from "./list/ListsHelper.js";
27
26
  import { ObjectsHelper } from "./object/ObjectsHelper.js";
28
27
  import { OrderByCanonicalizer } from "./OrderByCanonicalizer.js";
29
- import { RefCounts } from "./RefCounts.js";
30
- import { tombstone } from "./tombstone.js";
28
+ import { Queries } from "./Queries.js";
31
29
  import { WhereClauseCanonicalizer } from "./WhereClauseCanonicalizer.js";
32
-
33
- /*
34
- Work still to do:
35
- - [x] testing for optimistic writes
36
- - [x] automatic invalidation of actions
37
- - [x] automatic optimistic list updates
38
- - [x] useOsdkObjects
39
- - [x] imply offline for objects passed directly
40
- - [x] websocket subscriptions
41
- - [ ] links
42
- - [x] add pagination
43
- - [ ] sub-selection support
44
- - [ ] interfaces
45
- - [ ] setup defaults
46
- - [ ] reduce updates in react
47
- */
48
-
49
- function createInitEntry(cacheKey) {
50
- return {
51
- cacheKey,
52
- status: "init",
53
- value: undefined,
54
- lastUpdated: 0
55
- };
56
- }
57
-
58
30
  /*
59
31
  Notes:
60
32
  - Subjects are one per type per store (by cache key)
@@ -70,57 +42,29 @@ function createInitEntry(cacheKey) {
70
42
  export class Store {
71
43
  whereCanonicalizer = new WhereClauseCanonicalizer();
72
44
  orderByCanonicalizer = new OrderByCanonicalizer();
73
- #truthLayer = new Layer(undefined, undefined);
74
- #topLayer;
75
45
 
76
46
  /** @internal */
77
47
 
78
- // we can use a regular Map here because the refCounting will
79
- // handle cleanup.
80
- #queries = new Map();
81
- #cacheKeyToSubject = new WeakMap();
82
- #cacheKeys;
83
- #refCounts = new RefCounts(DEBUG_REFCOUNTS ? 15_000 : 60_000, k => this.#cleanupCacheKey(k));
84
-
85
- // we are currently only using this for debug logging and should just remove it in the future if that
86
- // continues to be true
87
- #finalizationRegistry;
48
+ queries = new Queries();
49
+ layers = new Layers({
50
+ logger: this.logger,
51
+ onRevalidate: this.#maybeRevalidateQueries.bind(this)
52
+ });
53
+ subjects = this.layers.subjects;
88
54
 
89
55
  // these are hopefully temporary
90
56
 
91
57
  constructor(client) {
92
- this.client = client;
93
58
  this.logger = client[additionalContext].logger?.child({}, {
94
59
  msgPrefix: "Store"
95
60
  });
96
- this.lists = new ListsHelper(this, this.whereCanonicalizer, this.orderByCanonicalizer);
97
- this.objects = new ObjectsHelper(this);
98
- this.links = new LinksHelper(this, this.whereCanonicalizer, this.orderByCanonicalizer);
99
- this.#topLayer = this.#truthLayer;
100
- this.#cacheKeys = new CacheKeys(this.whereCanonicalizer, this.orderByCanonicalizer, k => {
101
- if (DEBUG_REFCOUNTS) {
102
- const cacheKeyType = k.type;
103
- const otherKeys = k.otherKeys;
104
- // eslint-disable-next-line no-console
105
- console.log(`CacheKeys.onCreate(${cacheKeyType}, ${JSON.stringify(otherKeys)})`);
106
- this.#finalizationRegistry.register(k, () => {
107
- // eslint-disable-next-line no-console
108
- console.log(`CacheKey Finalization(${cacheKeyType}, ${JSON.stringify(otherKeys)})`);
109
- });
110
- }
111
- this.#refCounts.register(k);
112
- });
113
- setInterval(() => {
114
- this.#refCounts.gc();
115
- }, 1000);
116
- this.#finalizationRegistry = new FinalizationRegistry(cleanupCallback => {
117
- try {
118
- cleanupCallback();
119
- } catch (e) {
120
- // eslint-disable-next-line no-console
121
- console.error("Caught an error while running a finalization callback", e);
122
- }
61
+ this.client = client;
62
+ this.cacheKeys = new CacheKeys({
63
+ onDestroy: this.#cleanupCacheKey
123
64
  });
65
+ this.lists = new ListsHelper(this, this.cacheKeys, this.whereCanonicalizer, this.orderByCanonicalizer);
66
+ this.objects = new ObjectsHelper(this, this.cacheKeys);
67
+ this.links = new LinksHelper(this, this.cacheKeys, this.whereCanonicalizer, this.orderByCanonicalizer);
124
68
  }
125
69
 
126
70
  /**
@@ -128,7 +72,7 @@ export class Store {
128
72
  * @param key
129
73
  */
130
74
  #cleanupCacheKey = key => {
131
- const subject = this.peekSubject(key);
75
+ const subject = this.subjects.peek(key);
132
76
  if (DEBUG_REFCOUNTS) {
133
77
  // eslint-disable-next-line no-console
134
78
  console.log(`CacheKey cleaning up (${JSON.stringify({
@@ -136,16 +80,11 @@ export class Store {
136
80
  observed: subject?.observed
137
81
  })})`, JSON.stringify([key.type, ...key.otherKeys], null, 2));
138
82
  }
139
- this.#cacheKeys.remove(key);
140
83
  if (process.env.NODE_ENV !== "production") {
141
84
  !subject ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
142
85
  }
143
- if (subject) {
144
- subject.complete();
145
- this.#cacheKeyToSubject.delete(key);
146
- }
147
- this.#queries.get(key)?.dispose();
148
- this.#queries.delete(key);
86
+ this.subjects.delete(key);
87
+ this.queries.delete(key);
149
88
  };
150
89
  applyAction = async (action, args, opts) => {
151
90
  return await new ActionApplication(this).applyAction(action, args, opts);
@@ -157,134 +96,18 @@ export class Store {
157
96
  });
158
97
  return result;
159
98
  };
160
- removeLayer(layerId) {
161
- !(layerId != null) ? process.env.NODE_ENV !== "production" ? invariant(false, "undefined is the reserved layerId for the truth layer") : invariant(false) : void 0;
162
- // 1. collect all cache keys for a given layerId
163
- let currentLayer = this.#topLayer;
164
- const cacheKeys = new Map();
165
- while (currentLayer != null && currentLayer.parentLayer != null) {
166
- if (currentLayer.layerId === layerId) {
167
- for (const [k, v] of currentLayer.entries()) {
168
- if (cacheKeys.has(k)) continue;
169
- cacheKeys.set(k, v);
170
- }
171
- }
172
- currentLayer = currentLayer.parentLayer;
173
- }
174
-
175
- // 2. remove the layers from the chain
176
- this.#topLayer = this.#topLayer.removeLayer(layerId);
177
-
178
- // 3. check each cache key to see if it is different in the new chain
179
- for (const [k, oldEntry] of cacheKeys) {
180
- const currentEntry = this.#topLayer.get(k);
181
-
182
- // 4. if different, update the subject
183
- if (oldEntry !== currentEntry) {
184
- currentEntry ?? createInitEntry(k); // We are going to be pretty lazy here and just re-emit the value.
185
- // In the future it may benefit us to deep equal check her but I think
186
- // the subjects are effectively doing this anyway.
187
- this.peekSubject(k)?.next({
188
- // eslint-disable-next-line @typescript-eslint/no-misused-spread
189
- ...(currentEntry ?? createInitEntry(k)),
190
- isOptimistic: currentEntry?.value !== this.#truthLayer.get(k)?.value
191
- });
192
- }
193
- }
194
- }
195
- getCacheKey(type, ...args) {
196
- return this.#refCounts.register(this.#cacheKeys.get(type, ...args));
197
- }
198
- peekSubject = cacheKey => {
199
- return this.#cacheKeyToSubject.get(cacheKey);
200
- };
201
- getSubject = cacheKey => {
202
- let subject = this.#cacheKeyToSubject.get(cacheKey);
203
- if (!subject) {
204
- const initialValue = this.#topLayer.get(cacheKey) ?? createInitEntry(cacheKey);
205
- subject = new BehaviorSubject({
206
- // eslint-disable-next-line @typescript-eslint/no-misused-spread
207
- ...initialValue,
208
- isOptimistic: initialValue.value !== this.#truthLayer.get(cacheKey)?.value
209
- });
210
- this.#cacheKeyToSubject.set(cacheKey, subject);
211
- }
212
- return subject;
213
- };
214
- canonicalizeWhereClause(where) {
215
- return this.whereCanonicalizer.canonicalize(where);
216
- }
217
- peekQuery(cacheKey) {
218
- return this.#queries.get(cacheKey);
219
- }
220
- getQuery(cacheKey, createQuery) {
221
- let query = this.peekQuery(cacheKey);
222
- if (!query) {
223
- query = createQuery();
224
- this.#queries.set(cacheKey, query);
225
- }
226
- return query;
227
- }
228
99
  getValue(cacheKey) {
229
- return this.#topLayer.get(cacheKey);
100
+ return this.layers.top.get(cacheKey);
230
101
  }
231
- batch = ({
102
+ batch({
232
103
  optimisticId,
233
104
  changes = createChangedObjects()
234
- }, batchFn) => {
235
- !(optimisticId === undefined || !!optimisticId) ? process.env.NODE_ENV !== "production" ? invariant(false, "optimistic must be undefined or not falsy") : invariant(false) : void 0;
236
- let needsLayer = optimisticId !== undefined;
237
- const batchContext = {
238
- changes,
239
- createLayerIfNeeded: () => {
240
- if (needsLayer) {
241
- this.#topLayer = this.#topLayer.addLayer(optimisticId);
242
- needsLayer = false;
243
- }
244
- },
245
- optimisticWrite: !!optimisticId,
246
- write: (cacheKey, value, status) => {
247
- const oldTopValue = this.#topLayer.get(cacheKey);
248
- if (optimisticId) batchContext.createLayerIfNeeded();
249
- const writeLayer = optimisticId ? this.#topLayer : this.#truthLayer;
250
- const newValue = new Entry(cacheKey, value, Date.now(), status);
251
- writeLayer.set(cacheKey, newValue);
252
- const newTopValue = this.#topLayer.get(cacheKey);
253
- if (oldTopValue !== newTopValue) {
254
- this.getSubject(cacheKey)?.next({
255
- // eslint-disable-next-line @typescript-eslint/no-misused-spread
256
- ...newValue,
257
- isOptimistic: newTopValue?.value !== this.#truthLayer.get(cacheKey)?.value
258
- });
259
- }
260
- return newValue;
261
- },
262
- delete: (cacheKey, status) => {
263
- return batchContext.write(cacheKey, tombstone, status);
264
- },
265
- read: cacheKey => {
266
- return optimisticId ? this.#topLayer.get(cacheKey) : this.#truthLayer.get(cacheKey);
267
- }
268
- };
269
- const retVal = batchFn(batchContext);
270
- this.maybeRevalidateQueries(changes, optimisticId).catch(e => {
271
- // we don't want batch() to return a promise,
272
- // so we settle for logging an error here instead of
273
- // dropping it on the floor.
274
- if (this.logger) {
275
- this.logger.error("Unhandled error in batch", e);
276
- } else {
277
- // eslint-disable-next-line no-console
278
- console.error("Unhandled error in batch", e);
279
- throw e;
280
- }
281
- });
282
- return {
283
- batchResult: batchContext,
284
- retVal: retVal,
285
- changes: batchContext.changes
286
- };
287
- };
105
+ }, batchFn) {
106
+ return this.layers.batch({
107
+ optimisticId,
108
+ changes
109
+ }, batchFn);
110
+ }
288
111
  invalidateObject(apiName, pk) {
289
112
  if (typeof apiName !== "string") {
290
113
  apiName = apiName.apiName;
@@ -294,37 +117,31 @@ export class Store {
294
117
  pk
295
118
  }).revalidate(/* force */true);
296
119
  }
297
- async maybeRevalidateQueries(changes, optimisticId) {
120
+ async #maybeRevalidateQueries(changes, optimisticId) {
121
+ const logger = process.env.NODE_ENV !== "production" ? this.logger?.child({
122
+ methodName: "maybeRevalidateQueries"
123
+ }) : undefined;
298
124
  if (changes.isEmpty()) {
299
125
  if (process.env.NODE_ENV !== "production") {
300
- // todo
301
- this.logger?.child({
302
- methodName: "maybeRevalidateQueries"
303
- }).debug("No changes, aborting");
126
+ logger?.debug("No changes, aborting");
304
127
  }
305
128
  return;
306
129
  }
307
130
  if (process.env.NODE_ENV !== "production") {
308
- // todo
309
- this.logger?.child({
310
- methodName: "maybeRevalidateQueries"
311
- }).debug(DEBUG_ONLY__changesToString(changes), {
131
+ logger?.debug(DEBUG_ONLY__changesToString(changes), {
312
132
  optimisticId
313
133
  });
314
134
  }
315
135
  try {
316
136
  const promises = [];
317
- for (const cacheKey of this.#queries.keys()) {
318
- const promise = this.peekQuery(cacheKey)?.maybeUpdateAndRevalidate?.(changes, optimisticId);
137
+ for (const cacheKey of this.queries.keys()) {
138
+ const promise = this.queries.peek(cacheKey)?.maybeUpdateAndRevalidate?.(changes, optimisticId);
319
139
  if (promise) promises.push(promise);
320
140
  }
321
141
  await Promise.all(promises);
322
142
  } finally {
323
143
  if (process.env.NODE_ENV !== "production") {
324
- // todo
325
- this.logger?.child({
326
- methodName: "maybeRevalidateQueries"
327
- }).debug("in finally", DEBUG_ONLY__changesToString(changes));
144
+ logger?.debug("in finally", DEBUG_ONLY__changesToString(changes));
328
145
  }
329
146
  }
330
147
  }
@@ -350,11 +167,11 @@ export class Store {
350
167
  }).info(changes ? DEBUG_ONLY__changesToString(changes) : void 0);
351
168
  }
352
169
  const promises = [];
353
- for (const cacheKey of this.#truthLayer.keys()) {
170
+ for (const cacheKey of this.layers.truth.keys()) {
354
171
  if (changes && changes.modified.has(cacheKey)) {
355
172
  continue;
356
173
  }
357
- const query = this.peekQuery(cacheKey);
174
+ const query = this.queries.peek(cacheKey);
358
175
  if (!query) continue;
359
176
  promises.push(query.invalidateObjectType(apiName, changes));
360
177
  }
@@ -362,11 +179,5 @@ export class Store {
362
179
  // we use allSettled here because we don't care if it succeeds or fails, just that they all complete.
363
180
  return Promise.allSettled(promises).then(() => void 0);
364
181
  }
365
- retain(cacheKey) {
366
- this.#refCounts.retain(cacheKey);
367
- }
368
- release(cacheKey) {
369
- this.#refCounts.release(cacheKey);
370
- }
371
182
  }
372
183
  //# sourceMappingURL=Store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Store.js","names":["BehaviorSubject","invariant","additionalContext","DEBUG_REFCOUNTS","ActionApplication","CacheKeys","createChangedObjects","DEBUG_ONLY__changesToString","Entry","Layer","LinksHelper","ListsHelper","ObjectsHelper","OrderByCanonicalizer","RefCounts","tombstone","WhereClauseCanonicalizer","createInitEntry","cacheKey","status","value","undefined","lastUpdated","Store","whereCanonicalizer","orderByCanonicalizer","truthLayer","topLayer","queries","Map","cacheKeyToSubject","WeakMap","cacheKeys","refCounts","k","cleanupCacheKey","finalizationRegistry","constructor","client","logger","child","msgPrefix","lists","objects","links","cacheKeyType","type","otherKeys","console","log","JSON","stringify","register","setInterval","gc","FinalizationRegistry","cleanupCallback","e","error","key","subject","peekSubject","closed","observed","remove","process","env","NODE_ENV","complete","delete","get","dispose","applyAction","action","args","opts","validateAction","result","$validateOnly","$returnEdits","removeLayer","layerId","currentLayer","parentLayer","v","entries","has","set","oldEntry","currentEntry","next","isOptimistic","getCacheKey","getSubject","initialValue","canonicalizeWhereClause","where","canonicalize","peekQuery","getQuery","createQuery","query","getValue","batch","optimisticId","changes","batchFn","needsLayer","batchContext","createLayerIfNeeded","addLayer","optimisticWrite","write","oldTopValue","writeLayer","newValue","Date","now","newTopValue","read","retVal","maybeRevalidateQueries","catch","batchResult","invalidateObject","apiName","pk","revalidate","isEmpty","methodName","debug","promises","keys","promise","maybeUpdateAndRevalidate","push","Promise","all","invalidateObjectType","info","modified","allSettled","then","retain","release"],"sources":["Store.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n ActionDefinition,\n ActionEditResponse,\n ActionValidationResponse,\n InterfaceDefinition,\n Logger,\n ObjectTypeDefinition,\n PrimaryKeyType,\n WhereClause,\n} from \"@osdk/api\";\nimport { BehaviorSubject } from \"rxjs\";\nimport invariant from \"tiny-invariant\";\nimport type { ActionSignatureFromDef } from \"../../actions/applyAction.js\";\nimport { additionalContext, type Client } from \"../../Client.js\";\nimport { DEBUG_REFCOUNTS } from \"../DebugFlags.js\";\nimport type { OptimisticBuilder } from \"../OptimisticBuilder.js\";\nimport { ActionApplication } from \"./actions/ActionApplication.js\";\nimport { CacheKeys } from \"./CacheKeys.js\";\nimport type { Canonical } from \"./Canonical.js\";\nimport {\n type Changes,\n createChangedObjects,\n DEBUG_ONLY__changesToString,\n} from \"./Changes.js\";\nimport type { KnownCacheKey } from \"./KnownCacheKey.js\";\nimport { Entry, Layer } from \"./Layer.js\";\nimport { LinksHelper } from \"./links/LinksHelper.js\";\nimport { ListsHelper } from \"./list/ListsHelper.js\";\nimport { ObjectsHelper } from \"./object/ObjectsHelper.js\";\nimport { type OptimisticId } from \"./OptimisticId.js\";\nimport { OrderByCanonicalizer } from \"./OrderByCanonicalizer.js\";\nimport type { Query } from \"./Query.js\";\nimport { RefCounts } from \"./RefCounts.js\";\nimport type { SimpleWhereClause } from \"./SimpleWhereClause.js\";\nimport { tombstone } from \"./tombstone.js\";\nimport { WhereClauseCanonicalizer } from \"./WhereClauseCanonicalizer.js\";\n\n/*\n Work still to do:\n - [x] testing for optimistic writes\n - [x] automatic invalidation of actions\n - [x] automatic optimistic list updates\n - [x] useOsdkObjects\n - [x] imply offline for objects passed directly\n - [x] websocket subscriptions\n - [ ] links\n - [x] add pagination\n - [ ] sub-selection support\n - [ ] interfaces\n - [ ] setup defaults\n - [ ] reduce updates in react\n*/\n\nexport interface SubjectPayload<KEY extends KnownCacheKey> extends Entry<KEY> {\n isOptimistic: boolean;\n}\n\nexport interface BatchContext {\n changes: Changes;\n createLayerIfNeeded: () => void;\n optimisticWrite: boolean;\n\n write: <K extends KnownCacheKey>(\n k: K,\n v: Entry<K>[\"value\"],\n status: Entry<K>[\"status\"],\n ) => Entry<K>;\n\n read: <K extends KnownCacheKey>(\n k: K,\n ) => Entry<K> | undefined;\n\n delete: <K extends KnownCacheKey>(\n k: K,\n status: Entry<K>[\"status\"],\n ) => Entry<K>;\n}\n\ninterface UpdateOptions {\n optimisticId?: OptimisticId;\n}\n\nexport namespace Store {\n export interface ApplyActionOptions {\n optimisticUpdate?: (ctx: OptimisticBuilder) => void;\n }\n}\n\nfunction createInitEntry(cacheKey: KnownCacheKey): Entry<any> {\n return {\n cacheKey,\n status: \"init\",\n value: undefined,\n lastUpdated: 0,\n };\n}\n\n/*\n Notes:\n - Subjects are one per type per store (by cache key)\n - Data is one per layer per cache key\n*/\n\n/**\n * Central data store with layered cache architecture.\n * - Truth layer: server state | Optimistic layers: pending changes\n * - Reference counting prevents memory leaks\n * - Batch operations ensure consistency\n */\nexport class Store {\n whereCanonicalizer: WhereClauseCanonicalizer = new WhereClauseCanonicalizer();\n orderByCanonicalizer: OrderByCanonicalizer = new OrderByCanonicalizer();\n #truthLayer: Layer = new Layer(undefined, undefined);\n #topLayer: Layer;\n client: Client;\n\n /** @internal */\n logger?: Logger;\n\n // we can use a regular Map here because the refCounting will\n // handle cleanup.\n #queries: Map<\n KnownCacheKey,\n Query<any, any, any>\n > = new Map();\n\n #cacheKeyToSubject = new WeakMap<\n KnownCacheKey,\n BehaviorSubject<SubjectPayload<any>>\n >();\n #cacheKeys: CacheKeys;\n\n #refCounts = new RefCounts<KnownCacheKey>(\n DEBUG_REFCOUNTS ? 15_000 : 60_000,\n (k) => this.#cleanupCacheKey(k),\n );\n\n // we are currently only using this for debug logging and should just remove it in the future if that\n // continues to be true\n #finalizationRegistry: FinalizationRegistry<() => void>;\n\n // these are hopefully temporary\n lists: ListsHelper;\n objects: ObjectsHelper;\n links: LinksHelper;\n\n constructor(client: Client) {\n this.client = client;\n this.logger = client[additionalContext].logger?.child({}, {\n msgPrefix: \"Store\",\n });\n\n this.lists = new ListsHelper(\n this,\n this.whereCanonicalizer,\n this.orderByCanonicalizer,\n );\n this.objects = new ObjectsHelper(this);\n this.links = new LinksHelper(\n this,\n this.whereCanonicalizer,\n this.orderByCanonicalizer,\n );\n\n this.#topLayer = this.#truthLayer;\n this.#cacheKeys = new CacheKeys(\n this.whereCanonicalizer,\n this.orderByCanonicalizer,\n (k) => {\n if (DEBUG_REFCOUNTS) {\n const cacheKeyType = k.type;\n const otherKeys = k.otherKeys;\n // eslint-disable-next-line no-console\n console.log(\n `CacheKeys.onCreate(${cacheKeyType}, ${JSON.stringify(otherKeys)})`,\n );\n\n this.#finalizationRegistry.register(k, () => {\n // eslint-disable-next-line no-console\n console.log(\n `CacheKey Finalization(${cacheKeyType}, ${\n JSON.stringify(otherKeys)\n })`,\n );\n });\n }\n\n this.#refCounts.register(k);\n },\n );\n\n setInterval(() => {\n this.#refCounts.gc();\n }, 1000);\n\n this.#finalizationRegistry = new FinalizationRegistry<() => void>(\n (cleanupCallback) => {\n try {\n cleanupCallback();\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(\n \"Caught an error while running a finalization callback\",\n e,\n );\n }\n },\n );\n }\n\n /**\n * Called after a key is no longer retained and the timeout has elapsed\n * @param key\n */\n #cleanupCacheKey = (key: KnownCacheKey) => {\n const subject = this.peekSubject(key);\n\n if (DEBUG_REFCOUNTS) {\n // eslint-disable-next-line no-console\n console.log(\n `CacheKey cleaning up (${\n JSON.stringify({\n closed: subject?.closed,\n observed: subject?.observed,\n })\n })`,\n JSON.stringify([key.type, ...key.otherKeys], null, 2),\n );\n }\n this.#cacheKeys.remove(key);\n if (process.env.NODE_ENV !== \"production\") {\n invariant(subject);\n }\n\n if (subject) {\n subject.complete();\n this.#cacheKeyToSubject.delete(key);\n }\n\n this.#queries.get(key)?.dispose();\n this.#queries.delete(key);\n };\n\n applyAction: <Q extends ActionDefinition<any>>(\n action: Q,\n args:\n | Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0]\n | Array<Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0]>,\n opts?: Store.ApplyActionOptions,\n ) => Promise<ActionEditResponse> = async (action, args, opts) => {\n return await new ActionApplication(this).applyAction(action, args, opts);\n };\n\n validateAction: <Q extends ActionDefinition<any>>(\n action: Q,\n args: Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0],\n ) => Promise<ActionValidationResponse> = async (action, args) => {\n const result = await this.client(action).applyAction(args as any, {\n $validateOnly: true,\n $returnEdits: false,\n });\n return result as ActionValidationResponse;\n };\n\n removeLayer(layerId: OptimisticId): void {\n invariant(\n layerId != null,\n \"undefined is the reserved layerId for the truth layer\",\n );\n // 1. collect all cache keys for a given layerId\n let currentLayer: Layer | undefined = this.#topLayer;\n const cacheKeys = new Map<KnownCacheKey, Entry<any>>();\n while (currentLayer != null && currentLayer.parentLayer != null) {\n if (currentLayer.layerId === layerId) {\n for (const [k, v] of currentLayer.entries()) {\n if (cacheKeys.has(k)) continue;\n cacheKeys.set(k, v);\n }\n }\n\n currentLayer = currentLayer.parentLayer;\n }\n\n // 2. remove the layers from the chain\n this.#topLayer = this.#topLayer.removeLayer(layerId);\n\n // 3. check each cache key to see if it is different in the new chain\n for (const [k, oldEntry] of cacheKeys) {\n const currentEntry = this.#topLayer.get(k);\n\n // 4. if different, update the subject\n if (oldEntry !== currentEntry) {\n const x = currentEntry ?? createInitEntry(k);\n // We are going to be pretty lazy here and just re-emit the value.\n // In the future it may benefit us to deep equal check her but I think\n // the subjects are effectively doing this anyway.\n this.peekSubject(k)?.next(\n {\n // eslint-disable-next-line @typescript-eslint/no-misused-spread\n ...(currentEntry ?? createInitEntry(k)),\n isOptimistic:\n currentEntry?.value !== this.#truthLayer.get(k)?.value,\n },\n );\n }\n }\n }\n\n getCacheKey<K extends KnownCacheKey>(\n type: K[\"type\"],\n ...args: K[\"__cacheKey\"][\"args\"]\n ): K {\n return this.#refCounts.register(this.#cacheKeys.get(type, ...args));\n }\n\n peekSubject = <KEY extends KnownCacheKey>(\n cacheKey: KEY,\n ):\n | BehaviorSubject<SubjectPayload<KEY>>\n | undefined =>\n {\n return this.#cacheKeyToSubject.get(cacheKey);\n };\n\n getSubject = <KEY extends KnownCacheKey>(\n cacheKey: KEY,\n ): BehaviorSubject<SubjectPayload<KEY>> => {\n let subject = this.#cacheKeyToSubject.get(cacheKey);\n if (!subject) {\n const initialValue: Entry<KEY> = this.#topLayer.get(cacheKey)\n ?? createInitEntry(cacheKey);\n\n subject = new BehaviorSubject({\n // eslint-disable-next-line @typescript-eslint/no-misused-spread\n ...initialValue,\n isOptimistic:\n initialValue.value !== this.#truthLayer.get(cacheKey)?.value,\n });\n this.#cacheKeyToSubject.set(cacheKey, subject);\n }\n\n return subject;\n };\n\n public canonicalizeWhereClause<\n T extends ObjectTypeDefinition | InterfaceDefinition,\n >(\n where: WhereClause<T>,\n ): Canonical<SimpleWhereClause> {\n return this.whereCanonicalizer.canonicalize(where);\n }\n\n peekQuery<K extends KnownCacheKey>(\n cacheKey: K,\n ): K[\"__cacheKey\"][\"query\"] | undefined {\n return this.#queries.get(cacheKey) as K[\"__cacheKey\"][\"query\"] | undefined;\n }\n\n getQuery<K extends KnownCacheKey>(\n cacheKey: K,\n createQuery: () => K[\"__cacheKey\"][\"query\"],\n ): K[\"__cacheKey\"][\"query\"] {\n let query = this.peekQuery(cacheKey);\n if (!query) {\n query = createQuery();\n this.#queries.set(cacheKey, query);\n }\n return query;\n }\n\n public getValue<K extends KnownCacheKey>(\n cacheKey: K,\n ): Entry<K> | undefined {\n return this.#topLayer.get(cacheKey);\n }\n\n batch = <X>(\n { optimisticId, changes = createChangedObjects() }: {\n optimisticId?: OptimisticId;\n changes?: Changes;\n },\n batchFn: (batchContext: BatchContext) => X,\n ): {\n batchResult: BatchContext;\n retVal: X;\n changes: Changes;\n } => {\n invariant(\n optimisticId === undefined || !!optimisticId,\n \"optimistic must be undefined or not falsy\",\n );\n\n let needsLayer = optimisticId !== undefined;\n const batchContext: BatchContext = {\n changes,\n createLayerIfNeeded: () => {\n if (needsLayer) {\n this.#topLayer = this.#topLayer.addLayer(optimisticId);\n needsLayer = false;\n }\n },\n optimisticWrite: !!optimisticId,\n write: (cacheKey, value, status) => {\n const oldTopValue = this.#topLayer.get(cacheKey);\n\n if (optimisticId) batchContext.createLayerIfNeeded();\n\n const writeLayer = optimisticId\n ? this.#topLayer\n : this.#truthLayer;\n const newValue = new Entry(\n cacheKey,\n value,\n Date.now(),\n status,\n );\n\n writeLayer.set(cacheKey, newValue);\n\n const newTopValue = this.#topLayer.get(cacheKey);\n\n if (oldTopValue !== newTopValue) {\n this.getSubject(cacheKey)?.next({\n // eslint-disable-next-line @typescript-eslint/no-misused-spread\n ...newValue,\n isOptimistic:\n newTopValue?.value !== this.#truthLayer.get(cacheKey)?.value,\n });\n }\n\n return newValue;\n },\n delete: (cacheKey, status) => {\n return batchContext.write(cacheKey, tombstone, status);\n },\n read: (cacheKey) => {\n return optimisticId\n ? this.#topLayer.get(cacheKey)\n : this.#truthLayer.get(cacheKey);\n },\n };\n\n const retVal = batchFn(batchContext);\n this.maybeRevalidateQueries(changes, optimisticId).catch(e => {\n // we don't want batch() to return a promise,\n // so we settle for logging an error here instead of\n // dropping it on the floor.\n if (this.logger) {\n this.logger.error(\"Unhandled error in batch\", e);\n } else {\n // eslint-disable-next-line no-console\n console.error(\"Unhandled error in batch\", e);\n throw e;\n }\n });\n\n return {\n batchResult: batchContext,\n retVal: retVal,\n changes: batchContext.changes,\n };\n };\n\n public invalidateObject<T extends ObjectTypeDefinition>(\n apiName: T[\"apiName\"] | T,\n pk: PrimaryKeyType<T>,\n ): Promise<unknown> {\n if (typeof apiName !== \"string\") {\n apiName = apiName.apiName;\n }\n\n return this.objects.getQuery({\n apiName,\n pk,\n }).revalidate(/* force */ true);\n }\n\n async maybeRevalidateQueries(\n changes: Changes,\n optimisticId?: OptimisticId | undefined,\n ): Promise<void> {\n if (changes.isEmpty()) {\n if (process.env.NODE_ENV !== \"production\") {\n // todo\n this.logger?.child({ methodName: \"maybeRevalidateQueries\" }).debug(\n \"No changes, aborting\",\n );\n }\n return;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n // todo\n this.logger?.child({ methodName: \"maybeRevalidateQueries\" }).debug(\n DEBUG_ONLY__changesToString(changes),\n { optimisticId },\n );\n }\n\n try {\n const promises: Array<Promise<unknown>> = [];\n for (const cacheKey of this.#queries.keys()) {\n const promise = this.peekQuery(cacheKey)?.maybeUpdateAndRevalidate?.(\n changes,\n optimisticId,\n );\n if (promise) promises.push(promise);\n }\n await Promise.all(promises);\n } finally {\n if (process.env.NODE_ENV !== \"production\") {\n // todo\n this.logger?.child({ methodName: \"maybeRevalidateQueries\" }).debug(\n \"in finally\",\n DEBUG_ONLY__changesToString(changes),\n );\n }\n }\n }\n\n /**\n * Invalidates all cache entries for a specific object type.\n * This will revalidate:\n * 1. All objects of the specified type\n * 2. All lists of the specified type\n * 3. All links where the source object is of the specified type\n *\n * @param apiName - The API name of the object type to invalidate\n * @param changes - Optional changes object to track what has been modified\n * @returns Promise that resolves when all invalidations are complete\n */\n public invalidateObjectType<T extends ObjectTypeDefinition>(\n apiName: T[\"apiName\"] | T,\n changes: Changes | undefined,\n ): Promise<void> {\n if (typeof apiName !== \"string\") {\n apiName = apiName.apiName;\n }\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.child({ methodName: \"invalidateObjectType\" }).info(\n changes ? DEBUG_ONLY__changesToString(changes) : void 0,\n );\n }\n\n const promises: Array<Promise<void>> = [];\n\n for (const cacheKey of this.#truthLayer.keys()) {\n if (changes && changes.modified.has(cacheKey)) {\n continue;\n }\n const query = this.peekQuery(cacheKey);\n if (!query) continue;\n\n promises.push(query.invalidateObjectType(apiName, changes));\n }\n\n // we use allSettled here because we don't care if it succeeds or fails, just that they all complete.\n return Promise.allSettled(promises).then(() => void 0);\n }\n\n retain(cacheKey: KnownCacheKey): void {\n this.#refCounts.retain(cacheKey);\n }\n\n release(cacheKey: KnownCacheKey): void {\n this.#refCounts.release(cacheKey);\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"Store.js","names":["invariant","additionalContext","DEBUG_REFCOUNTS","ActionApplication","CacheKeys","createChangedObjects","DEBUG_ONLY__changesToString","Layers","LinksHelper","ListsHelper","ObjectsHelper","OrderByCanonicalizer","Queries","WhereClauseCanonicalizer","Store","whereCanonicalizer","orderByCanonicalizer","queries","layers","logger","onRevalidate","maybeRevalidateQueries","bind","subjects","constructor","client","child","msgPrefix","cacheKeys","onDestroy","cleanupCacheKey","lists","objects","links","key","subject","peek","console","log","JSON","stringify","closed","observed","type","otherKeys","process","env","NODE_ENV","delete","applyAction","action","args","opts","validateAction","result","$validateOnly","$returnEdits","getValue","cacheKey","top","get","batch","optimisticId","changes","batchFn","invalidateObject","apiName","pk","getQuery","revalidate","#maybeRevalidateQueries","methodName","undefined","isEmpty","debug","promises","keys","promise","maybeUpdateAndRevalidate","push","Promise","all","invalidateObjectType","info","truth","modified","has","query","allSettled","then"],"sources":["Store.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n ActionDefinition,\n ActionEditResponse,\n ActionValidationResponse,\n Logger,\n ObjectTypeDefinition,\n PrimaryKeyType,\n} from \"@osdk/api\";\nimport invariant from \"tiny-invariant\";\nimport type { ActionSignatureFromDef } from \"../../actions/applyAction.js\";\nimport { additionalContext, type Client } from \"../../Client.js\";\nimport { DEBUG_REFCOUNTS } from \"../DebugFlags.js\";\nimport type { OptimisticBuilder } from \"../OptimisticBuilder.js\";\nimport { ActionApplication } from \"./actions/ActionApplication.js\";\nimport type { BatchContext } from \"./BatchContext.js\";\nimport { CacheKeys } from \"./CacheKeys.js\";\nimport {\n type Changes,\n createChangedObjects,\n DEBUG_ONLY__changesToString,\n} from \"./Changes.js\";\nimport type { KnownCacheKey } from \"./KnownCacheKey.js\";\nimport type { Entry } from \"./Layer.js\";\nimport { Layers } from \"./Layers.js\";\nimport { LinksHelper } from \"./links/LinksHelper.js\";\nimport { ListsHelper } from \"./list/ListsHelper.js\";\nimport { ObjectsHelper } from \"./object/ObjectsHelper.js\";\nimport { type OptimisticId } from \"./OptimisticId.js\";\nimport { OrderByCanonicalizer } from \"./OrderByCanonicalizer.js\";\nimport { Queries } from \"./Queries.js\";\nimport type { Subjects } from \"./Subjects.js\";\nimport { WhereClauseCanonicalizer } from \"./WhereClauseCanonicalizer.js\";\n\nexport namespace Store {\n export interface ApplyActionOptions {\n optimisticUpdate?: (ctx: OptimisticBuilder) => void;\n }\n}\n\n/*\n Notes:\n - Subjects are one per type per store (by cache key)\n - Data is one per layer per cache key\n*/\n\n/**\n * Central data store with layered cache architecture.\n * - Truth layer: server state | Optimistic layers: pending changes\n * - Reference counting prevents memory leaks\n * - Batch operations ensure consistency\n */\nexport class Store {\n readonly whereCanonicalizer: WhereClauseCanonicalizer =\n new WhereClauseCanonicalizer();\n readonly orderByCanonicalizer: OrderByCanonicalizer =\n new OrderByCanonicalizer();\n\n readonly client: Client;\n\n /** @internal */\n readonly logger?: Logger;\n\n readonly cacheKeys: CacheKeys<KnownCacheKey>;\n readonly queries: Queries = new Queries();\n\n readonly layers: Layers = new Layers({\n logger: this.logger,\n onRevalidate: this.#maybeRevalidateQueries.bind(this),\n });\n readonly subjects: Subjects = this.layers.subjects;\n\n // these are hopefully temporary\n readonly lists: ListsHelper;\n readonly objects: ObjectsHelper;\n readonly links: LinksHelper;\n\n constructor(client: Client) {\n this.logger = client[additionalContext].logger?.child({}, {\n msgPrefix: \"Store\",\n });\n this.client = client;\n\n this.cacheKeys = new CacheKeys<KnownCacheKey>({\n onDestroy: this.#cleanupCacheKey,\n });\n\n this.lists = new ListsHelper(\n this,\n this.cacheKeys,\n this.whereCanonicalizer,\n this.orderByCanonicalizer,\n );\n this.objects = new ObjectsHelper(this, this.cacheKeys);\n this.links = new LinksHelper(\n this,\n this.cacheKeys,\n this.whereCanonicalizer,\n this.orderByCanonicalizer,\n );\n }\n\n /**\n * Called after a key is no longer retained and the timeout has elapsed\n * @param key\n */\n #cleanupCacheKey = (key: KnownCacheKey) => {\n const subject = this.subjects.peek(key);\n\n if (DEBUG_REFCOUNTS) {\n // eslint-disable-next-line no-console\n console.log(\n `CacheKey cleaning up (${\n JSON.stringify({\n closed: subject?.closed,\n observed: subject?.observed,\n })\n })`,\n JSON.stringify([key.type, ...key.otherKeys], null, 2),\n );\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n invariant(subject);\n }\n\n this.subjects.delete(key);\n this.queries.delete(key);\n };\n\n applyAction: <Q extends ActionDefinition<any>>(\n action: Q,\n args:\n | Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0]\n | Array<Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0]>,\n opts?: Store.ApplyActionOptions,\n ) => Promise<ActionEditResponse> = async (action, args, opts) => {\n return await new ActionApplication(this).applyAction(action, args, opts);\n };\n\n validateAction: <Q extends ActionDefinition<any>>(\n action: Q,\n args: Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0],\n ) => Promise<ActionValidationResponse> = async (action, args) => {\n const result = await this.client(action).applyAction(args as any, {\n $validateOnly: true,\n $returnEdits: false,\n });\n return result as ActionValidationResponse;\n };\n\n public getValue<K extends KnownCacheKey>(\n cacheKey: K,\n ): Entry<K> | undefined {\n return this.layers.top.get(cacheKey);\n }\n\n batch<X>(\n { optimisticId, changes = createChangedObjects() }: {\n optimisticId?: OptimisticId;\n changes?: Changes;\n },\n batchFn: (batchContext: BatchContext) => X,\n ): {\n batchResult: BatchContext;\n retVal: X;\n changes: Changes;\n } {\n return this.layers.batch({ optimisticId, changes }, batchFn);\n }\n\n public invalidateObject<T extends ObjectTypeDefinition>(\n apiName: T[\"apiName\"] | T,\n pk: PrimaryKeyType<T>,\n ): Promise<unknown> {\n if (typeof apiName !== \"string\") {\n apiName = apiName.apiName;\n }\n\n return this.objects.getQuery({\n apiName,\n pk,\n }).revalidate(/* force */ true);\n }\n\n async #maybeRevalidateQueries(\n changes: Changes,\n optimisticId?: OptimisticId | undefined,\n ): Promise<void> {\n const logger = process.env.NODE_ENV !== \"production\"\n ? this.logger?.child({ methodName: \"maybeRevalidateQueries\" })\n : undefined;\n\n if (changes.isEmpty()) {\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(\"No changes, aborting\");\n }\n return;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(DEBUG_ONLY__changesToString(changes), { optimisticId });\n }\n\n try {\n const promises: Array<Promise<unknown>> = [];\n for (const cacheKey of this.queries.keys()) {\n const promise = this.queries.peek(cacheKey)?.maybeUpdateAndRevalidate?.(\n changes,\n optimisticId,\n );\n if (promise) promises.push(promise);\n }\n await Promise.all(promises);\n } finally {\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(\"in finally\", DEBUG_ONLY__changesToString(changes));\n }\n }\n }\n\n /**\n * Invalidates all cache entries for a specific object type.\n * This will revalidate:\n * 1. All objects of the specified type\n * 2. All lists of the specified type\n * 3. All links where the source object is of the specified type\n *\n * @param apiName - The API name of the object type to invalidate\n * @param changes - Optional changes object to track what has been modified\n * @returns Promise that resolves when all invalidations are complete\n */\n public invalidateObjectType<T extends ObjectTypeDefinition>(\n apiName: T[\"apiName\"] | T,\n changes: Changes | undefined,\n ): Promise<void> {\n if (typeof apiName !== \"string\") {\n apiName = apiName.apiName;\n }\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.child({ methodName: \"invalidateObjectType\" }).info(\n changes ? DEBUG_ONLY__changesToString(changes) : void 0,\n );\n }\n\n const promises: Array<Promise<void>> = [];\n\n for (const cacheKey of this.layers.truth.keys()) {\n if (changes && changes.modified.has(cacheKey)) {\n continue;\n }\n const query = this.queries.peek(cacheKey);\n if (!query) continue;\n\n promises.push(query.invalidateObjectType(apiName, changes));\n }\n\n // we use allSettled here because we don't care if it succeeds or fails, just that they all complete.\n return Promise.allSettled(promises).then(() => void 0);\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -304,6 +304,7 @@ describe(Store, () => {
304
304
  describe("with mock server", () => {
305
305
  let client;
306
306
  let cache;
307
+ let cacheKeys;
307
308
  let employeesAsServerReturns;
308
309
  let mutatedEmployees;
309
310
  beforeAll(async () => {
@@ -325,13 +326,14 @@ describe(Store, () => {
325
326
  });
326
327
  beforeEach(() => {
327
328
  cache = new Store(client);
329
+ cacheKeys = cache.cacheKeys;
328
330
  return () => {
329
331
  cache = undefined;
330
332
  };
331
333
  });
332
334
  it("basic single object works", async () => {
333
335
  const emp = employeesAsServerReturns[0];
334
- const cacheKey = cache.getCacheKey("object", "Employee", emp.$primaryKey);
336
+ const cacheKey = cacheKeys.get("object", "Employee", emp.$primaryKey);
335
337
 
336
338
  // starts empty
337
339
  expect(cache.getValue(cacheKey)?.value).toBeUndefined();
@@ -372,7 +374,7 @@ describe(Store, () => {
372
374
  }), "loaded");
373
375
 
374
376
  // remove the optimistic write
375
- cache.removeLayer(optimisticId);
377
+ cache.layers.remove(optimisticId);
376
378
  expectSingleObjectCallAndClear(subFn, emp, "loaded");
377
379
  });
378
380
  it("rolls back to an updated real value", async () => {
@@ -432,7 +434,7 @@ describe(Store, () => {
432
434
  }, [truthUpdatedEmployee]);
433
435
 
434
436
  // remove the optimistic write
435
- cache.removeLayer(optimisticId);
437
+ cache.layers.remove(optimisticId);
436
438
 
437
439
  // see the object observation get updated
438
440
  expectSingleObjectCallAndClear(empSubFn, truthUpdatedEmployee, "loaded");
@@ -474,7 +476,7 @@ describe(Store, () => {
474
476
  expect(subFn.next).not.toHaveBeenCalled();
475
477
 
476
478
  // remove the optimistic write
477
- cache.removeLayer(optimisticId);
479
+ cache.layers.remove(optimisticId);
478
480
  expectSingleObjectCallAndClear(subFn, truthUpdatedEmployee);
479
481
  expectNoMoreCalls(subFn);
480
482
  });
@@ -502,7 +504,7 @@ describe(Store, () => {
502
504
  expectSingleListCallAndClear(subListFn, [emp], {
503
505
  status: "loaded"
504
506
  });
505
- const cacheKey = cache.getCacheKey("object", emp.$apiName, emp.$primaryKey);
507
+ const cacheKey = cacheKeys.get("object", emp.$apiName, emp.$primaryKey);
506
508
 
507
509
  // Actual test is here, prior to this is setup
508
510
  testStage("delete the object");
@@ -1096,7 +1098,7 @@ describe(Store, () => {
1096
1098
  isOptimistic: false
1097
1099
  })
1098
1100
  });
1099
- const object = store.getValue(store.getCacheKey("object", "Todo", 0))?.value;
1101
+ const object = store.getValue(store.cacheKeys.get("object", "Todo", 0))?.value;
1100
1102
  !object ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
1101
1103
 
1102
1104
  // at this point we have an observation properly set up
@@ -1363,7 +1365,7 @@ describe(Store, () => {
1363
1365
  $apiName: "Employee",
1364
1366
  $title: `truth ${i}`
1365
1367
  }));
1366
- const cacheKeys = baseObjects.map(obj => store.getCacheKey("object", "Employee", obj.$primaryKey));
1368
+ const cacheKeys = baseObjects.map(obj => store.cacheKeys.get("object", "Employee", obj.$primaryKey));
1367
1369
 
1368
1370
  // set the truth
1369
1371
  for (const obj of baseObjects) {
@@ -1398,7 +1400,7 @@ describe(Store, () => {
1398
1400
  }
1399
1401
 
1400
1402
  // remove the first layer
1401
- store.removeLayer(layerIds[0]);
1403
+ store.layers.remove(layerIds[0]);
1402
1404
 
1403
1405
  // should have truth object 1 and optimistic object 2
1404
1406
  expect(getObject(store, "Employee", 1)).toEqual(expect.objectContaining({
@@ -1409,7 +1411,7 @@ describe(Store, () => {
1409
1411
  }));
1410
1412
 
1411
1413
  // remove the second layer
1412
- store.removeLayer(layerIds[1]);
1414
+ store.layers.remove(layerIds[1]);
1413
1415
 
1414
1416
  // should have truth objects
1415
1417
  for (const obj of baseObjects) {