@isograph/react 0.0.0-main-c938c1af → 0.0.0-main-4693ce16

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.
@@ -26,6 +26,11 @@ export type FragmentSubscription<TReadFromStore extends {
26
26
  readonly fragmentReference: FragmentReference<TReadFromStore, any>;
27
27
  readonly readerAst: ReaderAst<TReadFromStore>;
28
28
  };
29
+ type AnyChangesToRecordSubscription = {
30
+ readonly kind: 'AnyChangesToRecord';
31
+ readonly callback: () => void;
32
+ readonly recordId: DataId;
33
+ };
29
34
  type AnyRecordSubscription = {
30
35
  readonly kind: 'AnyRecords';
31
36
  readonly callback: () => void;
@@ -33,7 +38,7 @@ type AnyRecordSubscription = {
33
38
  type Subscription = FragmentSubscription<{
34
39
  parameters: object;
35
40
  data: object;
36
- }> | AnyRecordSubscription;
41
+ }> | AnyChangesToRecordSubscription | AnyRecordSubscription;
37
42
  type Subscriptions = Set<Subscription>;
38
43
  type CacheMap<T> = {
39
44
  [index: string]: ParentCache<T>;
@@ -26,11 +26,12 @@ type NetworkResponseObject = {
26
26
  };
27
27
  export declare function normalizeData(environment: IsographEnvironment, normalizationAst: NormalizationAst, networkResponse: NetworkResponseObject, variables: Variables, nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[]): Set<DataId>;
28
28
  export declare function subscribeToAnyChange(environment: IsographEnvironment, callback: () => void): () => void;
29
+ export declare function subscribeToAnyChangesToRecord(environment: IsographEnvironment, recordId: DataId, callback: () => void): () => void;
29
30
  export declare function subscribe<TReadFromStore extends {
30
31
  parameters: object;
31
32
  data: object;
32
33
  }>(environment: IsographEnvironment, encounteredDataAndRecords: WithEncounteredRecords<TReadFromStore>, fragmentReference: FragmentReference<TReadFromStore, any>, callback: (newEncounteredDataAndRecords: WithEncounteredRecords<TReadFromStore>) => void, readerAst: ReaderAst<TReadFromStore>): () => void;
33
- export declare function onNextChange(environment: IsographEnvironment): Promise<void>;
34
+ export declare function onNextChangeToRecord(environment: IsographEnvironment, recordId: DataId): Promise<void>;
34
35
  export declare function getParentRecordKey(astNode: NormalizationLinkedField | NormalizationScalarField | ReaderLinkedField | ReaderScalarField, variables: Variables): string;
35
36
  export declare const FIRST_SPLIT_KEY = "____";
36
37
  export declare const SECOND_SPLIT_KEY = "___";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SECOND_SPLIT_KEY = exports.FIRST_SPLIT_KEY = exports.getParentRecordKey = exports.onNextChange = exports.subscribe = exports.subscribeToAnyChange = exports.normalizeData = exports.getOrCreateCacheForArtifact = exports.stableCopy = exports.getOrCreateItemInSuspenseCache = void 0;
3
+ exports.SECOND_SPLIT_KEY = exports.FIRST_SPLIT_KEY = exports.getParentRecordKey = exports.onNextChangeToRecord = exports.subscribe = exports.subscribeToAnyChangesToRecord = exports.subscribeToAnyChange = exports.normalizeData = exports.getOrCreateCacheForArtifact = exports.stableCopy = exports.getOrCreateItemInSuspenseCache = void 0;
4
4
  const react_disposable_state_1 = require("@isograph/react-disposable-state");
5
5
  const IsographEnvironment_1 = require("./IsographEnvironment");
6
6
  const read_1 = require("./read");
@@ -96,6 +96,16 @@ function subscribeToAnyChange(environment, callback) {
96
96
  return () => environment.subscriptions.delete(subscription);
97
97
  }
98
98
  exports.subscribeToAnyChange = subscribeToAnyChange;
99
+ function subscribeToAnyChangesToRecord(environment, recordId, callback) {
100
+ const subscription = {
101
+ kind: 'AnyChangesToRecord',
102
+ recordId,
103
+ callback,
104
+ };
105
+ environment.subscriptions.add(subscription);
106
+ return () => environment.subscriptions.delete(subscription);
107
+ }
108
+ exports.subscribeToAnyChangesToRecord = subscribeToAnyChangesToRecord;
99
109
  // TODO we should re-read and call callback if the value has changed
100
110
  function subscribe(environment, encounteredDataAndRecords, fragmentReference, callback, readerAst) {
101
111
  const fragmentSubscription = {
@@ -109,15 +119,15 @@ function subscribe(environment, encounteredDataAndRecords, fragmentReference, ca
109
119
  return () => environment.subscriptions.delete(fragmentSubscription);
110
120
  }
111
121
  exports.subscribe = subscribe;
112
- function onNextChange(environment) {
122
+ function onNextChangeToRecord(environment, recordId) {
113
123
  return new Promise((resolve) => {
114
- const unsubscribe = subscribeToAnyChange(environment, () => {
124
+ const unsubscribe = subscribeToAnyChangesToRecord(environment, recordId, () => {
115
125
  unsubscribe();
116
126
  resolve();
117
127
  });
118
128
  });
119
129
  }
120
- exports.onNextChange = onNextChange;
130
+ exports.onNextChangeToRecord = onNextChangeToRecord;
121
131
  // Calls to readButDoNotEvaluate can suspend (i.e. throw a promise).
122
132
  // Maybe in the future, they will be able to throw errors.
123
133
  //
@@ -181,7 +191,14 @@ function callSubscriptions(environment, recordsEncounteredWhenNormalizing) {
181
191
  return;
182
192
  }
183
193
  case 'AnyRecords': {
184
- return subscription.callback();
194
+ subscription.callback();
195
+ return;
196
+ }
197
+ case 'AnyChangesToRecord': {
198
+ if (recordsEncounteredWhenNormalizing.has(subscription.recordId)) {
199
+ subscription.callback();
200
+ }
201
+ return;
185
202
  }
186
203
  default: {
187
204
  // Ensure we have covered all variants
package/dist/core/read.js CHANGED
@@ -29,11 +29,11 @@ function readButDoNotEvaluate(environment, fragmentReference, networkRequestOpti
29
29
  networkRequestOptions.throwOnNetworkError) {
30
30
  // TODO assert that the network request state is not Err
31
31
  throw new Promise((resolve, reject) => {
32
- (0, cache_1.onNextChange)(environment).then(resolve);
32
+ (0, cache_1.onNextChangeToRecord)(environment, response.recordId).then(resolve);
33
33
  fragmentReference.networkRequest.promise.catch(reject);
34
34
  });
35
35
  }
36
- throw (0, cache_1.onNextChange)(environment);
36
+ throw (0, cache_1.onNextChangeToRecord)(environment, response.recordId);
37
37
  }
38
38
  else {
39
39
  return {
@@ -51,6 +51,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
51
51
  return {
52
52
  kind: 'MissingData',
53
53
  reason: 'No record for root ' + root,
54
+ recordId: root,
54
55
  };
55
56
  }
56
57
  if (storeRecord === null) {
@@ -72,6 +73,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
72
73
  return {
73
74
  kind: 'MissingData',
74
75
  reason: 'No value for ' + storeRecordName + ' on root ' + root,
76
+ recordId: root,
75
77
  };
76
78
  }
77
79
  target[(_a = field.alias) !== null && _a !== void 0 ? _a : field.fieldName] = value;
@@ -93,6 +95,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
93
95
  root +
94
96
  '. Link is ' +
95
97
  JSON.stringify(item),
98
+ recordId: root,
96
99
  };
97
100
  }
98
101
  else if (link === null) {
@@ -110,6 +113,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
110
113
  '. Link is ' +
111
114
  JSON.stringify(item),
112
115
  nestedReason: result,
116
+ recordId: result.recordId,
113
117
  };
114
118
  }
115
119
  results.push(result.data);
@@ -131,6 +135,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
131
135
  root +
132
136
  '. Link is ' +
133
137
  JSON.stringify(value),
138
+ recordId: root,
134
139
  };
135
140
  }
136
141
  else {
@@ -148,6 +153,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
148
153
  kind: 'MissingData',
149
154
  reason: 'Missing data for ' + storeRecordName + ' on root ' + root,
150
155
  nestedReason: data,
156
+ recordId: data.recordId,
151
157
  };
152
158
  }
153
159
  target[(_e = field.alias) !== null && _e !== void 0 ? _e : field.fieldName] = data.data;
@@ -167,6 +173,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
167
173
  kind: 'MissingData',
168
174
  reason: 'Missing data for ' + field.alias + ' on root ' + root,
169
175
  nestedReason: data,
176
+ recordId: data.recordId,
170
177
  };
171
178
  }
