@isograph/react 0.4.3 → 0.5.0
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.
- package/.turbo/turbo-compile-libs.log +2 -2
- package/dist/core/FragmentReference.d.ts +4 -2
- package/dist/core/FragmentReference.d.ts.map +1 -1
- package/dist/core/FragmentReference.js +2 -2
- package/dist/core/IsographEnvironment.d.ts +19 -11
- package/dist/core/IsographEnvironment.d.ts.map +1 -1
- package/dist/core/IsographEnvironment.js +27 -2
- package/dist/core/PromiseWrapper.d.ts +13 -7
- package/dist/core/PromiseWrapper.d.ts.map +1 -1
- package/dist/core/brand.d.ts +17 -0
- package/dist/core/brand.d.ts.map +1 -1
- package/dist/core/cache.d.ts +10 -7
- package/dist/core/cache.d.ts.map +1 -1
- package/dist/core/cache.js +102 -74
- package/dist/core/check.d.ts +8 -4
- package/dist/core/check.d.ts.map +1 -1
- package/dist/core/check.js +10 -7
- package/dist/core/componentCache.d.ts +1 -1
- package/dist/core/componentCache.d.ts.map +1 -1
- package/dist/core/componentCache.js +6 -4
- package/dist/core/entrypoint.d.ts +17 -7
- package/dist/core/entrypoint.d.ts.map +1 -1
- package/dist/core/garbageCollection.d.ts +8 -2
- package/dist/core/garbageCollection.d.ts.map +1 -1
- package/dist/core/garbageCollection.js +36 -14
- package/dist/core/logging.d.ts +16 -3
- package/dist/core/logging.d.ts.map +1 -1
- package/dist/core/makeNetworkRequest.d.ts +4 -2
- package/dist/core/makeNetworkRequest.d.ts.map +1 -1
- package/dist/core/makeNetworkRequest.js +115 -38
- package/dist/core/optimisticProxy.d.ts +59 -0
- package/dist/core/optimisticProxy.d.ts.map +1 -0
- package/dist/core/optimisticProxy.js +399 -0
- package/dist/core/read.d.ts +3 -2
- package/dist/core/read.d.ts.map +1 -1
- package/dist/core/read.js +158 -123
- package/dist/core/reader.d.ts +7 -4
- package/dist/core/reader.d.ts.map +1 -1
- package/dist/core/startUpdate.d.ts +3 -2
- package/dist/core/startUpdate.d.ts.map +1 -1
- package/dist/core/startUpdate.js +33 -34
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/loadable-hooks/useClientSideDefer.d.ts +9 -4
- package/dist/loadable-hooks/useClientSideDefer.d.ts.map +1 -1
- package/dist/loadable-hooks/useClientSideDefer.js +34 -1
- package/dist/loadable-hooks/useConnectionSpecPagination.d.ts +5 -3
- package/dist/loadable-hooks/useConnectionSpecPagination.d.ts.map +1 -1
- package/dist/loadable-hooks/useConnectionSpecPagination.js +27 -13
- package/dist/loadable-hooks/useImperativeLoadableField.d.ts +1 -1
- package/dist/loadable-hooks/useImperativeLoadableField.d.ts.map +1 -1
- package/dist/loadable-hooks/useSkipLimitPagination.d.ts +1 -1
- package/dist/loadable-hooks/useSkipLimitPagination.d.ts.map +1 -1
- package/dist/loadable-hooks/useSkipLimitPagination.js +1 -1
- package/dist/react/FragmentReader.d.ts +2 -1
- package/dist/react/FragmentReader.d.ts.map +1 -1
- package/dist/react/FragmentRenderer.d.ts +2 -1
- package/dist/react/FragmentRenderer.d.ts.map +1 -1
- package/dist/react/LoadableFieldReader.d.ts +9 -3
- package/dist/react/LoadableFieldReader.d.ts.map +1 -1
- package/dist/react/LoadableFieldReader.js +40 -1
- package/dist/react/LoadableFieldRenderer.d.ts +9 -3
- package/dist/react/LoadableFieldRenderer.d.ts.map +1 -1
- package/dist/react/LoadableFieldRenderer.js +36 -1
- package/dist/react/useImperativeReference.d.ts +4 -3
- package/dist/react/useImperativeReference.d.ts.map +1 -1
- package/dist/react/useImperativeReference.js +3 -5
- package/dist/react/useLazyReference.d.ts +2 -1
- package/dist/react/useLazyReference.d.ts.map +1 -1
- package/dist/react/useReadAndSubscribe.d.ts.map +1 -1
- package/dist/react/useReadAndSubscribe.js +1 -3
- package/dist/react/useResult.d.ts.map +1 -1
- package/dist/react/useResult.js +6 -5
- package/package.json +16 -17
- package/src/core/FragmentReference.ts +10 -4
- package/src/core/IsographEnvironment.ts +59 -13
- package/src/core/PromiseWrapper.ts +14 -7
- package/src/core/brand.ts +18 -0
- package/src/core/cache.ts +186 -91
- package/src/core/check.ts +21 -10
- package/src/core/componentCache.ts +8 -4
- package/src/core/entrypoint.ts +35 -6
- package/src/core/garbageCollection.ts +61 -19
- package/src/core/logging.ts +15 -3
- package/src/core/makeNetworkRequest.ts +307 -74
- package/src/core/optimisticProxy.ts +563 -0
- package/src/core/read.ts +233 -163
- package/src/core/reader.ts +10 -6
- package/src/core/startUpdate.ts +45 -30
- package/src/index.ts +2 -1
- package/src/loadable-hooks/useClientSideDefer.ts +76 -26
- package/src/loadable-hooks/useConnectionSpecPagination.ts +34 -17
- package/src/loadable-hooks/useImperativeLoadableField.ts +2 -2
- package/src/loadable-hooks/useSkipLimitPagination.ts +2 -3
- package/src/react/FragmentReader.tsx +3 -1
- package/src/react/FragmentRenderer.tsx +8 -1
- package/src/react/LoadableFieldReader.tsx +123 -12
- package/src/react/LoadableFieldRenderer.tsx +122 -12
- package/src/react/useImperativeReference.ts +20 -11
- package/src/react/useLazyReference.ts +17 -6
- package/src/react/useReadAndSubscribe.ts +1 -8
- package/src/react/useResult.ts +9 -11
- package/src/tests/__isograph/Node/asEconomist/resolver_reader.ts +1 -1
- package/src/tests/__isograph/Query/linkedUpdate/entrypoint.ts +3 -1
- package/src/tests/__isograph/Query/linkedUpdate/raw_response_type.ts +13 -0
- package/src/tests/__isograph/Query/linkedUpdate/resolver_reader.ts +1 -1
- package/src/tests/__isograph/Query/meName/entrypoint.ts +3 -1
- package/src/tests/__isograph/Query/meName/raw_response_type.ts +7 -0
- package/src/tests/__isograph/Query/meName/resolver_reader.ts +1 -1
- package/src/tests/__isograph/Query/meNameSuccessor/entrypoint.ts +3 -1
- package/src/tests/__isograph/Query/meNameSuccessor/raw_response_type.ts +14 -0
- package/src/tests/__isograph/Query/meNameSuccessor/resolver_reader.ts +1 -1
- package/src/tests/__isograph/Query/nodeField/entrypoint.ts +3 -1
- package/src/tests/__isograph/Query/nodeField/raw_response_type.ts +7 -0
- package/src/tests/__isograph/Query/nodeField/resolver_reader.ts +1 -1
- package/src/tests/__isograph/Query/normalizeUndefinedField/entrypoint.ts +33 -0
- package/src/tests/__isograph/Query/normalizeUndefinedField/normalization_ast.ts +25 -0
- package/src/tests/__isograph/Query/normalizeUndefinedField/output_type.ts +3 -0
- package/src/tests/__isograph/Query/normalizeUndefinedField/param_type.ts +9 -0
- package/src/tests/__isograph/Query/normalizeUndefinedField/query_text.ts +6 -0
- package/src/tests/__isograph/Query/normalizeUndefinedField/raw_response_type.ts +7 -0
- package/src/tests/__isograph/Query/normalizeUndefinedField/resolver_reader.ts +38 -0
- package/src/tests/__isograph/Query/startUpdate/entrypoint.ts +3 -1
- package/src/tests/__isograph/Query/startUpdate/raw_response_type.ts +8 -0
- package/src/tests/__isograph/Query/startUpdate/resolver_reader.ts +1 -1
- package/src/tests/__isograph/Query/subquery/entrypoint.ts +3 -1
- package/src/tests/__isograph/Query/subquery/raw_response_type.ts +9 -0
- package/src/tests/__isograph/Query/subquery/resolver_reader.ts +1 -1
- package/src/tests/__isograph/iso.ts +11 -1
- package/src/tests/garbageCollection.test.ts +8 -5
- package/src/tests/meNameSuccessor.ts +6 -3
- package/src/tests/nodeQuery.ts +4 -2
- package/src/tests/normalizeData.test.ts +89 -15
- package/src/tests/optimisticProxy.test.ts +860 -0
- package/src/tests/startUpdate.test.ts +7 -5
- package/src/tests/__isograph/Economist/__link/output_type.ts +0 -2
package/package.json
CHANGED
|
@@ -1,27 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@isograph/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Use Isograph with React",
|
|
5
5
|
"homepage": "https://isograph.dev",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"author": "Isograph Labs",
|
|
9
9
|
"license": "MIT",
|
|
10
|
-
"scripts": {
|
|
11
|
-
"compile-libs": "rimraf dist && tsc -p tsconfig.pkg.json",
|
|
12
|
-
"compile-watch": "tsc -p tsconfig.pkg.json --watch",
|
|
13
|
-
"test": "vitest run",
|
|
14
|
-
"test-watch": "vitest watch",
|
|
15
|
-
"coverage": "vitest run --coverage",
|
|
16
|
-
"prepack": "pnpm run test && pnpm run compile-libs",
|
|
17
|
-
"tsc": "tsc",
|
|
18
|
-
"tsc-force": "tsc --build --clean && tsc --build --force",
|
|
19
|
-
"iso": "cross-env ISO_PRINT_ABSOLUTE_FILEPATH=1 ../../target/debug/isograph_cli --config ./isograph.config.json"
|
|
20
|
-
},
|
|
21
10
|
"dependencies": {
|
|
22
|
-
"@isograph/disposable-types": "
|
|
23
|
-
"@isograph/react-disposable-state": "
|
|
24
|
-
"@isograph/reference-counted-pointer": "
|
|
11
|
+
"@isograph/disposable-types": "0.5.0",
|
|
12
|
+
"@isograph/react-disposable-state": "0.5.0",
|
|
13
|
+
"@isograph/reference-counted-pointer": "0.5.0"
|
|
25
14
|
},
|
|
26
15
|
"peerDependencies": {
|
|
27
16
|
"react": "^18.0.0 || ^19.0.0"
|
|
@@ -39,5 +28,15 @@
|
|
|
39
28
|
"url": "git+https://github.com/isographlabs/isograph.git",
|
|
40
29
|
"directory": "libs/isograph-react"
|
|
41
30
|
},
|
|
42
|
-
"sideEffects": false
|
|
43
|
-
|
|
31
|
+
"sideEffects": false,
|
|
32
|
+
"scripts": {
|
|
33
|
+
"compile-libs": "rimraf dist && tsc -p tsconfig.pkg.json",
|
|
34
|
+
"compile-watch": "tsc -p tsconfig.pkg.json --watch",
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"test-watch": "vitest watch",
|
|
37
|
+
"coverage": "vitest run --coverage",
|
|
38
|
+
"tsc": "tsc",
|
|
39
|
+
"tsc-force": "tsc --build --clean && tsc --build --force",
|
|
40
|
+
"iso": "cross-env ISO_PRINT_ABSOLUTE_FILEPATH=1 ../../target/debug/isograph_cli --config ./isograph.config.json"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { ReaderWithRefetchQueries } from '../core/entrypoint';
|
|
2
2
|
import { stableCopy } from './cache';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
type ComponentOrFieldName,
|
|
5
|
+
type StoreLink,
|
|
6
|
+
} from './IsographEnvironment';
|
|
4
7
|
import { PromiseWrapper } from './PromiseWrapper';
|
|
5
8
|
import type { StartUpdate } from './reader';
|
|
6
9
|
|
|
@@ -53,8 +56,12 @@ export type FragmentReference<
|
|
|
53
56
|
ReaderWithRefetchQueries<TReadFromStore, TClientFieldValue>
|
|
54
57
|
>;
|
|
55
58
|
readonly root: StoreLink;
|
|
59
|
+
readonly fieldName: ComponentOrFieldName;
|
|
60
|
+
readonly readerArtifactKind:
|
|
61
|
+
| 'EagerReaderArtifact'
|
|
62
|
+
| 'ComponentReaderArtifact';
|
|
56
63
|
// TODO we potentially stably copy and stringify variables a lot!
|
|
57
|
-
// So, we should employ interior mutability: pretend that
|
|
64
|
+
// So, we should employ interior mutability: pretend that fragment reference
|
|
58
65
|
// is immutable, but actually store something like
|
|
59
66
|
// `Map<Variable, StablyCopiedStringifiedOutput>`
|
|
60
67
|
// and read or update that map when we would otherwise stably copy and
|
|
@@ -67,7 +74,6 @@ export type StableIdForFragmentReference = string;
|
|
|
67
74
|
|
|
68
75
|
export function stableIdForFragmentReference(
|
|
69
76
|
fragmentReference: FragmentReference<any, any>,
|
|
70
|
-
fieldName: string,
|
|
71
77
|
): StableIdForFragmentReference {
|
|
72
|
-
return `${fragmentReference.root.__typename}/${fragmentReference.root.__link}/${fieldName}/${JSON.stringify(stableCopy(fragmentReference.variables))}`;
|
|
78
|
+
return `${fragmentReference.root.__typename}/${fragmentReference.root.__link}/${fragmentReference.fieldName}/${JSON.stringify(stableCopy(fragmentReference.variables))}`;
|
|
73
79
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { ParentCache } from '@isograph/react-disposable-state';
|
|
2
|
+
import type { Brand } from './brand';
|
|
3
|
+
import { isArray } from './cache';
|
|
2
4
|
import {
|
|
3
5
|
IsographEntrypoint,
|
|
4
6
|
IsographOperation,
|
|
5
7
|
IsographPersistedOperation,
|
|
8
|
+
type ReaderWithRefetchQueries,
|
|
9
|
+
type ReaderWithRefetchQueriesLoader,
|
|
6
10
|
} from './entrypoint';
|
|
7
11
|
import {
|
|
8
12
|
FragmentReference,
|
|
@@ -10,12 +14,16 @@ import {
|
|
|
10
14
|
type StableIdForFragmentReference,
|
|
11
15
|
type UnknownTReadFromStore,
|
|
12
16
|
} from './FragmentReference';
|
|
13
|
-
import { RetainedQuery } from './garbageCollection';
|
|
17
|
+
import type { RetainedQuery } from './garbageCollection';
|
|
14
18
|
import { LogFunction, WrappedLogFunction } from './logging';
|
|
15
|
-
import {
|
|
19
|
+
import { type StoreLayer } from './optimisticProxy';
|
|
20
|
+
import {
|
|
21
|
+
PromiseWrapper,
|
|
22
|
+
wrapPromise,
|
|
23
|
+
wrapResolvedValue,
|
|
24
|
+
} from './PromiseWrapper';
|
|
16
25
|
import { WithEncounteredRecords } from './read';
|
|
17
26
|
import type { ReaderAst, StartUpdate } from './reader';
|
|
18
|
-
import type { Brand } from './brand';
|
|
19
27
|
|
|
20
28
|
export type ComponentOrFieldName = string;
|
|
21
29
|
export type StringifiedArgs = string;
|
|
@@ -56,7 +64,7 @@ export type Subscriptions = Set<Subscription>;
|
|
|
56
64
|
export type CacheMap<T> = { [index: string]: ParentCache<T> };
|
|
57
65
|
|
|
58
66
|
export type IsographEnvironment = {
|
|
59
|
-
|
|
67
|
+
store: StoreLayer;
|
|
60
68
|
readonly networkFunction: IsographNetworkFunction;
|
|
61
69
|
readonly missingFieldHandler: MissingFieldHandler | null;
|
|
62
70
|
readonly componentCache: FieldCache<React.FC<any>>;
|
|
@@ -68,7 +76,7 @@ export type IsographEnvironment = {
|
|
|
68
76
|
// TODO make this a CacheMap and add GC
|
|
69
77
|
readonly entrypointArtifactCache: Map<
|
|
70
78
|
string,
|
|
71
|
-
PromiseWrapper<IsographEntrypoint<any, any, any>>
|
|
79
|
+
PromiseWrapper<IsographEntrypoint<any, any, any, any>>
|
|
72
80
|
>;
|
|
73
81
|
readonly retainedQueries: Set<RetainedQuery>;
|
|
74
82
|
readonly gcBuffer: Array<RetainedQuery>;
|
|
@@ -111,7 +119,7 @@ export type DataTypeValue =
|
|
|
111
119
|
// Singular linked fields:
|
|
112
120
|
| StoreLink
|
|
113
121
|
// Plural scalar and linked fields:
|
|
114
|
-
| DataTypeValue[];
|
|
122
|
+
| readonly DataTypeValue[];
|
|
115
123
|
|
|
116
124
|
export type StoreRecord = {
|
|
117
125
|
[index: DataId | string]: DataTypeValue;
|
|
@@ -125,18 +133,21 @@ export type DataId = string;
|
|
|
125
133
|
|
|
126
134
|
export const ROOT_ID: DataId & '__ROOT' = '__ROOT';
|
|
127
135
|
|
|
128
|
-
export type
|
|
136
|
+
export type StoreLayerData = {
|
|
129
137
|
[index: TypeName]: {
|
|
130
138
|
[index: DataId]: StoreRecord | null;
|
|
131
139
|
} | null;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export interface BaseStoreLayerData extends StoreLayerData {
|
|
132
143
|
readonly Query: {
|
|
133
144
|
readonly __ROOT: StoreRecord;
|
|
134
145
|
};
|
|
135
|
-
}
|
|
146
|
+
}
|
|
136
147
|
|
|
137
148
|
const DEFAULT_GC_BUFFER_SIZE = 10;
|
|
138
149
|
export function createIsographEnvironment(
|
|
139
|
-
|
|
150
|
+
baseStoreLayerData: BaseStoreLayerData,
|
|
140
151
|
networkFunction: IsographNetworkFunction,
|
|
141
152
|
missingFieldHandler?: MissingFieldHandler | null,
|
|
142
153
|
logFunction?: LogFunction | null,
|
|
@@ -144,6 +155,12 @@ export function createIsographEnvironment(
|
|
|
144
155
|
logFunction?.({
|
|
145
156
|
kind: 'EnvironmentCreated',
|
|
146
157
|
});
|
|
158
|
+
let store = {
|
|
159
|
+
kind: 'BaseStoreLayer',
|
|
160
|
+
data: baseStoreLayerData,
|
|
161
|
+
parentStoreLayer: null,
|
|
162
|
+
childStoreLayer: null,
|
|
163
|
+
} as const;
|
|
147
164
|
return {
|
|
148
165
|
store,
|
|
149
166
|
networkFunction,
|
|
@@ -160,7 +177,7 @@ export function createIsographEnvironment(
|
|
|
160
177
|
};
|
|
161
178
|
}
|
|
162
179
|
|
|
163
|
-
export function createIsographStore():
|
|
180
|
+
export function createIsographStore(): BaseStoreLayerData {
|
|
164
181
|
return {
|
|
165
182
|
Query: {
|
|
166
183
|
[ROOT_ID]: {},
|
|
@@ -169,7 +186,7 @@ export function createIsographStore(): IsographStore {
|
|
|
169
186
|
}
|
|
170
187
|
|
|
171
188
|
export function assertLink(link: DataTypeValue): StoreLink | null | undefined {
|
|
172
|
-
if (
|
|
189
|
+
if (isArray(link)) {
|
|
173
190
|
throw new Error('Unexpected array');
|
|
174
191
|
}
|
|
175
192
|
if (link == null) {
|
|
@@ -198,8 +215,8 @@ export function getLink(maybeLink: DataTypeValue): StoreLink | null {
|
|
|
198
215
|
export function getOrLoadIsographArtifact(
|
|
199
216
|
environment: IsographEnvironment,
|
|
200
217
|
key: string,
|
|
201
|
-
loader: () => Promise<IsographEntrypoint<any, any, any>>,
|
|
202
|
-
): PromiseWrapper<IsographEntrypoint<any, any, any>> {
|
|
218
|
+
loader: () => Promise<IsographEntrypoint<any, any, any, any>>,
|
|
219
|
+
): PromiseWrapper<IsographEntrypoint<any, any, any, any>> {
|
|
203
220
|
const value = environment.entrypointArtifactCache.get(key);
|
|
204
221
|
if (value != null) {
|
|
205
222
|
return value;
|
|
@@ -208,3 +225,32 @@ export function getOrLoadIsographArtifact(
|
|
|
208
225
|
environment.entrypointArtifactCache.set(key, wrapped);
|
|
209
226
|
return wrapped;
|
|
210
227
|
}
|
|
228
|
+
|
|
229
|
+
export function getOrLoadReaderWithRefetchQueries(
|
|
230
|
+
_environment: IsographEnvironment,
|
|
231
|
+
readerWithRefetchQueries:
|
|
232
|
+
| ReaderWithRefetchQueries<any, any>
|
|
233
|
+
| ReaderWithRefetchQueriesLoader<any, any>,
|
|
234
|
+
): {
|
|
235
|
+
readerWithRefetchQueries: PromiseWrapper<ReaderWithRefetchQueries<any, any>>;
|
|
236
|
+
fieldName: string;
|
|
237
|
+
readerArtifactKind: 'EagerReaderArtifact' | 'ComponentReaderArtifact';
|
|
238
|
+
} {
|
|
239
|
+
switch (readerWithRefetchQueries.kind) {
|
|
240
|
+
case 'ReaderWithRefetchQueries':
|
|
241
|
+
return {
|
|
242
|
+
readerWithRefetchQueries: wrapResolvedValue(readerWithRefetchQueries),
|
|
243
|
+
fieldName: readerWithRefetchQueries.readerArtifact.fieldName,
|
|
244
|
+
readerArtifactKind: readerWithRefetchQueries.readerArtifact.kind,
|
|
245
|
+
};
|
|
246
|
+
case 'ReaderWithRefetchQueriesLoader':
|
|
247
|
+
return {
|
|
248
|
+
// TODO: cache promise wrapper
|
|
249
|
+
readerWithRefetchQueries: wrapPromise(
|
|
250
|
+
readerWithRefetchQueries.loader(),
|
|
251
|
+
),
|
|
252
|
+
fieldName: readerWithRefetchQueries.fieldName,
|
|
253
|
+
readerArtifactKind: readerWithRefetchQueries.readerArtifactKind,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
}
|
|
@@ -5,12 +5,12 @@ export type NotSet = typeof NOT_SET;
|
|
|
5
5
|
|
|
6
6
|
export type Result<T, E> =
|
|
7
7
|
| {
|
|
8
|
-
kind: 'Ok';
|
|
9
|
-
value: T;
|
|
8
|
+
readonly kind: 'Ok';
|
|
9
|
+
readonly value: T;
|
|
10
10
|
}
|
|
11
11
|
| {
|
|
12
|
-
kind: 'Err';
|
|
13
|
-
error: E;
|
|
12
|
+
readonly kind: 'Err';
|
|
13
|
+
readonly error: E;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -22,6 +22,13 @@ export type PromiseWrapper<T, E = any> = {
|
|
|
22
22
|
result: Result<Exclude<T, NotSet>, E> | NotSet;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
+
export interface PromiseWrapperOk<T, E = any> extends PromiseWrapper<T, E> {
|
|
26
|
+
result: {
|
|
27
|
+
readonly kind: 'Ok';
|
|
28
|
+
readonly value: Exclude<T, NotSet>;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
25
32
|
export function wrapPromise<T>(
|
|
26
33
|
promise: Promise<Exclude<T, NotSet>>,
|
|
27
34
|
): PromiseWrapper<T, unknown> {
|
|
@@ -39,7 +46,7 @@ export function wrapPromise<T>(
|
|
|
39
46
|
|
|
40
47
|
export function wrapResolvedValue<T>(
|
|
41
48
|
value: Exclude<T, NotSet>,
|
|
42
|
-
):
|
|
49
|
+
): PromiseWrapperOk<T, never> {
|
|
43
50
|
return {
|
|
44
51
|
promise: Promise.resolve(value),
|
|
45
52
|
result: {
|
|
@@ -65,8 +72,8 @@ export function readPromise<T, E>(p: PromiseWrapper<T, E>): T {
|
|
|
65
72
|
|
|
66
73
|
export type PromiseState<T, E> =
|
|
67
74
|
| {
|
|
68
|
-
kind: 'Pending';
|
|
69
|
-
promise: Promise<T>;
|
|
75
|
+
readonly kind: 'Pending';
|
|
76
|
+
readonly promise: Promise<T>;
|
|
70
77
|
}
|
|
71
78
|
| Result<T, E>;
|
|
72
79
|
|
package/src/core/brand.ts
CHANGED
|
@@ -16,3 +16,21 @@ export type Brand<
|
|
|
16
16
|
Brand extends symbol | string,
|
|
17
17
|
// @ts-ignore
|
|
18
18
|
> = infer _ extends Brand ? BaseType : never;
|
|
19
|
+
|
|
20
|
+
declare const PhantomDataBrand: unique symbol;
|
|
21
|
+
/**
|
|
22
|
+
* A phantom data type is one that shouldn't show up at runtime, but is checked statically (and only) at compile time.
|
|
23
|
+
* Data types can use extra properties to act as markers or to perform type checking at compile time. These extra properties should hold no storage values, and have no runtime behavior.
|
|
24
|
+
*
|
|
25
|
+
* ```tsx
|
|
26
|
+
* type MyType<T> = {
|
|
27
|
+
* readonly value: number;
|
|
28
|
+
* readonly '~T'?: PhantomData<T>;
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export type PhantomData<T> = Brand<T, typeof PhantomDataBrand>;
|
|
33
|
+
|
|
34
|
+
export type Invariant<T> = (_: T) => T;
|
|
35
|
+
export type Covariant<T> = (_: never) => T;
|
|
36
|
+
export type Contravariant<T> = (_: T) => void;
|