@isograph/react 0.0.0-main-7e562882 → 0.0.0-main-8821fa52

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.
@@ -1,4 +1,4 @@
1
1
 
2
- > @isograph/react@0.0.0-main-7e562882 compile-typescript /Users/runner/work/isograph/isograph/libs/isograph-react
2
+ > @isograph/react@0.0.0-main-8821fa52 compile-typescript /Users/runner/work/isograph/isograph/libs/isograph-react
3
3
  > rm -rf dist/* && tsc -p tsconfig.pkg.json
4
4
 
@@ -1,21 +1,25 @@
1
1
  import { type EncounteredIds } from './cache';
2
- import { ExtractData, FragmentReference, type UnknownTReadFromStore } from './FragmentReference';
3
- import { IsographEnvironment, type Link } from './IsographEnvironment';
2
+ import { ExtractData, FragmentReference, Variables, type UnknownTReadFromStore } from './FragmentReference';
3
+ import { IsographEnvironment, type DataTypeValue, type Link, type StoreRecord } from './IsographEnvironment';
4
+ import { PromiseWrapper } from './PromiseWrapper';
5
+ import { ReaderAst, type ReaderLinkedField, type ReaderScalarField } from './reader';
4
6
  export type WithEncounteredRecords<T> = {
5
7
  readonly encounteredRecords: EncounteredIds;
6
8
  readonly item: ExtractData<T>;
7
9
  };
8
10
  export declare function readButDoNotEvaluate<TReadFromStore extends UnknownTReadFromStore>(environment: IsographEnvironment, fragmentReference: FragmentReference<TReadFromStore, unknown>, networkRequestOptions: NetworkRequestReaderOptions): WithEncounteredRecords<TReadFromStore>;
9
- export type ReadDataResult<TReadFromStore> = {
11
+ export type ReadDataResultSuccess<Data> = {
10
12
  readonly kind: 'Success';
11
- readonly data: ExtractData<TReadFromStore>;
12
- readonly encounteredRecords: EncounteredIds;
13
- } | {
13
+ readonly data: Data;
14
+ };
15
+ export type ReadDataResult<Data> = ReadDataResultSuccess<Data> | {
14
16
  readonly kind: 'MissingData';
15
17
  readonly reason: string;
16
18
  readonly nestedReason?: ReadDataResult<unknown>;
17
19
  readonly recordLink: Link;
18
20
  };
21
+ export declare function readScalarFieldData(field: ReaderScalarField, storeRecord: StoreRecord, root: Link, variables: Variables): ReadDataResult<string | number | boolean | Link | DataTypeValue[] | null>;
22
+ export declare function readLinkedFieldData(environment: IsographEnvironment, field: ReaderLinkedField, storeRecord: StoreRecord, root: Link, variables: Variables, networkRequest: PromiseWrapper<void, any>, readData: <TReadFromStore>(ast: ReaderAst<TReadFromStore>, root: Link) => ReadDataResult<object>): ReadDataResult<unknown>;
19
23
  export type NetworkRequestReaderOptions = {
20
24
  suspendIfInFlight: boolean;
21
25
  throwOnNetworkError: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/core/read.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAQjB,OAAO,EACL,WAAW,EAEX,iBAAiB,EAEjB,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,mBAAmB,EACnB,KAAK,IAAI,EACV,MAAM,uBAAuB,CAAC;AAe/B,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI;IACtC,QAAQ,CAAC,kBAAkB,EAAE,cAAc,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;CAC/B,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,cAAc,SAAS,qBAAqB,EAE5C,WAAW,EAAE,mBAAmB,EAChC,iBAAiB,EAAE,iBAAiB,CAAC,cAAc,EAAE,OAAO,CAAC,EAC7D,qBAAqB,EAAE,2BAA2B,GACjD,sBAAsB,CAAC,cAAc,CAAC,CAiExC;AAED,MAAM,MAAM,cAAc,CAAC,cAAc,IACrC;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;IAC3C,QAAQ,CAAC,kBAAkB,EAAE,cAAc,CAAC;CAC7C,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IAChD,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;CAC3B,CAAC;AAwoBN,MAAM,MAAM,2BAA2B,GAAG;IACxC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,wBAAgB,oCAAoC,CAClD,qBAAqB,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAAG,IAAI,GAClE,2BAA2B,CAK7B"}
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/core/read.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAQjB,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,SAAS,EACT,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,IAAI,EACT,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAEL,cAAc,EAKf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,SAAS,EACT,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,UAAU,CAAC;AAIlB,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI;IACtC,QAAQ,CAAC,kBAAkB,EAAE,cAAc,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;CAC/B,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,cAAc,SAAS,qBAAqB,EAE5C,WAAW,EAAE,mBAAmB,EAChC,iBAAiB,EAAE,iBAAiB,CAAC,cAAc,EAAE,OAAO,CAAC,EAC7D,qBAAqB,EAAE,2BAA2B,GACjD,sBAAsB,CAAC,cAAc,CAAC,CAiExC;AAED,MAAM,MAAM,qBAAqB,CAAC,IAAI,IAAI;IACxC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,cAAc,CAAC,IAAI,IAC3B,qBAAqB,CAAC,IAAI,CAAC,GAC3B;IACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IAChD,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;CAC3B,CAAC;AA6dN,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,iBAAiB,EACxB,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,GACnB,cAAc,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,aAAa,EAAE,GAAG,IAAI,CAAC,CAa3E;AAED,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,mBAAmB,EAChC,KAAK,EAAE,iBAAiB,EACxB,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,EAEzC,QAAQ,EAAE,CAAC,cAAc,EACvB,GAAG,EAAE,SAAS,CAAC,cAAc,CAAC,EAC9B,IAAI,EAAE,IAAI,KACP,cAAc,CAAC,MAAM,CAAC,GAC1B,cAAc,CAAC,OAAO,CAAC,CA6JzB;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,wBAAgB,oCAAoC,CAClD,qBAAqB,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAAG,IAAI,GAClE,2BAA2B,CAK7B"}
package/dist/core/read.js CHANGED
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.readButDoNotEvaluate = readButDoNotEvaluate;
4
+ exports.readScalarFieldData = readScalarFieldData;
5
+ exports.readLinkedFieldData = readLinkedFieldData;
4
6
  exports.getNetworkRequestOptionsWithDefaults = getNetworkRequestOptionsWithDefaults;
5
7
  const cache_1 = require("./cache");
6
8
  const componentCache_1 = require("./componentCache");
@@ -56,7 +58,7 @@ function readButDoNotEvaluate(environment, fragmentReference, networkRequestOpti
56
58
  }
57
59
  }
58
60
  function readData(environment, ast, root, variables, nestedRefetchQueries, networkRequest, networkRequestOptions, mutableEncounteredRecords) {
59
- var _a, _b, _c, _d, _e;
61
+ var _a, _b, _c;
60
62
  const encounteredIds = (0, cache_1.insertIfNotExists)(mutableEncounteredRecords, root.__typename);
61
63
  encounteredIds.add(root.__link);
62
64
  let storeRecord = (_a = environment.store[root.__typename]) === null || _a === void 0 ? void 0 : _a[root.__link];
@@ -71,25 +73,17 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
71
73
  return {
72
74
  kind: 'Success',
73
75
  data: null,
74
- encounteredRecords: mutableEncounteredRecords,
75
76
  };
76
77
  }
77
78
  let target = {};
78
79
  for (const field of ast) {
79
80
  switch (field.kind) {
80
81
  case 'Scalar': {
81
- const storeRecordName = (0, cache_1.getParentRecordKey)(field, variables);
82
- const value = storeRecord[storeRecordName];
83
- // TODO consider making scalars into discriminated unions. This probably has
84
- // to happen for when we handle errors.
85
- if (value === undefined) {
86
- return {
87
- kind: 'MissingData',
88
- reason: 'No value for ' + storeRecordName + ' on root ' + root.__link,
89
- recordLink: root,
90
- };
82
+ const data = readScalarFieldData(field, storeRecord, root, variables);
83
+ if (data.kind === 'MissingData') {
84
+ return data;
91
85
  }
92
- target[(_b = field.alias) !== null && _b !== void 0 ? _b : field.fieldName] = value;
86
+ target[(_b = field.alias) !== null && _b !== void 0 ? _b : field.fieldName] = data.data;
93
87
  break;
94
88
  }
95
89
  case 'Link': {
@@ -97,138 +91,11 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
97
91
  break;
98
92
  }
99
93
  case 'Linked': {
100
- const storeRecordName = (0, cache_1.getParentRecordKey)(field, variables);
101
- const value = storeRecord[storeRecordName];
102
- if (Array.isArray(value)) {
103
- const results = [];
104
- for (const item of value) {
105
- const link = (0, IsographEnvironment_1.assertLink)(item);
106
- if (link === undefined) {
107
- return {
108
- kind: 'MissingData',
109
- reason: 'No link for ' +
110
- storeRecordName +
111
- ' on root ' +
112
- root.__link +
113
- '. Link is ' +
114
- JSON.stringify(item),
115
- recordLink: root,
116
- };
117
- }
118
- else if (link === null) {
119
- results.push(null);
120
- continue;
121
- }
122
- const result = readData(environment, field.selections, link, variables, nestedRefetchQueries, networkRequest, networkRequestOptions, mutableEncounteredRecords);
123
- if (result.kind === 'MissingData') {
124
- return {
125
- kind: 'MissingData',
126
- reason: 'Missing data for ' +
127
- storeRecordName +
128
- ' on root ' +
129
- root.__link +
130
- '. Link is ' +
131
- JSON.stringify(item),
132
- nestedReason: result,
133
- recordLink: result.recordLink,
134
- };
135
- }
136
- results.push(result.data);
137
- }
138
- target[(_c = field.alias) !== null && _c !== void 0 ? _c : field.fieldName] = results;
139
- break;
140
- }
141
- let link = (0, IsographEnvironment_1.assertLink)(value);
142
- if (field.condition) {
143
- const data = readData(environment, field.condition.readerAst, root, variables, nestedRefetchQueries, networkRequest, networkRequestOptions, mutableEncounteredRecords);
144
- if (data.kind === 'MissingData') {
145
- return {
146
- kind: 'MissingData',
147
- reason: 'Missing data for ' +
148
- storeRecordName +
149
- ' on root ' +
150
- root.__link,
151
- nestedReason: data,
152
- recordLink: data.recordLink,
153
- };
154
- }
155
- const readerWithRefetchQueries = {
156
- kind: 'ReaderWithRefetchQueries',
157
- readerArtifact: field.condition,
158
- // TODO this is wrong
159
- // should map field.condition.usedRefetchQueries
160
- // but it doesn't exist
161
- nestedRefetchQueries: [],
162
- };
163
- const fragment = {
164
- kind: 'FragmentReference',
165
- readerWithRefetchQueries: (0, PromiseWrapper_1.wrapResolvedValue)(readerWithRefetchQueries),
166
- root,
167
- variables: generateChildVariableMap(variables,
168
- // TODO this is wrong
169
- // should use field.condition.variables
170
- // but it doesn't exist
171
- []),
172
- networkRequest,
173
- };
174
- const condition = field.condition.resolver(Object.assign({ data: data.data, parameters: {} }, (field.condition.hasUpdatable
175
- ? {
176
- startUpdate: (0, startUpdate_1.getOrCreateCachedStartUpdate)(environment, fragment, readerWithRefetchQueries.readerArtifact.fieldName),
177
- }
178
- : undefined)));
179
- if (condition === true) {
180
- link = root;
181
- }
182
- else if (condition === false) {
183
- link = null;
184
- }
185
- else {
186
- link = condition;
187
- }
188
- }
189
- if (link === undefined) {
190
- // TODO make this configurable, and also generated and derived from the schema
191
- const missingFieldHandler = environment.missingFieldHandler;
192
- const altLink = missingFieldHandler === null || missingFieldHandler === void 0 ? void 0 : missingFieldHandler(storeRecord, root, field.fieldName, field.arguments, variables);
193
- (0, logging_1.logMessage)(environment, {
194
- kind: 'MissingFieldHandlerCalled',
195
- root,
196
- storeRecord,
197
- fieldName: field.fieldName,
198
- arguments: field.arguments,
199
- variables,
200
- });
201
- if (altLink === undefined) {
202
- return {
203
- kind: 'MissingData',
204
- reason: 'No link for ' +
205
- storeRecordName +
206
- ' on root ' +
207
- root.__link +
208
- '. Link is ' +
209
- JSON.stringify(value),
210
- recordLink: root,
211
- };
212
- }
213
- else {
214
- link = altLink;
215
- }
216
- }
217
- else if (link === null) {
218
- target[(_d = field.alias) !== null && _d !== void 0 ? _d : field.fieldName] = null;
219
- break;
220
- }
221
- const targetId = link;
222
- const data = readData(environment, field.selections, targetId, variables, nestedRefetchQueries, networkRequest, networkRequestOptions, mutableEncounteredRecords);
94
+ const data = readLinkedFieldData(environment, field, storeRecord, root, variables, networkRequest, (ast, root) => readData(environment, ast, root, variables, nestedRefetchQueries, networkRequest, networkRequestOptions, mutableEncounteredRecords));
223
95
  if (data.kind === 'MissingData') {
224
- return {
225
- kind: 'MissingData',
226
- reason: 'Missing data for ' + storeRecordName + ' on root ' + root.__link,
227
- nestedReason: data,
228
- recordLink: data.recordLink,
229
- };
96
+ return data;
230
97
  }
231
- target[(_e = field.alias) !== null && _e !== void 0 ? _e : field.fieldName] = data.data;
98
+ target[(_c = field.alias) !== null && _c !== void 0 ? _c : field.fieldName] = data.data;
232
99
  break;
233
100
  }
234
101
  case 'ImperativelyLoadedField': {
@@ -436,7 +303,6 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
436
303
  return {
437
304
  kind: 'Success',
438
305
  data: target,
439
- encounteredRecords: mutableEncounteredRecords,
440
306
  };
441
307
  }
442
308
  function filterVariables(variables, allowedVariables) {
@@ -504,6 +370,155 @@ function writeQueryArgsToVariables(targetVariables, queryArgs, variables) {
504
370
  }
505
371
  }
506
372
  }
373
+ function readScalarFieldData(field, storeRecord, root, variables) {
374
+ const storeRecordName = (0, cache_1.getParentRecordKey)(field, variables);
375
+ const value = storeRecord[storeRecordName];
376
+ // TODO consider making scalars into discriminated unions. This probably has
377
+ // to happen for when we handle errors.
378
+ if (value === undefined) {
379
+ return {
380
+ kind: 'MissingData',
381
+ reason: 'No value for ' + storeRecordName + ' on root ' + root.__link,
382
+ recordLink: root,
383
+ };
384
+ }
385
+ return { kind: 'Success', data: value };
386
+ }
387
+ function readLinkedFieldData(environment, field, storeRecord, root, variables, networkRequest, readData) {
388
+ const storeRecordName = (0, cache_1.getParentRecordKey)(field, variables);
389
+ const value = storeRecord[storeRecordName];
390
+ if (Array.isArray(value)) {
391
+ const results = [];
392
+ for (const item of value) {
393
+ const link = (0, IsographEnvironment_1.assertLink)(item);
394
+ if (link === undefined) {
395
+ return {
396
+ kind: 'MissingData',
397
+ reason: 'No link for ' +
398
+ storeRecordName +
399
+ ' on root ' +
400
+ root.__link +
401
+ '. Link is ' +
402
+ JSON.stringify(item),
403
+ recordLink: root,
404
+ };
405
+ }
406
+ else if (link === null) {
407
+ results.push(null);
408
+ continue;
409
+ }
410
+ const result = readData(field.selections, link);
411
+ if (result.kind === 'MissingData') {
412
+ return {
413
+ kind: 'MissingData',
414
+ reason: 'Missing data for ' +
415
+ storeRecordName +
416
+ ' on root ' +
417
+ root.__link +
418
+ '. Link is ' +
419
+ JSON.stringify(item),
420
+ nestedReason: result,
421
+ recordLink: result.recordLink,
422
+ };
423
+ }
424
+ results.push(result.data);
425
+ }
426
+ return {
427
+ kind: 'Success',
428
+ data: results,
429
+ };
430
+ }
431
+ let link = (0, IsographEnvironment_1.assertLink)(value);
432
+ if (field.condition) {
433
+ const data = readData(field.condition.readerAst, root);
434
+ if (data.kind === 'MissingData') {
435
+ return {
436
+ kind: 'MissingData',
437
+ reason: 'Missing data for ' + storeRecordName + ' on root ' + root.__link,
438
+ nestedReason: data,
439
+ recordLink: data.recordLink,
440
+ };
441
+ }
442
+ const readerWithRefetchQueries = {
443
+ kind: 'ReaderWithRefetchQueries',
444
+ readerArtifact: field.condition,
445
+ // TODO this is wrong
446
+ // should map field.condition.usedRefetchQueries
447
+ // but it doesn't exist
448
+ nestedRefetchQueries: [],
449
+ };
450
+ const fragment = {
451
+ kind: 'FragmentReference',
452
+ readerWithRefetchQueries: (0, PromiseWrapper_1.wrapResolvedValue)(readerWithRefetchQueries),
453
+ root,
454
+ variables: generateChildVariableMap(variables,
455
+ // TODO this is wrong
456
+ // should use field.condition.variables
457
+ // but it doesn't exist
458
+ []),
459
+ networkRequest,
460
+ };
461
+ const condition = field.condition.resolver(Object.assign({ data: data.data, parameters: {} }, (field.condition.hasUpdatable
462
+ ? {
463
+ startUpdate: (0, startUpdate_1.getOrCreateCachedStartUpdate)(environment, fragment, readerWithRefetchQueries.readerArtifact.fieldName),
464
+ }
465
+ : undefined)));
466
+ if (condition === true) {
467
+ link = root;
468
+ }
469
+ else if (condition === false) {
470
+ link = null;
471
+ }
472
+ else {
473
+ link = condition;
474
+ }
475
+ }
476
+ if (link === undefined) {
477
+ // TODO make this configurable, and also generated and derived from the schema
478
+ const missingFieldHandler = environment.missingFieldHandler;
479
+ const altLink = missingFieldHandler === null || missingFieldHandler === void 0 ? void 0 : missingFieldHandler(storeRecord, root, field.fieldName, field.arguments, variables);
480
+ (0, logging_1.logMessage)(environment, {
481
+ kind: 'MissingFieldHandlerCalled',
482
+ root,
483
+ storeRecord,
484
+ fieldName: field.fieldName,
485
+ arguments: field.arguments,
486
+ variables,
487
+ });
488
+ if (altLink === undefined) {
489
+ return {
490
+ kind: 'MissingData',
491
+ reason: 'No link for ' +
492
+ storeRecordName +
493
+ ' on root ' +
494
+ root.__link +
495
+ '. Link is ' +
496
+ JSON.stringify(value),
497
+ recordLink: root,
498
+ };
499
+ }
500
+ else {
501
+ link = altLink;
502
+ }
503
+ }
504
+ else if (link === null) {
505
+ return {
506
+ kind: 'Success',
507
+ data: null,
508
+ };
509
+ }
510
+ const targetId = link;
511
+ const data = readData(field.selections, targetId);
512
+ if (data.kind === 'MissingData') {
513
+ return {
514
+ kind: 'MissingData',
515
+ reason: 'Missing data for ' + storeRecordName + ' on root ' + root.__link,
516
+ nestedReason: data,
517
+ recordLink: data.recordLink,
518
+ };
519
+ }
520
+ return data;
521
+ }
507
522
  function getNetworkRequestOptionsWithDefaults(networkRequestOptions) {
508
523
  var _a, _b;
509
524
  return {
@@ -50,6 +50,7 @@ export type ReaderLinkedField = {
50
50
  parameters: any;
51
51
  startUpdate?: StartUpdate<object>;
52
52
  }, boolean | Link | null> | null;
53
+ readonly isUpdatable: boolean;
53
54
  };
54
55
  export type ReaderNonLoadableResolverField = {
55
56
  readonly kind: 'Resolver';
@@ -1 +1 @@
1
- {"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/core/reader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/core/reader.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isograph/react",
3
- "version": "0.0.0-main-7e562882",
3
+ "version": "0.0.0-main-8821fa52",
4
4
  "description": "Use Isograph with React",
5
5
  "homepage": "https://isograph.dev",
6
6
  "main": "dist/index.js",
@@ -20,9 +20,9 @@
20
20
  "iso-watch": "cross-env ../../target/debug/isograph_cli --config ./isograph.config.json --watch"
21
21
  },
22
22
  "dependencies": {
23
- "@isograph/disposable-types": "0.0.0-main-7e562882",
24
- "@isograph/react-disposable-state": "0.0.0-main-7e562882",
25
- "@isograph/reference-counted-pointer": "0.0.0-main-7e562882"
23
+ "@isograph/disposable-types": "0.0.0-main-8821fa52",
24
+ "@isograph/react-disposable-state": "0.0.0-main-8821fa52",
25
+ "@isograph/reference-counted-pointer": "0.0.0-main-8821fa52"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "react": "^18.0.0 || ^19.0.0"
package/src/core/read.ts CHANGED
@@ -14,7 +14,6 @@ import {
14
14
  } from './entrypoint';
15
15
  import {
16
16
  ExtractData,
17
- ExtractParameters,
18
17
  FragmentReference,
19
18
  Variables,
20
19
  type UnknownTReadFromStore,
@@ -23,7 +22,9 @@ import {
23
22
  assertLink,
24
23
  getOrLoadIsographArtifact,
25
24
  IsographEnvironment,
25
+ type DataTypeValue,
26
26
  type Link,
27
+ type StoreRecord,
27
28
  } from './IsographEnvironment';
28
29
  import { logMessage } from './logging';
29
30
  import { maybeMakeNetworkRequest } from './makeNetworkRequest';
@@ -35,7 +36,11 @@ import {
35
36
  wrapPromise,
36
37
  wrapResolvedValue,
37
38
  } from './PromiseWrapper';
38
- import { ReaderAst } from './reader';
39
+ import {
40
+ ReaderAst,
41
+ type ReaderLinkedField,
42
+ type ReaderScalarField,
43
+ } from './reader';
39
44
  import { getOrCreateCachedStartUpdate } from './startUpdate';
40
45
  import { Arguments } from './util';
41
46
 
@@ -117,12 +122,13 @@ export function readButDoNotEvaluate<
117
122
  }
118
123
  }
119
124
 
120
- export type ReadDataResult<TReadFromStore> =
121
- | {
122
- readonly kind: 'Success';
123
- readonly data: ExtractData<TReadFromStore>;
124
- readonly encounteredRecords: EncounteredIds;
125
- }
125
+ export type ReadDataResultSuccess<Data> = {
126
+ readonly kind: 'Success';
127
+ readonly data: Data;
128
+ };
129
+
130
+ export type ReadDataResult<Data> =
131
+ | ReadDataResultSuccess<Data>
126
132
  | {
127
133
  readonly kind: 'MissingData';
128
134
  readonly reason: string;
@@ -134,12 +140,12 @@ function readData<TReadFromStore>(
134
140
  environment: IsographEnvironment,
135
141
  ast: ReaderAst<TReadFromStore>,
136
142
  root: Link,
137
- variables: ExtractParameters<TReadFromStore>,
143
+ variables: Variables,
138
144
  nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
139
145
  networkRequest: PromiseWrapper<void, any>,
140
146
  networkRequestOptions: NetworkRequestReaderOptions,
141
147
  mutableEncounteredRecords: EncounteredIds,
142
- ): ReadDataResult<TReadFromStore> {
148
+ ): ReadDataResult<ExtractData<TReadFromStore>> {
143
149
  const encounteredIds = insertIfNotExists(
144
150
  mutableEncounteredRecords,
145
151
  root.__typename,
@@ -158,7 +164,6 @@ function readData<TReadFromStore>(
158
164
  return {
159
165
  kind: 'Success',
160
166
  data: null as any,
161
- encounteredRecords: mutableEncounteredRecords,
162
167
  };
163
168
  }
164
169
 
@@ -167,19 +172,12 @@ function readData<TReadFromStore>(
167
172
  for (const field of ast) {
168
173
  switch (field.kind) {
169
174
  case 'Scalar': {
170
- const storeRecordName = getParentRecordKey(field, variables);
171
- const value = storeRecord[storeRecordName];
172
- // TODO consider making scalars into discriminated unions. This probably has
173
- // to happen for when we handle errors.
174
- if (value === undefined) {
175
- return {
176
- kind: 'MissingData',
177
- reason:
178
- 'No value for ' + storeRecordName + ' on root ' + root.__link,
179
- recordLink: root,
180
- };
175
+ const data = readScalarFieldData(field, storeRecord, root, variables);
176
+
177
+ if (data.kind === 'MissingData') {
178
+ return data;
181
179
  }
182
- target[field.alias ?? field.fieldName] = value;
180
+ target[field.alias ?? field.fieldName] = data.data;
183
181
  break;
184
182
  }
185
183
  case 'Link': {
@@ -187,189 +185,27 @@ function readData<TReadFromStore>(
187
185
  break;
188
186
  }
189
187
  case 'Linked': {
190
- const storeRecordName = getParentRecordKey(field, variables);
191
- const value = storeRecord[storeRecordName];
192
- if (Array.isArray(value)) {
193
- const results = [];
194
- for (const item of value) {
195
- const link = assertLink(item);
196
- if (link === undefined) {
197
- return {
198
- kind: 'MissingData',
199
- reason:
200
- 'No link for ' +
201
- storeRecordName +
202
- ' on root ' +
203
- root.__link +
204
- '. Link is ' +
205
- JSON.stringify(item),
206
- recordLink: root,
207
- };
208
- } else if (link === null) {
209
- results.push(null);
210
- continue;
211
- }
212
-
213
- const result = readData(
188
+ const data = readLinkedFieldData(
189
+ environment,
190
+ field,
191
+ storeRecord,
192
+ root,
193
+ variables,
194
+ networkRequest,
195
+ (ast, root) =>
196
+ readData(
214
197
  environment,
215
- field.selections,
216
- link,
198
+ ast,
199
+ root,
217
200
  variables,
218
201
  nestedRefetchQueries,
219
202
  networkRequest,
220
203
  networkRequestOptions,
221
204
  mutableEncounteredRecords,
222
- );
223
- if (result.kind === 'MissingData') {
224
- return {
225
- kind: 'MissingData',
226
- reason:
227
- 'Missing data for ' +
228
- storeRecordName +
229
- ' on root ' +
230
- root.__link +
231
- '. Link is ' +
232
- JSON.stringify(item),
233
- nestedReason: result,
234
- recordLink: result.recordLink,
235
- };
236
- }
237
- results.push(result.data);
238
- }
239
- target[field.alias ?? field.fieldName] = results;
240
- break;
241
- }
242
- let link = assertLink(value);
243
-
244
- if (field.condition) {
245
- const data = readData(
246
- environment,
247
- field.condition.readerAst,
248
- root,
249
- variables,
250
- nestedRefetchQueries,
251
- networkRequest,
252
- networkRequestOptions,
253
- mutableEncounteredRecords,
254
- );
255
- if (data.kind === 'MissingData') {
256
- return {
257
- kind: 'MissingData',
258
- reason:
259
- 'Missing data for ' +
260
- storeRecordName +
261
- ' on root ' +
262
- root.__link,
263
- nestedReason: data,
264
- recordLink: data.recordLink,
265
- };
266
- }
267
-
268
- const readerWithRefetchQueries = {
269
- kind: 'ReaderWithRefetchQueries',
270
- readerArtifact: field.condition,
271
- // TODO this is wrong
272
- // should map field.condition.usedRefetchQueries
273
- // but it doesn't exist
274
- nestedRefetchQueries: [],
275
- } satisfies ReaderWithRefetchQueries<any, any>;
276
-
277
- const fragment = {
278
- kind: 'FragmentReference',
279
- readerWithRefetchQueries: wrapResolvedValue(
280
- readerWithRefetchQueries,
281
- ),
282
- root,
283
- variables: generateChildVariableMap(
284
- variables,
285
- // TODO this is wrong
286
- // should use field.condition.variables
287
- // but it doesn't exist
288
- [],
289
205
  ),
290
- networkRequest,
291
- } satisfies FragmentReference<any, any>;
292
-
293
- const condition = field.condition.resolver({
294
- data: data.data,
295
- parameters: {},
296
- ...(field.condition.hasUpdatable
297
- ? {
298
- startUpdate: getOrCreateCachedStartUpdate(
299
- environment,
300
- fragment,
301
- readerWithRefetchQueries.readerArtifact.fieldName,
302
- ),
303
- }
304
- : undefined),
305
- });
306
- if (condition === true) {
307
- link = root;
308
- } else if (condition === false) {
309
- link = null;
310
- } else {
311
- link = condition;
312
- }
313
- }
314
-
315
- if (link === undefined) {
316
- // TODO make this configurable, and also generated and derived from the schema
317
- const missingFieldHandler = environment.missingFieldHandler;
318
-
319
- const altLink = missingFieldHandler?.(
320
- storeRecord,
321
- root,
322
- field.fieldName,
323
- field.arguments,
324
- variables,
325
- );
326
- logMessage(environment, {
327
- kind: 'MissingFieldHandlerCalled',
328
- root,
329
- storeRecord,
330
- fieldName: field.fieldName,
331
- arguments: field.arguments,
332
- variables,
333
- });
334
-
335
- if (altLink === undefined) {
336
- return {
337
- kind: 'MissingData',
338
- reason:
339
- 'No link for ' +
340
- storeRecordName +
341
- ' on root ' +
342
- root.__link +
343
- '. Link is ' +
344
- JSON.stringify(value),
345
- recordLink: root,
346
- };
347
- } else {
348
- link = altLink;
349
- }
350
- } else if (link === null) {
351
- target[field.alias ?? field.fieldName] = null;
352
- break;
353
- }
354
- const targetId = link;
355
- const data = readData(
356
- environment,
357
- field.selections,
358
- targetId,
359
- variables,
360
- nestedRefetchQueries,
361
- networkRequest,
362
- networkRequestOptions,
363
- mutableEncounteredRecords,
364
206
  );
365
207
  if (data.kind === 'MissingData') {
366
- return {
367
- kind: 'MissingData',
368
- reason:
369
- 'Missing data for ' + storeRecordName + ' on root ' + root.__link,
370
- nestedReason: data,
371
- recordLink: data.recordLink,
372
- };
208
+ return data;
373
209
  }
374
210
  target[field.alias ?? field.fieldName] = data.data;
375
211
  break;
@@ -690,7 +526,6 @@ function readData<TReadFromStore>(
690
526
  return {
691
527
  kind: 'Success',
692
528
  data: target as any,
693
- encounteredRecords: mutableEncounteredRecords,
694
529
  };
695
530
  }
696
531
 
@@ -776,6 +611,197 @@ function writeQueryArgsToVariables(
776
611
  }
777
612
  }
778
613
 
614
+ export function readScalarFieldData(
615
+ field: ReaderScalarField,
616
+ storeRecord: StoreRecord,
617
+ root: Link,
618
+ variables: Variables,
619
+ ): ReadDataResult<string | number | boolean | Link | DataTypeValue[] | null> {
620
+ const storeRecordName = getParentRecordKey(field, variables);
621
+ const value = storeRecord[storeRecordName];
622
+ // TODO consider making scalars into discriminated unions. This probably has
623
+ // to happen for when we handle errors.
624
+ if (value === undefined) {
625
+ return {
626
+ kind: 'MissingData',
627
+ reason: 'No value for ' + storeRecordName + ' on root ' + root.__link,
628
+ recordLink: root,
629
+ };
630
+ }
631
+ return { kind: 'Success', data: value };
632
+ }
633
+
634
+ export function readLinkedFieldData(
635
+ environment: IsographEnvironment,
636
+ field: ReaderLinkedField,
637
+ storeRecord: StoreRecord,
638
+ root: Link,
639
+ variables: Variables,
640
+ networkRequest: PromiseWrapper<void, any>,
641
+
642
+ readData: <TReadFromStore>(
643
+ ast: ReaderAst<TReadFromStore>,
644
+ root: Link,
645
+ ) => ReadDataResult<object>,
646
+ ): ReadDataResult<unknown> {
647
+ const storeRecordName = getParentRecordKey(field, variables);
648
+ const value = storeRecord[storeRecordName];
649
+ if (Array.isArray(value)) {
650
+ const results = [];
651
+ for (const item of value) {
652
+ const link = assertLink(item);
653
+ if (link === undefined) {
654
+ return {
655
+ kind: 'MissingData',
656
+ reason:
657
+ 'No link for ' +
658
+ storeRecordName +
659
+ ' on root ' +
660
+ root.__link +
661
+ '. Link is ' +
662
+ JSON.stringify(item),
663
+ recordLink: root,
664
+ };
665
+ } else if (link === null) {
666
+ results.push(null);
667
+ continue;
668
+ }
669
+
670
+ const result = readData(field.selections, link);
671
+ if (result.kind === 'MissingData') {
672
+ return {
673
+ kind: 'MissingData',
674
+ reason:
675
+ 'Missing data for ' +
676
+ storeRecordName +
677
+ ' on root ' +
678
+ root.__link +
679
+ '. Link is ' +
680
+ JSON.stringify(item),
681
+ nestedReason: result,
682
+ recordLink: result.recordLink,
683
+ };
684
+ }
685
+ results.push(result.data);
686
+ }
687
+ return {
688
+ kind: 'Success',
689
+ data: results,
690
+ };
691
+ }
692
+ let link = assertLink(value);
693
+
694
+ if (field.condition) {
695
+ const data = readData(field.condition.readerAst, root);
696
+ if (data.kind === 'MissingData') {
697
+ return {
698
+ kind: 'MissingData',
699
+ reason:
700
+ 'Missing data for ' + storeRecordName + ' on root ' + root.__link,
701
+ nestedReason: data,
702
+ recordLink: data.recordLink,
703
+ };
704
+ }
705
+
706
+ const readerWithRefetchQueries = {
707
+ kind: 'ReaderWithRefetchQueries',
708
+ readerArtifact: field.condition,
709
+ // TODO this is wrong
710
+ // should map field.condition.usedRefetchQueries
711
+ // but it doesn't exist
712
+ nestedRefetchQueries: [],
713
+ } satisfies ReaderWithRefetchQueries<any, any>;
714
+
715
+ const fragment = {
716
+ kind: 'FragmentReference',
717
+ readerWithRefetchQueries: wrapResolvedValue(readerWithRefetchQueries),
718
+ root,
719
+ variables: generateChildVariableMap(
720
+ variables,
721
+ // TODO this is wrong
722
+ // should use field.condition.variables
723
+ // but it doesn't exist
724
+ [],
725
+ ),
726
+ networkRequest,
727
+ } satisfies FragmentReference<any, any>;
728
+
729
+ const condition = field.condition.resolver({
730
+ data: data.data,
731
+ parameters: {},
732
+ ...(field.condition.hasUpdatable
733
+ ? {
734
+ startUpdate: getOrCreateCachedStartUpdate(
735
+ environment,
736
+ fragment,
737
+ readerWithRefetchQueries.readerArtifact.fieldName,
738
+ ),
739
+ }
740
+ : undefined),
741
+ });
742
+ if (condition === true) {
743
+ link = root;
744
+ } else if (condition === false) {
745
+ link = null;
746
+ } else {
747
+ link = condition;
748
+ }
749
+ }
750
+
751
+ if (link === undefined) {
752
+ // TODO make this configurable, and also generated and derived from the schema
753
+ const missingFieldHandler = environment.missingFieldHandler;
754
+
755
+ const altLink = missingFieldHandler?.(
756
+ storeRecord,
757
+ root,
758
+ field.fieldName,
759
+ field.arguments,
760
+ variables,
761
+ );
762
+ logMessage(environment, {
763
+ kind: 'MissingFieldHandlerCalled',
764
+ root,
765
+ storeRecord,
766
+ fieldName: field.fieldName,
767
+ arguments: field.arguments,
768
+ variables,
769
+ });
770
+
771
+ if (altLink === undefined) {
772
+ return {
773
+ kind: 'MissingData',
774
+ reason:
775
+ 'No link for ' +
776
+ storeRecordName +
777
+ ' on root ' +
778
+ root.__link +
779
+ '. Link is ' +
780
+ JSON.stringify(value),
781
+ recordLink: root,
782
+ };
783
+ } else {
784
+ link = altLink;
785
+ }
786
+ } else if (link === null) {
787
+ return {
788
+ kind: 'Success',
789
+ data: null,
790
+ };
791
+ }
792
+ const targetId = link;
793
+ const data = readData(field.selections, targetId);
794
+ if (data.kind === 'MissingData') {
795
+ return {
796
+ kind: 'MissingData',
797
+ reason: 'Missing data for ' + storeRecordName + ' on root ' + root.__link,
798
+ nestedReason: data,
799
+ recordLink: data.recordLink,
800
+ };
801
+ }
802
+ return data;
803
+ }
804
+
779
805
  export type NetworkRequestReaderOptions = {
780
806
  suspendIfInFlight: boolean;
781
807
  throwOnNetworkError: boolean;
@@ -112,6 +112,7 @@ export type ReaderLinkedField = {
112
112
  { data: object; parameters: any; startUpdate?: StartUpdate<object> },
113
113
  boolean | Link | null
114
114
  > | null;
115
+ readonly isUpdatable: boolean;
115
116
  };
116
117
 
117
118
  export type ReaderNonLoadableResolverField = {
@@ -10,6 +10,7 @@ const readerAst: ReaderAst<Query__meName__param> = [
10
10
  alias: null,
11
11
  arguments: null,
12
12
  condition: null,
13
+ isUpdatable: false,
13
14
  selections: [
14
15
  {
15
16
  kind: "Scalar",
@@ -10,6 +10,7 @@ const readerAst: ReaderAst<Query__meNameSuccessor__param> = [
10
10
  alias: null,
11
11
  arguments: null,
12
12
  condition: null,
13
+ isUpdatable: false,
13
14
  selections: [
14
15
  {
15
16
  kind: "Scalar",
@@ -24,6 +25,7 @@ const readerAst: ReaderAst<Query__meNameSuccessor__param> = [
24
25
  alias: null,
25
26
  arguments: null,
26
27
  condition: null,
28
+ isUpdatable: false,
27
29
  selections: [
28
30
  {
29
31
  kind: "Linked",
@@ -31,6 +33,7 @@ const readerAst: ReaderAst<Query__meNameSuccessor__param> = [
31
33
  alias: null,
32
34
  arguments: null,
33
35
  condition: null,
36
+ isUpdatable: false,
34
37
  selections: [
35
38
  {
36
39
  kind: "Scalar",
@@ -15,6 +15,7 @@ const readerAst: ReaderAst<Query__nodeField__param> = [
15
15
  ],
16
16
  ],
17
17
  condition: null,
18
+ isUpdatable: false,
18
19
  selections: [
19
20
  {
20
21
  kind: "Scalar",
@@ -10,6 +10,7 @@ const readerAst: ReaderAst<Query__subquery__param> = [
10
10
  alias: null,
11
11
  arguments: null,
12
12
  condition: null,
13
+ isUpdatable: false,
13
14
  selections: [
14
15
  {
15
16
  kind: "Linked",
@@ -22,6 +23,7 @@ const readerAst: ReaderAst<Query__subquery__param> = [
22
23
  ],
23
24
  ],
24
25
  condition: null,
26
+ isUpdatable: false,
25
27
  selections: [
26
28
  {
27
29
  kind: "Scalar",