172
179
  else {
@@ -201,6 +208,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
201
208
  kind: 'MissingData',
202
209
  reason: 'Missing data for ' + field.alias + ' on root ' + root,
203
210
  nestedReason: data,
211
+ recordId: data.recordId,
204
212
  };
205
213
  }
206
214
  else {
@@ -244,6 +252,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
244
252
  kind: 'MissingData',
245
253
  reason: 'Missing data for ' + field.alias + ' on root ' + root,
246
254
  nestedReason: refetchReaderParams,
255
+ recordId: refetchReaderParams.recordId,
247
256
  };
248
257
  }
249
258
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isograph/react",
3
- "version": "0.0.0-main-c938c1af",
3
+ "version": "0.0.0-main-4693ce16",
4
4
  "description": "Use Isograph with React",
5
5
  "homepage": "https://isograph.dev",
6
6
  "main": "dist/index.js",
@@ -17,9 +17,9 @@
17
17
  "tsc": "tsc"
18
18
  },
19
19
  "dependencies": {
20
- "@isograph/disposable-types": "0.0.0-main-c938c1af",
21
- "@isograph/react-disposable-state": "0.0.0-main-c938c1af",
22
- "@isograph/reference-counted-pointer": "0.0.0-main-c938c1af"
20
+ "@isograph/disposable-types": "0.0.0-main-4693ce16",
21
+ "@isograph/react-disposable-state": "0.0.0-main-4693ce16",
22
+ "@isograph/reference-counted-pointer": "0.0.0-main-4693ce16"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "react": "18.2.0"
@@ -26,6 +26,13 @@ export type FragmentSubscription<
26
26
  readonly fragmentReference: FragmentReference<TReadFromStore, any>;
27
27
  readonly readerAst: ReaderAst<TReadFromStore>;
28
28
  };
