@isograph/react 0.0.0-main-dc9ca2f6 → 0.0.0-main-1bfd646b

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,8 +1,6 @@
1
- import { ReactNode } from 'react';
2
- import * as React from 'react';
1
+ /// <reference types="react" />
3
2
  import { ParentCache } from '@isograph/isograph-react-disposable-state';
4
- import { NormalizationAst } from './index';
5
- export declare const IsographEnvironmentContext: React.Context<IsographEnvironment | null>;
3
+ import { RetainedQuery } from './garbageCollection';
6
4
  type ComponentName = string;
7
5
  type StringifiedArgs = string;
8
6
  type ComponentCache = {
@@ -16,10 +14,6 @@ export type Subscriptions = Set<() => void>;
16
14
  type SuspenseCache = {
17
15
  [index: string]: ParentCache<any>;
18
16
  };
19
- export type RetainedQuery = {
20
- normalizationAst: NormalizationAst;
21
- variables: {};
22
- };
23
17
  export type IsographEnvironment = {
24
18
  store: IsographStore;
25
19
  networkFunction: IsographNetworkFunction;
@@ -51,18 +45,8 @@ export type IsographStore = {
51
45
  [index: DataId]: StoreRecord | null;
52
46
  __ROOT: StoreRecord;
53
47
  };
54
- export type IsographEnvironmentProviderProps = {
55
- environment: IsographEnvironment;
56
- children: ReactNode;
57
- };
58
- export declare function IsographEnvironmentProvider({ environment, children, }: IsographEnvironmentProviderProps): React.JSX.Element;
59
- export declare function useIsographEnvironment(): IsographEnvironment;
60
48
  export declare function createIsographEnvironment(store: IsographStore, networkFunction: IsographNetworkFunction, missingFieldHandler?: MissingFieldHandler): IsographEnvironment;
61
49
  export declare function createIsographStore(): {
62
50
  __ROOT: {};
63
51
  };
64
- export declare function garbageCollectEnvironment(environment: IsographEnvironment): void;
65
- type DidUnretainSomeQuery = boolean;
66
- export declare function unretainQuery(environment: IsographEnvironment, retainedQuery: RetainedQuery): DidUnretainSomeQuery;
67
- export declare function retainQuery(environment: IsographEnvironment, queryToRetain: RetainedQuery): void;
68
52
  export {};
@@ -1,47 +1,7 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.retainQuery = exports.unretainQuery = exports.garbageCollectEnvironment = exports.createIsographStore = exports.createIsographEnvironment = exports.useIsographEnvironment = exports.IsographEnvironmentProvider = exports.ROOT_ID = exports.IsographEnvironmentContext = void 0;
27
- const react_1 = require("react");
28
- const React = __importStar(require("react"));
29
- const cache_1 = require("./cache");
30
- exports.IsographEnvironmentContext = (0, react_1.createContext)(null);
3
+ exports.createIsographStore = exports.createIsographEnvironment = exports.ROOT_ID = void 0;
31
4
  exports.ROOT_ID = '__ROOT';
32
- function IsographEnvironmentProvider({ environment, children, }) {
33
- return (React.createElement(exports.IsographEnvironmentContext.Provider, { value: environment }, children));
34
- }
35
- exports.IsographEnvironmentProvider = IsographEnvironmentProvider;
36
- function useIsographEnvironment() {
37
- const context = (0, react_1.useContext)(exports.IsographEnvironmentContext);
38
- if (context == null) {
39
- throw new Error('Unexpected null environment context. Make sure to render ' +
40
- 'this component within an IsographEnvironmentProvider component');
41
- }
42
- return context;
43
- }
44
- exports.useIsographEnvironment = useIsographEnvironment;
45
5
  const DEFAULT_GC_BUFFER_SIZE = 10;
46
6
  function createIsographEnvironment(store, networkFunction, missingFieldHandler) {
47
7
  return {
@@ -63,82 +23,3 @@ function createIsographStore() {
63
23
  };
64
24
  }
65
25
  exports.createIsographStore = createIsographStore;
66
- function garbageCollectEnvironment(environment) {
67
- const retainedIds = new Set([exports.ROOT_ID]);
68
- for (const query of environment.retainedQueries) {
69
- recordReachableIds(environment.store, query, retainedIds);
70
- }
71
- for (const query of environment.gcBuffer) {
72
- recordReachableIds(environment.store, query, retainedIds);
73
- }
74
- for (const dataId in environment.store) {
75
- if (!retainedIds.has(dataId)) {
76
- delete environment.store[dataId];
77
- }
78
- }
79
- }
80
- exports.garbageCollectEnvironment = garbageCollectEnvironment;
81
- function recordReachableIds(store, retainedQuery, mutableRetainedIds) {
82
- recordReachableIdsFromRecord(store, store[exports.ROOT_ID], mutableRetainedIds, retainedQuery.normalizationAst, retainedQuery.variables);
83
- }
84
- function getLinkedId(data) {
85
- // @ts-expect-error
86
- if (data.__link != null) {
87
- // @ts-expect-error
88
- return data.__link;
89
- }
90
- else {
91
- throw new Error('Record in an invalid state');
92
- }
93
- }
94
- function recordReachableIdsFromRecord(store, currentRecord, mutableRetainedIds, selections, variables) {
95
- for (const selection of selections) {
96
- switch (selection.kind) {
97
- case 'Linked':
98
- const linkKey = (0, cache_1.getParentRecordKey)(selection, variables !== null && variables !== void 0 ? variables : {});
99
- const linkedFieldOrFields = currentRecord[linkKey];
100
- const ids = [];
101
- if (Array.isArray(linkedFieldOrFields)) {
102
- for (const link of linkedFieldOrFields) {
103
- if (link != null) {
104
- const id = getLinkedId(link);
105
- ids.push(id);
106
- }
107
- }
108
- }
109
- else {
110
- if (linkedFieldOrFields != null) {
111
- const id = getLinkedId(linkedFieldOrFields);
112
- ids.push(id);
113
- }
114
- }
115
- for (const nextRecordId of ids) {
116
- const nextRecord = store[nextRecordId];
117
- if (nextRecord != null) {
118
- mutableRetainedIds.add(nextRecordId);
119
- recordReachableIdsFromRecord(store, nextRecord, mutableRetainedIds, selection.selections, variables);
120
- }
121
- }
122
- continue;
123
- case 'Scalar':
124
- continue;
125
- }
126
- }
127
- }
128
- function unretainQuery(environment, retainedQuery) {
129
- environment.retainedQueries.delete(retainedQuery);
130
- environment.gcBuffer.push(retainedQuery);
131
- if (environment.gcBuffer.length > environment.gcBufferSize) {
132
- environment.gcBuffer.shift();
133
- return true;
134
- }
135
- return false;
136
- }
137
- exports.unretainQuery = unretainQuery;
138
- function retainQuery(environment, queryToRetain) {
139
- environment.retainedQueries.add(queryToRetain);
140
- // TODO can we remove this query from the buffer somehow?
141
- // We are relying on === equality, but we really should be comparing
142
- // id + variables
143
- }
144
- exports.retainQuery = retainQuery;
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { type IsographEnvironment } from './IsographEnvironment';
4
+ export declare const IsographEnvironmentContext: React.Context<IsographEnvironment | null>;
5
+ export type IsographEnvironmentProviderProps = {
6
+ environment: IsographEnvironment;
7
+ children: ReactNode;
8
+ };
9
+ export declare function IsographEnvironmentProvider({ environment, children, }: IsographEnvironmentProviderProps): React.JSX.Element;
10
+ export declare function useIsographEnvironment(): IsographEnvironment;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.useIsographEnvironment = exports.IsographEnvironmentProvider = exports.IsographEnvironmentContext = void 0;
27
+ const React = __importStar(require("react"));
28
+ const react_1 = require("react");
29
+ exports.IsographEnvironmentContext = (0, react_1.createContext)(null);
30
+ function IsographEnvironmentProvider({ environment, children, }) {
31
+ return (React.createElement(exports.IsographEnvironmentContext.Provider, { value: environment }, children));
32
+ }
33
+ exports.IsographEnvironmentProvider = IsographEnvironmentProvider;
34
+ function useIsographEnvironment() {
35
+ const context = (0, react_1.useContext)(exports.IsographEnvironmentContext);
36
+ if (context == null) {
37
+ throw new Error('Unexpected null environment context. Make sure to render ' +
38
+ 'this component within an IsographEnvironmentProvider component');
39
+ }
40
+ return context;
41
+ }
42
+ exports.useIsographEnvironment = useIsographEnvironment;
package/dist/cache.js CHANGED
@@ -4,6 +4,7 @@ exports.SECOND_SPLIT_KEY = exports.FIRST_SPLIT_KEY = exports.getParentRecordKey
4
4
  const react_disposable_state_1 = require("@isograph/react-disposable-state");
5
5
  const PromiseWrapper_1 = require("./PromiseWrapper");
6
6
  const IsographEnvironment_1 = require("./IsographEnvironment");
7
+ const garbageCollection_1 = require("./garbageCollection");
7
8
  function getOrCreateCache(environment, index, factory) {
8
9
  if (typeof window !== 'undefined' && window.__LOG) {
9
10
  console.log('getting cache for', {
@@ -69,7 +70,7 @@ function makeNetworkRequest(environment, artifact, variables) {
69
70
  kind: 'UndisposedComplete',
70
71
  retainedQuery,
71
72
  };
72
- (0, IsographEnvironment_1.retainQuery)(environment, retainedQuery);
73
+ (0, garbageCollection_1.retainQuery)(environment, retainedQuery);
73
74
  }
74
75
  // TODO return null
75
76
  return networkResponse;
@@ -79,9 +80,9 @@ function makeNetworkRequest(environment, artifact, variables) {
79
80
  wrapper,
80
81
  () => {
81
82
  if (status.kind === 'UndisposedComplete') {
82
- const didUnretainSomeQuery = (0, IsographEnvironment_1.unretainQuery)(environment, status.retainedQuery);
83
+ const didUnretainSomeQuery = (0, garbageCollection_1.unretainQuery)(environment, status.retainedQuery);
83
84
  if (didUnretainSomeQuery) {
84
- (0, IsographEnvironment_1.garbageCollectEnvironment)(environment);
85
+ (0, garbageCollection_1.garbageCollectEnvironment)(environment);
85
86
  }
86
87
  }
87
88
  status = {
@@ -0,0 +1,32 @@
1
+ import { Arguments } from './index';
2
+ import { ReaderArtifact } from './reader';
3
+ export type IsographEntrypoint<TReadFromStore extends Object, TResolverResult> = {
4
+ kind: 'Entrypoint';
5
+ queryText: string;
6
+ normalizationAst: NormalizationAst;
7
+ readerArtifact: ReaderArtifact<TReadFromStore, TResolverResult>;
8
+ nestedRefetchQueries: RefetchQueryArtifactWrapper[];
9
+ };
10
+ export type NormalizationAstNode = NormalizationScalarField | NormalizationLinkedField;
11
+ export type NormalizationAst = NormalizationAstNode[];
12
+ export type NormalizationScalarField = {
13
+ kind: 'Scalar';
14
+ fieldName: string;
15
+ arguments: Arguments | null;
16
+ };
17
+ export type NormalizationLinkedField = {
18
+ kind: 'Linked';
19
+ fieldName: string;
20
+ arguments: Arguments | null;
21
+ selections: NormalizationAst;
22
+ };
23
+ export type RefetchQueryArtifact = {
24
+ kind: 'RefetchQuery';
25
+ queryText: string;
26
+ normalizationAst: NormalizationAst;
27
+ };
28
+ export type RefetchQueryArtifactWrapper = {
29
+ artifact: RefetchQueryArtifact;
30
+ allowedVariables: string[];
31
+ };
32
+ export declare function assertIsEntrypoint<TReadFromStore extends Object, TResolverResult>(value: IsographEntrypoint<TReadFromStore, TResolverResult> | ((_: any) => any) | any): asserts value is IsographEntrypoint<TReadFromStore, TResolverResult>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertIsEntrypoint = void 0;
4
+ function assertIsEntrypoint(value) {
5
+ if (typeof value === 'function')
6
+ throw new Error('Not a string');
7
+ }
8
+ exports.assertIsEntrypoint = assertIsEntrypoint;
@@ -0,0 +1,11 @@
1
+ import { IsographEnvironment } from './IsographEnvironment';
2
+ import { NormalizationAst } from './index';
3
+ export type RetainedQuery = {
4
+ normalizationAst: NormalizationAst;
5
+ variables: {};
6
+ };
7
+ type DidUnretainSomeQuery = boolean;
8
+ export declare function unretainQuery(environment: IsographEnvironment, retainedQuery: RetainedQuery): DidUnretainSomeQuery;
9
+ export declare function retainQuery(environment: IsographEnvironment, queryToRetain: RetainedQuery): void;
10
+ export declare function garbageCollectEnvironment(environment: IsographEnvironment): void;
11
+ export {};
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.garbageCollectEnvironment = exports.retainQuery = exports.unretainQuery = void 0;
4
+ const IsographEnvironment_1 = require("./IsographEnvironment");
5
+ const cache_1 = require("./cache");
6
+ function unretainQuery(environment, retainedQuery) {
7
+ environment.retainedQueries.delete(retainedQuery);
8
+ environment.gcBuffer.push(retainedQuery);
9
+ if (environment.gcBuffer.length > environment.gcBufferSize) {
10
+ environment.gcBuffer.shift();
11
+ return true;
12
+ }
13
+ return false;
14
+ }
15
+ exports.unretainQuery = unretainQuery;
16
+ function retainQuery(environment, queryToRetain) {
17
+ environment.retainedQueries.add(queryToRetain);
18
+ // TODO can we remove this query from the buffer somehow?
19
+ // We are relying on === equality, but we really should be comparing
20
+ // id + variables
21
+ }
22
+ exports.retainQuery = retainQuery;
23
+ function garbageCollectEnvironment(environment) {
24
+ const retainedIds = new Set([IsographEnvironment_1.ROOT_ID]);
25
+ for (const query of environment.retainedQueries) {
26
+ recordReachableIds(environment.store, query, retainedIds);
27
+ }
28
+ for (const query of environment.gcBuffer) {
29
+ recordReachableIds(environment.store, query, retainedIds);
30
+ }
31
+ for (const dataId in environment.store) {
32
+ if (!retainedIds.has(dataId)) {
33
+ delete environment.store[dataId];
34
+ }
35
+ }
36
+ }
37
+ exports.garbageCollectEnvironment = garbageCollectEnvironment;
38
+ function recordReachableIds(store, retainedQuery, mutableRetainedIds) {
39
+ recordReachableIdsFromRecord(store, store[IsographEnvironment_1.ROOT_ID], mutableRetainedIds, retainedQuery.normalizationAst, retainedQuery.variables);
40
+ }
41
+ function getLinkedId(data) {
42
+ // @ts-expect-error
43
+ if (data.__link != null) {
44
+ // @ts-expect-error
45
+ return data.__link;
46
+ }
47
+ else {
48
+ throw new Error('Record in an invalid state');
49
+ }
50
+ }
51
+ function recordReachableIdsFromRecord(store, currentRecord, mutableRetainedIds, selections, variables) {
52
+ for (const selection of selections) {
53
+ switch (selection.kind) {
54
+ case 'Linked':
55
+ const linkKey = (0, cache_1.getParentRecordKey)(selection, variables !== null && variables !== void 0 ? variables : {});
56
+ const linkedFieldOrFields = currentRecord[linkKey];
57
+ const ids = [];
58
+ if (Array.isArray(linkedFieldOrFields)) {
59
+ for (const link of linkedFieldOrFields) {
60
+ if (link != null) {
61
+ const id = getLinkedId(link);
62
+ ids.push(id);
63
+ }
64
+ }
65
+ }
66
+ else {
67
+ if (linkedFieldOrFields != null) {
68
+ const id = getLinkedId(linkedFieldOrFields);
69
+ ids.push(id);
70
+ }
71
+ }
72
+ for (const nextRecordId of ids) {
73
+ const nextRecord = store[nextRecordId];
74
+ if (nextRecord != null) {
75
+ mutableRetainedIds.add(nextRecordId);
76
+ recordReachableIdsFromRecord(store, nextRecord, mutableRetainedIds, selection.selections, variables);
77
+ }
78
+ }
79
+ continue;
80
+ case 'Scalar':
81
+ continue;
82
+ }
83
+ }
84
+ }
package/dist/index.d.ts CHANGED
@@ -1,85 +1,16 @@
1
1
  import { DataId, IsographEnvironment, Link, StoreRecord } from './IsographEnvironment';
2
+ import { ReaderArtifact } from './reader';
3
+ import { IsographEntrypoint, RefetchQueryArtifactWrapper } from './entrypoint';
4
+ export { retainQuery, unretainQuery, type RetainedQuery, garbageCollectEnvironment, } from './garbageCollection';
2
5
  export { type PromiseWrapper } from './PromiseWrapper';
3
6
  export { makeNetworkRequest, subscribe } from './cache';
4
- export { IsographEnvironmentContext, ROOT_ID, type DataId, type DataTypeValue, type IsographEnvironment, IsographEnvironmentProvider, type IsographEnvironmentProviderProps, type IsographNetworkFunction, type IsographStore, type Link, type StoreRecord, useIsographEnvironment, createIsographEnvironment, createIsographStore, } from './IsographEnvironment';
7
+ export { ROOT_ID, type DataId, type DataTypeValue, type IsographEnvironment, type IsographNetworkFunction, type IsographStore, type Link, type StoreRecord, createIsographEnvironment, createIsographStore, } from './IsographEnvironment';
8
+ export { IsographEnvironmentProvider, useIsographEnvironment, type IsographEnvironmentProviderProps, } from './IsographEnvironmentProvider';
5
9
  export { useImperativeReference } from './useImperativeReference';
6
10
  export { EntrypointReader } from './EntrypointReader';
7
- export type IsographEntrypoint<TReadFromStore extends Object, TResolverResult> = {
8
- kind: 'Entrypoint';
9
- queryText: string;
10
- normalizationAst: NormalizationAst;
11
- readerArtifact: ReaderArtifact<TReadFromStore, TResolverResult>;
12
- nestedRefetchQueries: RefetchQueryArtifactWrapper[];
13
- };
14
- export type ReaderArtifact<TReadFromStore extends Object, TResolverResult> = {
15
- kind: 'ReaderArtifact';
16
- readerAst: ReaderAst<TReadFromStore>;
17
- resolver: (data: TReadFromStore, runtimeProps: any) => TResolverResult;
18
- variant: ReaderResolverVariant;
19
- };
20
- export type ReaderAstNode = ReaderScalarField | ReaderLinkedField | ReaderResolverField | ReaderRefetchField | ReaderMutationField;
21
- export type ReaderAst<TReadFromStore> = ReaderAstNode[];
11
+ export { type ReaderArtifact, ReaderAst, ReaderAstNode, ReaderLinkedField, ReaderMutationField, ReaderRefetchField, ReaderResolverField, ReaderResolverVariant, ReaderScalarField, } from './reader';
12
+ export { NormalizationAst, NormalizationAstNode, NormalizationLinkedField, NormalizationScalarField, IsographEntrypoint, assertIsEntrypoint, RefetchQueryArtifact, RefetchQueryArtifactWrapper, } from './entrypoint';
22
13
  export type ExtractSecondParam<T extends (arg1: any, arg2: any) => any> = T extends (arg1: any, arg2: infer P) => any ? P : never;
23
- export type ReaderScalarField = {
24
- kind: 'Scalar';
25
- fieldName: string;
26
- alias: string | null;
27
- arguments: Arguments | null;
28
- };
29
- export type ReaderLinkedField = {
30
- kind: 'Linked';
31
- fieldName: string;
32
- alias: string | null;
33
- selections: ReaderAst<unknown>;
34
- arguments: Arguments | null;
35
- };
36
- export type ReaderResolverVariant = {
37
- kind: 'Eager';
38
- } | {
39
- kind: 'Component';
40
- componentName: string;
41
- };
42
- export type ReaderResolverField = {
43
- kind: 'Resolver';
44
- alias: string;
45
- readerArtifact: ReaderArtifact<any, any>;
46
- arguments: Arguments | null;
47
- usedRefetchQueries: number[];
48
- };
49
- export type ReaderRefetchField = {
50
- kind: 'RefetchField';
51
- alias: string;
52
- readerArtifact: ReaderArtifact<any, any>;
53
- refetchQuery: number;
54
- };
55
- export type ReaderMutationField = {
56
- kind: 'MutationField';
57
- alias: string;
58
- readerArtifact: ReaderArtifact<any, any>;
59
- refetchQuery: number;
60
- };
61
- export type NormalizationAstNode = NormalizationScalarField | NormalizationLinkedField;
62
- export type NormalizationAst = NormalizationAstNode[];
63
- export type NormalizationScalarField = {
64
- kind: 'Scalar';
65
- fieldName: string;
66
- arguments: Arguments | null;
67
- };
68
- export type NormalizationLinkedField = {
69
- kind: 'Linked';
70
- fieldName: string;
71
- arguments: Arguments | null;
72
- selections: NormalizationAst;
73
- };
74
- export type RefetchQueryArtifact = {
75
- kind: 'RefetchQuery';
76
- queryText: string;
77
- normalizationAst: NormalizationAst;
78
- };
79
- export type RefetchQueryArtifactWrapper = {
80
- artifact: RefetchQueryArtifact;
81
- allowedVariables: string[];
82
- };
83
14
  export type Arguments = Argument[];
84
15
  export type Argument = [ArgumentName, ArgumentValue];
85
16
  export type ArgumentName = string;
package/dist/index.js CHANGED
@@ -1,36 +1,40 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultMissingFieldHandler = exports.readButDoNotEvaluate = exports.read = exports.useResult = exports.useLazyReference = exports.EntrypointReader = exports.useImperativeReference = exports.createIsographStore = exports.createIsographEnvironment = exports.useIsographEnvironment = exports.IsographEnvironmentProvider = exports.ROOT_ID = exports.IsographEnvironmentContext = exports.subscribe = exports.makeNetworkRequest = void 0;
3
+ exports.defaultMissingFieldHandler = exports.readButDoNotEvaluate = exports.read = exports.useResult = exports.useLazyReference = exports.assertIsEntrypoint = exports.EntrypointReader = exports.useImperativeReference = exports.useIsographEnvironment = exports.IsographEnvironmentProvider = exports.createIsographStore = exports.createIsographEnvironment = exports.ROOT_ID = exports.subscribe = exports.makeNetworkRequest = exports.garbageCollectEnvironment = exports.unretainQuery = exports.retainQuery = void 0;
4
4
  const cache_1 = require("./cache");
5
5
  const react_disposable_state_1 = require("@isograph/react-disposable-state");
6
6
  const componentCache_1 = require("./componentCache");
7
7
  const IsographEnvironment_1 = require("./IsographEnvironment");
8
8
  const react_1 = require("react");
9
+ const IsographEnvironmentProvider_1 = require("./IsographEnvironmentProvider");
10
+ const entrypoint_1 = require("./entrypoint");
11
+ var garbageCollection_1 = require("./garbageCollection");
12
+ Object.defineProperty(exports, "retainQuery", { enumerable: true, get: function () { return garbageCollection_1.retainQuery; } });
13
+ Object.defineProperty(exports, "unretainQuery", { enumerable: true, get: function () { return garbageCollection_1.unretainQuery; } });
14
+ Object.defineProperty(exports, "garbageCollectEnvironment", { enumerable: true, get: function () { return garbageCollection_1.garbageCollectEnvironment; } });
9
15
  var cache_2 = require("./cache");
10
16
  Object.defineProperty(exports, "makeNetworkRequest", { enumerable: true, get: function () { return cache_2.makeNetworkRequest; } });
11
17
  Object.defineProperty(exports, "subscribe", { enumerable: true, get: function () { return cache_2.subscribe; } });
12
18
  var IsographEnvironment_2 = require("./IsographEnvironment");
13
- Object.defineProperty(exports, "IsographEnvironmentContext", { enumerable: true, get: function () { return IsographEnvironment_2.IsographEnvironmentContext; } });
14
19
  Object.defineProperty(exports, "ROOT_ID", { enumerable: true, get: function () { return IsographEnvironment_2.ROOT_ID; } });
15
- Object.defineProperty(exports, "IsographEnvironmentProvider", { enumerable: true, get: function () { return IsographEnvironment_2.IsographEnvironmentProvider; } });
16
- Object.defineProperty(exports, "useIsographEnvironment", { enumerable: true, get: function () { return IsographEnvironment_2.useIsographEnvironment; } });
17
20
  Object.defineProperty(exports, "createIsographEnvironment", { enumerable: true, get: function () { return IsographEnvironment_2.createIsographEnvironment; } });
18
21
  Object.defineProperty(exports, "createIsographStore", { enumerable: true, get: function () { return IsographEnvironment_2.createIsographStore; } });
22
+ var IsographEnvironmentProvider_2 = require("./IsographEnvironmentProvider");
23
+ Object.defineProperty(exports, "IsographEnvironmentProvider", { enumerable: true, get: function () { return IsographEnvironmentProvider_2.IsographEnvironmentProvider; } });
24
+ Object.defineProperty(exports, "useIsographEnvironment", { enumerable: true, get: function () { return IsographEnvironmentProvider_2.useIsographEnvironment; } });
19
25
  var useImperativeReference_1 = require("./useImperativeReference");
20
26
  Object.defineProperty(exports, "useImperativeReference", { enumerable: true, get: function () { return useImperativeReference_1.useImperativeReference; } });
21
27
  var EntrypointReader_1 = require("./EntrypointReader");
22
28
  Object.defineProperty(exports, "EntrypointReader", { enumerable: true, get: function () { return EntrypointReader_1.EntrypointReader; } });
23
- function assertIsEntrypoint(value) {
24
- if (typeof value === 'function')
25
- throw new Error('Not a string');
26
- }
29
+ var entrypoint_2 = require("./entrypoint");
30
+ Object.defineProperty(exports, "assertIsEntrypoint", { enumerable: true, get: function () { return entrypoint_2.assertIsEntrypoint; } });
27
31
  // Note: we cannot write TEntrypoint extends IsographEntrypoint<any, any, any>, or else
28
32
  // if we do not explicitly pass a type, the read out type will be any.
29
33
  // We cannot write TEntrypoint extends IsographEntrypoint<never, never, never>, or else
30
34
  // any actual Entrypoint we pass will not be valid.
31
35
  function useLazyReference(entrypoint, variables) {
32
- const environment = (0, IsographEnvironment_1.useIsographEnvironment)();
33
- assertIsEntrypoint(entrypoint);
36
+ const environment = (0, IsographEnvironmentProvider_1.useIsographEnvironment)();
37
+ (0, entrypoint_1.assertIsEntrypoint)(entrypoint);
34
38
  const cache = (0, cache_1.getOrCreateCacheForArtifact)(environment, entrypoint, variables);
35
39
  // TODO add comment explaining why we never use this value
36
40
  // @ts-ignore
@@ -47,7 +51,7 @@ function useLazyReference(entrypoint, variables) {
47
51
  }
48
52
  exports.useLazyReference = useLazyReference;
49
53
  function useResult(fragmentReference) {
50
- const environment = (0, IsographEnvironment_1.useIsographEnvironment)();
54
+ const environment = (0, IsographEnvironmentProvider_1.useIsographEnvironment)();
51
55
  const [, setState] = (0, react_1.useState)();
52
56
  (0, react_1.useEffect)(() => {
53
57
  return (0, cache_1.subscribe)(environment, () => {
@@ -0,0 +1,47 @@
1
+ import { Arguments } from './index';
2
+ export type ReaderArtifact<TReadFromStore extends Object, TResolverResult> = {
3
+ kind: 'ReaderArtifact';
4
+ readerAst: ReaderAst<TReadFromStore>;
5
+ resolver: (data: TReadFromStore, runtimeProps: any) => TResolverResult;
6
+ variant: ReaderResolverVariant;
7
+ };
8
+ export type ReaderAstNode = ReaderScalarField | ReaderLinkedField | ReaderResolverField | ReaderRefetchField | ReaderMutationField;
9
+ export type ReaderAst<TReadFromStore> = ReaderAstNode[];
10
+ export type ReaderScalarField = {
11
+ kind: 'Scalar';
12
+ fieldName: string;
13
+ alias: string | null;
14
+ arguments: Arguments | null;
15
+ };
16
+ export type ReaderLinkedField = {
17
+ kind: 'Linked';
18
+ fieldName: string;
19
+ alias: string | null;
20
+ selections: ReaderAst<unknown>;
21
+ arguments: Arguments | null;
22
+ };
23
+ export type ReaderResolverVariant = {
24
+ kind: 'Eager';
25
+ } | {
26
+ kind: 'Component';
27
+ componentName: string;
28
+ };
29
+ export type ReaderResolverField = {
30
+ kind: 'Resolver';
31
+ alias: string;
32
+ readerArtifact: ReaderArtifact<any, any>;
33
+ arguments: Arguments | null;
34
+ usedRefetchQueries: number[];
35
+ };
36
+ export type ReaderRefetchField = {
37
+ kind: 'RefetchField';
38
+ alias: string;
39
+ readerArtifact: ReaderArtifact<any, any>;
40
+ refetchQuery: number;
41
+ };
42
+ export type ReaderMutationField = {
43
+ kind: 'MutationField';
44
+ alias: string;
45
+ readerArtifact: ReaderArtifact<any, any>;
46
+ refetchQuery: number;
47
+ };
package/dist/reader.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ // TODO this should probably be at least three distinct types, for @component,
3
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isograph/react",
3
- "version": "0.0.0-main-dc9ca2f6",
3
+ "version": "0.0.0-main-1bfd646b",
4
4
  "description": "Use Isograph with React",
5
5
  "homepage": "https://isograph.dev",
6
6
  "main": "dist/index.js",
@@ -16,8 +16,8 @@
16
16
  "prepack": "yarn run test && yarn run compile"
17
17
  },
18
18
  "dependencies": {
19
- "@isograph/disposable-types": "0.0.0-main-dc9ca2f6",
20
- "@isograph/react-disposable-state": "0.0.0-main-dc9ca2f6",
19
+ "@isograph/disposable-types": "0.0.0-main-1bfd646b",
20
+ "@isograph/react-disposable-state": "0.0.0-main-1bfd646b",
21
21
  "react": "^18.2.0"
22
22
  },
23
23
  "devDependencies": {
@@ -1,11 +1,5 @@
1
- import { ReactNode, createContext, useContext } from 'react';
2
- import * as React from 'react';
3
1
  import { ParentCache } from '@isograph/isograph-react-disposable-state';
4
- import { NormalizationAst } from './index';
5
- import { getParentRecordKey } from './cache';
6
-
7
- export const IsographEnvironmentContext =
8
- createContext<IsographEnvironment | null>(null);
2
+ import { RetainedQuery } from './garbageCollection';
9
3
 
10
4
  type ComponentName = string;
11
5
  type StringifiedArgs = string;
@@ -18,11 +12,6 @@ type ComponentCache = {
18
12
  export type Subscriptions = Set<() => void>;
19
13
  type SuspenseCache = { [index: string]: ParentCache<any> };
20
14
 
21
- export type RetainedQuery = {
22
- normalizationAst: NormalizationAst;
23
- variables: {};
24
- };
25
-
26
15
  export type IsographEnvironment = {
27
16
  store: IsographStore;
28
17
  networkFunction: IsographNetworkFunction;
@@ -51,6 +40,7 @@ export type IsographNetworkFunction = (
51
40
  export type Link = {
52
41
  __link: DataId;
53
42
  };
43
+
54
44
  export type DataTypeValue =
55
45
  // N.B. undefined is here to support optional id's, but
56
46
  // undefined should not *actually* be present in the store.
@@ -81,33 +71,6 @@ export type IsographStore = {
81
71
  __ROOT: StoreRecord;
82
72
  };
83
73
 
84
- export type IsographEnvironmentProviderProps = {
85
- environment: IsographEnvironment;
86
- children: ReactNode;
87
- };
88
-
89
- export function IsographEnvironmentProvider({
90
- environment,
91
- children,
92
- }: IsographEnvironmentProviderProps) {
93
- return (
94
- <IsographEnvironmentContext.Provider value={environment}>
95
- {children}
96
- </IsographEnvironmentContext.Provider>
97
- );
98
- }
99
-
100
- export function useIsographEnvironment(): IsographEnvironment {
101
- const context = useContext(IsographEnvironmentContext);
102
- if (context == null) {
103
- throw new Error(
104
- 'Unexpected null environment context. Make sure to render ' +
105
- 'this component within an IsographEnvironmentProvider component',
106
- );
107
- }
108
- return context;
109
- }
110
-
111
74
  const DEFAULT_GC_BUFFER_SIZE = 10;
112
75
  export function createIsographEnvironment(
113
76
  store: IsographStore,
@@ -132,119 +95,3 @@ export function createIsographStore() {
132
95
  [ROOT_ID]: {},
133
96
  };
134
97
  }
135
-
136
- export function garbageCollectEnvironment(environment: IsographEnvironment) {
137
- const retainedIds = new Set<DataId>([ROOT_ID]);
138
-
139
- for (const query of environment.retainedQueries) {
140
- recordReachableIds(environment.store, query, retainedIds);
141
- }
142
- for (const query of environment.gcBuffer) {
143
- recordReachableIds(environment.store, query, retainedIds);
144
- }
145
-
146
- for (const dataId in environment.store) {
147
- if (!retainedIds.has(dataId)) {
148
- delete environment.store[dataId];
149
- }
150
- }
151
- }
152
-
153
- function recordReachableIds(
154
- store: IsographStore,
155
- retainedQuery: RetainedQuery,
156
- mutableRetainedIds: Set<DataId>,
157
- ) {
158
- recordReachableIdsFromRecord(
159
- store,
160
- store[ROOT_ID],
161
- mutableRetainedIds,
162
- retainedQuery.normalizationAst,
163
- retainedQuery.variables,
164
- );
165
- }
166
-
167
- function getLinkedId(data: Exclude<DataTypeValue, null | void>): string {
168
- // @ts-expect-error
169
- if (data.__link != null) {
170
- // @ts-expect-error
171
- return data.__link;
172
- } else {
173
- throw new Error('Record in an invalid state');
174
- }
175
- }
176
-
177
- function recordReachableIdsFromRecord(
178
- store: IsographStore,
179
- currentRecord: StoreRecord,
180
- mutableRetainedIds: Set<DataId>,
181
- selections: NormalizationAst,
182
- variables: { [index: string]: string } | null,
183
- ) {
184
- for (const selection of selections) {
185
- switch (selection.kind) {
186
- case 'Linked':
187
- const linkKey = getParentRecordKey(selection, variables ?? {});
188
- const linkedFieldOrFields = currentRecord[linkKey];
189
-
190
- const ids = [];
191
- if (Array.isArray(linkedFieldOrFields)) {
192
- for (const link of linkedFieldOrFields) {
193
- if (link != null) {
194
- const id = getLinkedId(link);
195
- ids.push(id);
196
- }
197
- }
198
- } else {
199
- if (linkedFieldOrFields != null) {
200
- const id = getLinkedId(linkedFieldOrFields);
201
- ids.push(id);
202
- }
203
- }
204
-
205
- for (const nextRecordId of ids) {
206
- const nextRecord = store[nextRecordId];
207
- if (nextRecord != null) {
208
- mutableRetainedIds.add(nextRecordId);
209
- recordReachableIdsFromRecord(
210
- store,
211
- nextRecord,
212
- mutableRetainedIds,
213
- selection.selections,
214
- variables,
215
- );
216
- }
217
- }
218
-
219
- continue;
220
- case 'Scalar':
221
- continue;
222
- }
223
- }
224
- }
225
-
226
- type DidUnretainSomeQuery = boolean;
227
- export function unretainQuery(
228
- environment: IsographEnvironment,
229
- retainedQuery: RetainedQuery,
230
- ): DidUnretainSomeQuery {
231
- environment.retainedQueries.delete(retainedQuery);
232
- environment.gcBuffer.push(retainedQuery);
233
-
234
- if (environment.gcBuffer.length > environment.gcBufferSize) {
235
- environment.gcBuffer.shift();
236
- return true;
237
- }
238
-
239
- return false;
240
- }
241
-
242
- export function retainQuery(
243
- environment: IsographEnvironment,
244
- queryToRetain: RetainedQuery,
245
- ) {
246
- environment.retainedQueries.add(queryToRetain);
247
- // TODO can we remove this query from the buffer somehow?
248
- // We are relying on === equality, but we really should be comparing
249
- // id + variables
250
- }
@@ -0,0 +1,33 @@
1
+ import * as React from 'react';
2
+ import { ReactNode, createContext, useContext } from 'react';
3
+ import { type IsographEnvironment } from './IsographEnvironment';
4
+
5
+ export const IsographEnvironmentContext =
6
+ createContext<IsographEnvironment | null>(null);
7
+
8
+ export type IsographEnvironmentProviderProps = {
9
+ environment: IsographEnvironment;
10
+ children: ReactNode;
11
+ };
12
+
13
+ export function IsographEnvironmentProvider({
14
+ environment,
15
+ children,
16
+ }: IsographEnvironmentProviderProps) {
17
+ return (
18
+ <IsographEnvironmentContext.Provider value={environment}>
19
+ {children}
20
+ </IsographEnvironmentContext.Provider>
21
+ );
22
+ }
23
+
24
+ export function useIsographEnvironment(): IsographEnvironment {
25
+ const context = useContext(IsographEnvironmentContext);
26
+ if (context == null) {
27
+ throw new Error(
28
+ 'Unexpected null environment context. Make sure to render ' +
29
+ 'this component within an IsographEnvironmentProvider component',
30
+ );
31
+ }
32
+ return context;
33
+ }
package/src/cache.tsx CHANGED
@@ -21,11 +21,13 @@ import {
21
21
  StoreRecord,
22
22
  Link,
23
23
  type IsographEnvironment,
24
- garbageCollectEnvironment,
24
+ } from './IsographEnvironment';
25
+ import {
25
26
  RetainedQuery,
26
- unretainQuery,
27
+ garbageCollectEnvironment,
27
28
  retainQuery,
28
- } from './IsographEnvironment';
29
+ unretainQuery,
30
+ } from './garbageCollection';
29
31
 
30
32
  declare global {
31
33
  interface Window {
@@ -0,0 +1,59 @@
1
+ import { Arguments } from './index';
2
+ import { ReaderArtifact } from './reader';
3
+
4
+ // This type should be treated as an opaque type.
5
+ export type IsographEntrypoint<
6
+ TReadFromStore extends Object,
7
+ TResolverResult,
8
+ > = {
9
+ kind: 'Entrypoint';
10
+ queryText: string;
11
+ normalizationAst: NormalizationAst;
12
+ readerArtifact: ReaderArtifact<TReadFromStore, TResolverResult>;
13
+ nestedRefetchQueries: RefetchQueryArtifactWrapper[];
14
+ };
15
+
16
+ export type NormalizationAstNode =
17
+ | NormalizationScalarField
18
+ | NormalizationLinkedField;
19
+ export type NormalizationAst = NormalizationAstNode[];
20
+
21
+ export type NormalizationScalarField = {
22
+ kind: 'Scalar';
23
+ fieldName: string;
24
+ arguments: Arguments | null;
25
+ };
26
+
27
+ export type NormalizationLinkedField = {
28
+ kind: 'Linked';
29
+ fieldName: string;
30
+ arguments: Arguments | null;
31
+ selections: NormalizationAst;
32
+ };
33
+
34
+ // This is more like an entrypoint, but one specifically for a refetch query/mutation
35
+ export type RefetchQueryArtifact = {
36
+ kind: 'RefetchQuery';
37
+ queryText: string;
38
+ normalizationAst: NormalizationAst;
39
+ };
40
+
41
+ // TODO rename
42
+ export type RefetchQueryArtifactWrapper = {
43
+ artifact: RefetchQueryArtifact;
44
+ allowedVariables: string[];
45
+ };
46
+
47
+ export function assertIsEntrypoint<
48
+ TReadFromStore extends Object,
49
+ TResolverResult,
50
+ >(
51
+ value:
52
+ | IsographEntrypoint<TReadFromStore, TResolverResult>
53
+ | ((_: any) => any)
54
+ // Temporarily, allow any here. Once we automatically provide
55
+ // types to entrypoints, we probably don't need this.
56
+ | any,
57
+ ): asserts value is IsographEntrypoint<TReadFromStore, TResolverResult> {
58
+ if (typeof value === 'function') throw new Error('Not a string');
59
+ }
@@ -0,0 +1,131 @@
1
+ import {
2
+ DataId,
3
+ DataTypeValue,
4
+ IsographEnvironment,
5
+ IsographStore,
6
+ ROOT_ID,
7
+ StoreRecord,
8
+ } from './IsographEnvironment';
9
+ import { NormalizationAst } from './index';
10
+ import { getParentRecordKey } from './cache';
11
+
12
+ export type RetainedQuery = {
13
+ normalizationAst: NormalizationAst;
14
+ variables: {};
15
+ };
16
+
17
+ type DidUnretainSomeQuery = boolean;
18
+ export function unretainQuery(
19
+ environment: IsographEnvironment,
20
+ retainedQuery: RetainedQuery,
21
+ ): DidUnretainSomeQuery {
22
+ environment.retainedQueries.delete(retainedQuery);
23
+ environment.gcBuffer.push(retainedQuery);
24
+
25
+ if (environment.gcBuffer.length > environment.gcBufferSize) {
26
+ environment.gcBuffer.shift();
27
+ return true;
28
+ }
29
+
30
+ return false;
31
+ }
32
+
33
+ export function retainQuery(
34
+ environment: IsographEnvironment,
35
+ queryToRetain: RetainedQuery,
36
+ ) {
37
+ environment.retainedQueries.add(queryToRetain);
38
+ // TODO can we remove this query from the buffer somehow?
39
+ // We are relying on === equality, but we really should be comparing
40
+ // id + variables
41
+ }
42
+
43
+ export function garbageCollectEnvironment(environment: IsographEnvironment) {
44
+ const retainedIds = new Set<DataId>([ROOT_ID]);
45
+
46
+ for (const query of environment.retainedQueries) {
47
+ recordReachableIds(environment.store, query, retainedIds);
48
+ }
49
+ for (const query of environment.gcBuffer) {
50
+ recordReachableIds(environment.store, query, retainedIds);
51
+ }
52
+
53
+ for (const dataId in environment.store) {
54
+ if (!retainedIds.has(dataId)) {
55
+ delete environment.store[dataId];
56
+ }
57
+ }
58
+ }
59
+
60
+ function recordReachableIds(
61
+ store: IsographStore,
62
+ retainedQuery: RetainedQuery,
63
+ mutableRetainedIds: Set<DataId>,
64
+ ) {
65
+ recordReachableIdsFromRecord(
66
+ store,
67
+ store[ROOT_ID],
68
+ mutableRetainedIds,
69
+ retainedQuery.normalizationAst,
70
+ retainedQuery.variables,
71
+ );
72
+ }
73
+
74
+ function getLinkedId(data: Exclude<DataTypeValue, null | void>): string {
75
+ // @ts-expect-error
76
+ if (data.__link != null) {
77
+ // @ts-expect-error
78
+ return data.__link;
79
+ } else {
80
+ throw new Error('Record in an invalid state');
81
+ }
82
+ }
83
+
84
+ function recordReachableIdsFromRecord(
85
+ store: IsographStore,
86
+ currentRecord: StoreRecord,
87
+ mutableRetainedIds: Set<DataId>,
88
+ selections: NormalizationAst,
89
+ variables: { [index: string]: string } | null,
90
+ ) {
91
+ for (const selection of selections) {
92
+ switch (selection.kind) {
93
+ case 'Linked':
94
+ const linkKey = getParentRecordKey(selection, variables ?? {});
95
+ const linkedFieldOrFields = currentRecord[linkKey];
96
+
97
+ const ids = [];
98
+ if (Array.isArray(linkedFieldOrFields)) {
99
+ for (const link of linkedFieldOrFields) {
100
+ if (link != null) {
101
+ const id = getLinkedId(link);
102
+ ids.push(id);
103
+ }
104
+ }
105
+ } else {
106
+ if (linkedFieldOrFields != null) {
107
+ const id = getLinkedId(linkedFieldOrFields);
108
+ ids.push(id);
109
+ }
110
+ }
111
+
112
+ for (const nextRecordId of ids) {
113
+ const nextRecord = store[nextRecordId];
114
+ if (nextRecord != null) {
115
+ mutableRetainedIds.add(nextRecordId);
116
+ recordReachableIdsFromRecord(
117
+ store,
118
+ nextRecord,
119
+ mutableRetainedIds,
120
+ selection.selections,
121
+ variables,
122
+ );
123
+ }
124
+ }
125
+
126
+ continue;
127
+ case 'Scalar':
128
+ continue;
129
+ }
130
+ }
131
+ }
package/src/index.tsx CHANGED
@@ -14,140 +14,68 @@ import {
14
14
  Link,
15
15
  ROOT_ID,
16
16
  StoreRecord,
17
- useIsographEnvironment,
18
17
  } from './IsographEnvironment';
19
18
  import { useEffect, useState } from 'react';
19
+ import { useIsographEnvironment } from './IsographEnvironmentProvider';
20
+ import { ReaderArtifact, ReaderAst } from './reader';
21
+ import {
22
+ IsographEntrypoint,
23
+ RefetchQueryArtifactWrapper,
24
+ assertIsEntrypoint,
25
+ } from './entrypoint';
20
26
 
27
+ export {
28
+ retainQuery,
29
+ unretainQuery,
30
+ type RetainedQuery,
31
+ garbageCollectEnvironment,
32
+ } from './garbageCollection';
21
33
  export { type PromiseWrapper } from './PromiseWrapper';
22
34
  export { makeNetworkRequest, subscribe } from './cache';
23
35
  export {
24
- IsographEnvironmentContext,
25
36
  ROOT_ID,
26
37
  type DataId,
27
38
  type DataTypeValue,
28
39
  type IsographEnvironment,
29
- IsographEnvironmentProvider,
30
- type IsographEnvironmentProviderProps,
31
40
  type IsographNetworkFunction,
32
41
  type IsographStore,
33
42
  type Link,
34
43
  type StoreRecord,
35
- useIsographEnvironment,
36
44
  createIsographEnvironment,
37
45
  createIsographStore,
38
46
  } from './IsographEnvironment';
47
+ export {
48
+ IsographEnvironmentProvider,
49
+ useIsographEnvironment,
50
+ type IsographEnvironmentProviderProps,
51
+ } from './IsographEnvironmentProvider';
39
52
  export { useImperativeReference } from './useImperativeReference';
40
53
  export { EntrypointReader } from './EntrypointReader';
41
-
42
- // This type should be treated as an opaque type.
43
- export type IsographEntrypoint<
44
- TReadFromStore extends Object,
45
- TResolverResult,
46
- > = {
47
- kind: 'Entrypoint';
48
- queryText: string;
49
- normalizationAst: NormalizationAst;
50
- readerArtifact: ReaderArtifact<TReadFromStore, TResolverResult>;
51
- nestedRefetchQueries: RefetchQueryArtifactWrapper[];
52
- };
53
-
54
- // TODO this should probably be at least three distinct types, for @component,
55
- // non-@component and refetch resolvers
56
- export type ReaderArtifact<TReadFromStore extends Object, TResolverResult> = {
57
- kind: 'ReaderArtifact';
58
- readerAst: ReaderAst<TReadFromStore>;
59
- resolver: (data: TReadFromStore, runtimeProps: any) => TResolverResult;
60
- variant: ReaderResolverVariant;
61
- };
62
-
63
- export type ReaderAstNode =
64
- | ReaderScalarField
65
- | ReaderLinkedField
66
- | ReaderResolverField
67
- | ReaderRefetchField
68
- | ReaderMutationField;
69
-
70
- // @ts-ignore
71
- export type ReaderAst<TReadFromStore> = ReaderAstNode[];
54
+ export {
55
+ type ReaderArtifact,
56
+ ReaderAst,
57
+ ReaderAstNode,
58
+ ReaderLinkedField,
59
+ ReaderMutationField,
60
+ ReaderRefetchField,
61
+ ReaderResolverField,
62
+ ReaderResolverVariant,
63
+ ReaderScalarField,
64
+ } from './reader';
65
+ export {
66
+ NormalizationAst,
67
+ NormalizationAstNode,
68
+ NormalizationLinkedField,
69
+ NormalizationScalarField,
70
+ IsographEntrypoint,
71
+ assertIsEntrypoint,
72
+ RefetchQueryArtifact,
73
+ RefetchQueryArtifactWrapper,
74
+ } from './entrypoint';
72
75
 
73
76
  export type ExtractSecondParam<T extends (arg1: any, arg2: any) => any> =
74
77
  T extends (arg1: any, arg2: infer P) => any ? P : never;
75
78
 
76
- export type ReaderScalarField = {
77
- kind: 'Scalar';
78
- fieldName: string;
79
- alias: string | null;
80
- arguments: Arguments | null;
81
- };
82
- export type ReaderLinkedField = {
83
- kind: 'Linked';
84
- fieldName: string;
85
- alias: string | null;
86
- selections: ReaderAst<unknown>;
87
- arguments: Arguments | null;
88
- };
89
-
90
- export type ReaderResolverVariant =
91
- | { kind: 'Eager' }
92
- // componentName is the component's cacheKey for getRefReaderByName
93
- // and is the type + field concatenated
94
- | { kind: 'Component'; componentName: string };
95
-
96
- export type ReaderResolverField = {
97
- kind: 'Resolver';
98
- alias: string;
99
- readerArtifact: ReaderArtifact<any, any>;
100
- arguments: Arguments | null;
101
- usedRefetchQueries: number[];
102
- };
103
-
104
- export type ReaderRefetchField = {
105
- kind: 'RefetchField';
106
- alias: string;
107
- // TODO this bad modeling. A refetch field cannot have variant: "Component" (I think)
108
- readerArtifact: ReaderArtifact<any, any>;
109
- refetchQuery: number;
110
- };
111
-
112
- export type ReaderMutationField = {
113
- kind: 'MutationField';
114
- alias: string;
115
- // TODO this bad modeling. A mutation field cannot have variant: "Component" (I think)
116
- readerArtifact: ReaderArtifact<any, any>;
117
- refetchQuery: number;
118
- };
119
-
120
- export type NormalizationAstNode =
121
- | NormalizationScalarField
122
- | NormalizationLinkedField;
123
- export type NormalizationAst = NormalizationAstNode[];
124
-
125
- export type NormalizationScalarField = {
126
- kind: 'Scalar';
127
- fieldName: string;
128
- arguments: Arguments | null;
129
- };
130
-
131
- export type NormalizationLinkedField = {
132
- kind: 'Linked';
133
- fieldName: string;
134
- arguments: Arguments | null;
135
- selections: NormalizationAst;
136
- };
137
-
138
- // This is more like an entrypoint, but one specifically for a refetch query/mutation
139
- export type RefetchQueryArtifact = {
140
- kind: 'RefetchQuery';
141
- queryText: string;
142
- normalizationAst: NormalizationAst;
143
- };
144
-
145
- // TODO rename
146
- export type RefetchQueryArtifactWrapper = {
147
- artifact: RefetchQueryArtifact;
148
- allowedVariables: string[];
149
- };
150
-
151
79
  export type Arguments = Argument[];
152
80
  export type Argument = [ArgumentName, ArgumentValue];
153
81
  export type ArgumentName = string;
@@ -176,17 +104,6 @@ export type FragmentReference<
176
104
  nestedRefetchQueries: RefetchQueryArtifactWrapper[];
177
105
  };
178
106
 
179
- function assertIsEntrypoint<TReadFromStore extends Object, TResolverResult>(
180
- value:
181
- | IsographEntrypoint<TReadFromStore, TResolverResult>
182
- | ((_: any) => any)
183
- // Temporarily, allow any here. Once we automatically provide
184
- // types to entrypoints, we probably don't need this.
185
- | any,
186
- ): asserts value is IsographEntrypoint<TReadFromStore, TResolverResult> {
187
- if (typeof value === 'function') throw new Error('Not a string');
188
- }
189
-
190
107
  export type ExtractReadFromStore<Type> =
191
108
  Type extends IsographEntrypoint<infer X, any> ? X : never;
192
109
  export type ExtractResolverResult<Type> =
package/src/reader.ts ADDED
@@ -0,0 +1,65 @@
1
+ // TODO this should probably be at least three distinct types, for @component,
2
+
3
+ import { Arguments } from './index';
4
+
5
+ // non-@component and refetch resolvers
6
+ export type ReaderArtifact<TReadFromStore extends Object, TResolverResult> = {
7
+ kind: 'ReaderArtifact';
8
+ readerAst: ReaderAst<TReadFromStore>;
9
+ resolver: (data: TReadFromStore, runtimeProps: any) => TResolverResult;
10
+ variant: ReaderResolverVariant;
11
+ };
12
+
13
+ export type ReaderAstNode =
14
+ | ReaderScalarField
15
+ | ReaderLinkedField
16
+ | ReaderResolverField
17
+ | ReaderRefetchField
18
+ | ReaderMutationField;
19
+
20
+ // @ts-ignore
21
+ export type ReaderAst<TReadFromStore> = ReaderAstNode[];
22
+
23
+ export type ReaderScalarField = {
24
+ kind: 'Scalar';
25
+ fieldName: string;
26
+ alias: string | null;
27
+ arguments: Arguments | null;
28
+ };
29
+ export type ReaderLinkedField = {
30
+ kind: 'Linked';
31
+ fieldName: string;
32
+ alias: string | null;
33
+ selections: ReaderAst<unknown>;
34
+ arguments: Arguments | null;
35
+ };
36
+
37
+ export type ReaderResolverVariant =
38
+ | { kind: 'Eager' }
39
+ // componentName is the component's cacheKey for getRefReaderByName
40
+ // and is the type + field concatenated
41
+ | { kind: 'Component'; componentName: string };
42
+
43
+ export type ReaderResolverField = {
44
+ kind: 'Resolver';
45
+ alias: string;
46
+ readerArtifact: ReaderArtifact<any, any>;
47
+ arguments: Arguments | null;
48
+ usedRefetchQueries: number[];
49
+ };
50
+
51
+ export type ReaderRefetchField = {
52
+ kind: 'RefetchField';
53
+ alias: string;
54
+ // TODO this bad modeling. A refetch field cannot have variant: "Component" (I think)
55
+ readerArtifact: ReaderArtifact<any, any>;
56
+ refetchQuery: number;
57
+ };
58
+
59
+ export type ReaderMutationField = {
60
+ kind: 'MutationField';
61
+ alias: string;
62
+ // TODO this bad modeling. A mutation field cannot have variant: "Component" (I think)
63
+ readerArtifact: ReaderArtifact<any, any>;
64
+ refetchQuery: number;
65
+ };