29
+
30
+ type AnyChangesToRecordSubscription = {
31
+ readonly kind: 'AnyChangesToRecord';
32
+ readonly callback: () => void;
33
+ readonly recordId: DataId;
34
+ };
35
+
29
36
  type AnyRecordSubscription = {
30
37
  readonly kind: 'AnyRecords';
31
38
  readonly callback: () => void;
@@ -33,6 +40,7 @@ type AnyRecordSubscription = {
33
40
 
34
41
  type Subscription =
35
42
  | FragmentSubscription<{ parameters: object; data: object }>
43
+ | AnyChangesToRecordSubscription
36
44
  | AnyRecordSubscription;
37
45
  type Subscriptions = Set<Subscription>;
38
46
  // Should this be a map?
package/src/core/cache.ts CHANGED
@@ -183,6 +183,20 @@ export function subscribeToAnyChange(
183
183
  return () => environment.subscriptions.delete(subscription);
184
184
  }
185
185
 
186
+ export function subscribeToAnyChangesToRecord(
187
+ environment: IsographEnvironment,
188
+ recordId: DataId,
189
+ callback: () => void,
190
+ ): () => void {
191
+ const subscription = {
192
+ kind: 'AnyChangesToRecord',
193
+ recordId,
194
+ callback,
195
+ } as const;
196
+ environment.subscriptions.add(subscription);
197
+ return () => environment.subscriptions.delete(subscription);
198
+ }
199
+
186
200
  // TODO we should re-read and call callback if the value has changed
187
201
  export function subscribe<
188
202
  TReadFromStore extends { parameters: object; data: object },
@@ -206,12 +220,19 @@ export function subscribe<
206
220
  return () => environment.subscriptions.delete(fragmentSubscription);
207
221
  }
208
222
 
209
- export function onNextChange(environment: IsographEnvironment): Promise<void> {
223
+ export function onNextChangeToRecord(
224
+ environment: IsographEnvironment,
225
+ recordId: DataId,
226
+ ): Promise<void> {
210
227
  return new Promise((resolve) => {
211
- const unsubscribe = subscribeToAnyChange(environment, () => {
212
- unsubscribe();
213
- resolve();
214
- });
228
+ const unsubscribe = subscribeToAnyChangesToRecord(
229
+ environment,
230
+ recordId,
231
+ () => {
232
+ unsubscribe();
233
+ resolve();
234
+ },
235
+ );
215
236
  });
216
237
  }
217
238
 
@@ -294,7 +315,14 @@ function callSubscriptions(
294
315
  return;
295
316
  }
296
317
  case 'AnyRecords': {
297
- return subscription.callback();
318
+ subscription.callback();
319
+ return;
320
+ }
321
+ case 'AnyChangesToRecord': {
322
+ if (recordsEncounteredWhenNormalizing.has(subscription.recordId)) {
323
+ subscription.callback();
324
+ }
325
+ return;
298
326
  }
299
327
  default: {
300
328
  // Ensure we have covered all variants
package/src/core/read.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CleanupFn } from '@isograph/isograph-disposable-types/dist';
2
- import { getParentRecordKey, onNextChange } from './cache';
2
+ import { getParentRecordKey, onNextChangeToRecord } from './cache';
3
3
  import { getOrCreateCachedComponent } from './componentCache';
4
4
  import {
5
5
  IsographEntrypoint,
@@ -77,11 +77,11 @@ export function readButDoNotEvaluate<
77
77
  ) {
78
78
  // TODO assert that the network request state is not Err
79
79
  throw new Promise((resolve, reject) => {
80
- onNextChange(environment).then(resolve);
80
+ onNextChangeToRecord(environment, response.recordId).then(resolve);
81
81
  fragmentReference.networkRequest.promise.catch(reject);
82
82
  });
83
83
  }
84
- throw onNextChange(environment);
84
+ throw onNextChangeToRecord(environment, response.recordId);
85
85
  } else {
86
86
  return {
87
87
  encounteredRecords: mutableEncounteredRecords,
@@ -100,6 +100,7 @@ type ReadDataResult<TReadFromStore> =
100
100
  readonly kind: 'MissingData';
101
101
  readonly reason: string;
102
102
  readonly nestedReason?: ReadDataResult<unknown>;
103
+ readonly recordId: DataId;
103
104
  };
104
105
 
105
106
  function readData<TReadFromStore>(
@@ -118,6 +119,7 @@ function readData<TReadFromStore>(
118
119
  return {
119
120
  kind: 'MissingData',
120
121
  reason: 'No record for root ' + root,
122
+ recordId: root,
121
123
  };
122
124
  }
123
125
 
@@ -142,6 +144,7 @@ function readData<TReadFromStore>(
142
144
  return {
143
145
  kind: 'MissingData',
144
146
  reason: 'No value for ' + storeRecordName + ' on root ' + root,
147
+ recordId: root,
145
148
  };
146
149
  }
147
150
  target[field.alias ?? field.fieldName] = value;
@@ -164,6 +167,7 @@ function readData<TReadFromStore>(
164
167
  root +
165
168
  '. Link is ' +
166
169
  JSON.stringify(item),
170
+ recordId: root,
167
171
  };
168
172
  } else if (link === null) {
169
173
  results.push(null);
@@ -190,6 +194,7 @@ function readData<TReadFromStore>(
190
194
  '. Link is ' +
191
195
  JSON.stringify(item),
192
196
  nestedReason: result,
197
+ recordId: result.recordId,
193
198
  };
194
199
  }
195
200
  results.push(result.data);
@@ -219,6 +224,7 @@ function readData<TReadFromStore>(
219
224
  root +
220
225
  '. Link is ' +
221
226
  JSON.stringify(value),
227
+ recordId: root,
222
228
  };
223
229
  } else {
224
230
  link = altLink;
@@ -243,6 +249,7 @@ function readData<TReadFromStore>(
243
249
  kind: 'MissingData',
244
250
  reason: 'Missing data for ' + storeRecordName + ' on root ' + root,
245
251
  nestedReason: data,
252
+ recordId: data.recordId,
246
253
  };
247
254
  }
248
255
  target[field.alias ?? field.fieldName] = data.data;
@@ -269,6 +276,7 @@ function readData<TReadFromStore>(
269
276
  kind: 'MissingData',
270
277
  reason: 'Missing data for ' + field.alias + ' on root ' + root,
271
278
  nestedReason: data,
279
+ recordId: data.recordId,
272
280
  };
273
281
  } else {
274
282
  const refetchQueryIndex = field.refetchQuery;
@@ -322,6 +330,7 @@ function readData<TReadFromStore>(
322
330
  kind: 'MissingData',
323
331
  reason: 'Missing data for ' + field.alias + ' on root ' + root,
324
332
  nestedReason: data,
333
+ recordId: data.recordId,
325
334
  };
326
335
  } else {
327
336
  const firstParameter = {
@@ -377,6 +386,7 @@ function readData<TReadFromStore>(
377
386
  kind: 'MissingData',
378
387
  reason: 'Missing data for ' + field.alias + ' on root ' + root,
379
388
  nestedReason: refetchReaderParams,
389
+ recordId: refetchReaderParams.recordId,
380
390
  };
381
391
  } else {
382
392
  target[field.alias] = (args: any) => {