enskit 0.0.1 → 1.10.1
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/LICENSE +21 -0
- package/dist/react/index.d.ts +39 -0
- package/dist/react/index.js +22 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/omnigraph/index.d.ts +32 -0
- package/dist/react/omnigraph/index.js +187 -0
- package/dist/react/omnigraph/index.js.map +1 -0
- package/package.json +60 -6
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 NameHash
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { LiteralName, InterpretedName, literalNameToInterpretedName } from 'enssdk';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type MalformedNameRenderer = (name: string) => ReactNode;
|
|
5
|
+
type InterpretedNameRenderer = (name: InterpretedName) => ReactNode;
|
|
6
|
+
/**
|
|
7
|
+
* Renders a {@link LiteralName} by ensuring it is an {@link InterpretedName}. This is useful for
|
|
8
|
+
* ensuring that downstream components get the guarantees of an {@link InterpretedName}.
|
|
9
|
+
*
|
|
10
|
+
* @param name - The user-provided {@link LiteralName} to render.
|
|
11
|
+
* @param children - Render prop called with the {@link InterpretedName} when `name` is already interpreted.
|
|
12
|
+
* @param coerced - Render prop called with the coerced {@link InterpretedName} when `name` was not already
|
|
13
|
+
* interpreted but could be successfully coerced under `options`. Typically used to redirect the user to the
|
|
14
|
+
* canonical URL.
|
|
15
|
+
* @param malformed - Render prop called with the original literal string when `name` cannot be coerced into an
|
|
16
|
+
* {@link InterpretedName} under `options`.
|
|
17
|
+
* @param options - Forwarded to {@link literalNameToInterpretedName}. Controls how the interpretation handles edge
|
|
18
|
+
* cases. When `options.allowENSRootName` is `true`, an empty `name` is accepted and rendered via `children`; when
|
|
19
|
+
* `false` (default), an empty `name` falls through to `malformed`. When `options.allowEncodedLabelHashes` is
|
|
20
|
+
* `true`, a Label already formatted as an EncodedLabelHash is preserved verbatim; when `false` (default), such a
|
|
21
|
+
* Label is treated like any other input and passed through normalization, which will fail and fall through to the
|
|
22
|
+
* unnormalizable-Label handling. When `options.coerceUnnormalizedLabelsToNormalizedLabels` is `true` (default), an
|
|
23
|
+
* unnormalized Label is passed through ENSIP-15 normalization (e.g. `"Vitalik"` → `"vitalik"`); when `false`, any
|
|
24
|
+
* unnormalized Label causes `malformed` to be invoked — no normalization is attempted and
|
|
25
|
+
* `coerceUnnormalizableLabelsToEncodedLabelHashes` is not consulted. When
|
|
26
|
+
* `options.coerceUnnormalizableLabelsToEncodedLabelHashes` is `true`, a Label that cannot be normalized is replaced
|
|
27
|
+
* with the EncodedLabelHash of its literal bytes and `coerced` is invoked; when `false` (default), encountering
|
|
28
|
+
* such a Label causes `malformed` to be invoked. Only consulted when
|
|
29
|
+
* `coerceUnnormalizedLabelsToNormalizedLabels` is `true`.
|
|
30
|
+
*/
|
|
31
|
+
declare function EnsureInterpretedName({ name, children, coerced, malformed, options, }: {
|
|
32
|
+
name: LiteralName;
|
|
33
|
+
children: InterpretedNameRenderer;
|
|
34
|
+
coerced: InterpretedNameRenderer;
|
|
35
|
+
malformed: MalformedNameRenderer;
|
|
36
|
+
options?: Parameters<typeof literalNameToInterpretedName>[1];
|
|
37
|
+
}): ReactNode;
|
|
38
|
+
|
|
39
|
+
export { EnsureInterpretedName };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/react/components/ensure-interpreted-name.tsx
|
|
2
|
+
import { literalNameToInterpretedName } from "enssdk";
|
|
3
|
+
function EnsureInterpretedName({
|
|
4
|
+
name,
|
|
5
|
+
children,
|
|
6
|
+
coerced,
|
|
7
|
+
malformed,
|
|
8
|
+
options
|
|
9
|
+
}) {
|
|
10
|
+
let interpreted;
|
|
11
|
+
try {
|
|
12
|
+
interpreted = literalNameToInterpretedName(name, options);
|
|
13
|
+
} catch {
|
|
14
|
+
return malformed(name);
|
|
15
|
+
}
|
|
16
|
+
if (name !== interpreted) return coerced(interpreted);
|
|
17
|
+
return children(interpreted);
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
EnsureInterpretedName
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/react/components/ensure-interpreted-name.tsx"],"sourcesContent":["import { type InterpretedName, type LiteralName, literalNameToInterpretedName } from \"enssdk\";\nimport type { ReactNode } from \"react\";\n\ntype MalformedNameRenderer = (name: string) => ReactNode;\ntype InterpretedNameRenderer = (name: InterpretedName) => ReactNode;\n\n/**\n * Renders a {@link LiteralName} by ensuring it is an {@link InterpretedName}. This is useful for\n * ensuring that downstream components get the guarantees of an {@link InterpretedName}.\n *\n * @param name - The user-provided {@link LiteralName} to render.\n * @param children - Render prop called with the {@link InterpretedName} when `name` is already interpreted.\n * @param coerced - Render prop called with the coerced {@link InterpretedName} when `name` was not already\n * interpreted but could be successfully coerced under `options`. Typically used to redirect the user to the\n * canonical URL.\n * @param malformed - Render prop called with the original literal string when `name` cannot be coerced into an\n * {@link InterpretedName} under `options`.\n * @param options - Forwarded to {@link literalNameToInterpretedName}. Controls how the interpretation handles edge\n * cases. When `options.allowENSRootName` is `true`, an empty `name` is accepted and rendered via `children`; when\n * `false` (default), an empty `name` falls through to `malformed`. When `options.allowEncodedLabelHashes` is\n * `true`, a Label already formatted as an EncodedLabelHash is preserved verbatim; when `false` (default), such a\n * Label is treated like any other input and passed through normalization, which will fail and fall through to the\n * unnormalizable-Label handling. When `options.coerceUnnormalizedLabelsToNormalizedLabels` is `true` (default), an\n * unnormalized Label is passed through ENSIP-15 normalization (e.g. `\"Vitalik\"` → `\"vitalik\"`); when `false`, any\n * unnormalized Label causes `malformed` to be invoked — no normalization is attempted and\n * `coerceUnnormalizableLabelsToEncodedLabelHashes` is not consulted. When\n * `options.coerceUnnormalizableLabelsToEncodedLabelHashes` is `true`, a Label that cannot be normalized is replaced\n * with the EncodedLabelHash of its literal bytes and `coerced` is invoked; when `false` (default), encountering\n * such a Label causes `malformed` to be invoked. Only consulted when\n * `coerceUnnormalizedLabelsToNormalizedLabels` is `true`.\n */\nexport function EnsureInterpretedName({\n name,\n children,\n coerced,\n malformed,\n options,\n}: {\n name: LiteralName;\n children: InterpretedNameRenderer;\n coerced: InterpretedNameRenderer;\n malformed: MalformedNameRenderer;\n options?: Parameters<typeof literalNameToInterpretedName>[1];\n}) {\n // attempt to convert the LiteralName to an InterpretedName\n let interpreted: InterpretedName;\n try {\n interpreted = literalNameToInterpretedName(name, options);\n } catch {\n // this name can't conform to InterpretedName: it is malformed or contains unnormalizable Labels\n return malformed(name);\n }\n\n // from here, the name is either already interpreted or was coerced; check with string equality\n if ((name as string) !== (interpreted as string)) return coerced(interpreted);\n\n // the name was already interpreted, render the happy path\n return children(interpreted);\n}\n"],"mappings":";AAAA,SAAiD,oCAAoC;AA+B9E,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AAED,MAAI;AACJ,MAAI;AACF,kBAAc,6BAA6B,MAAM,OAAO;AAAA,EAC1D,QAAQ;AAEN,WAAO,UAAU,IAAI;AAAA,EACvB;AAGA,MAAK,SAAqB,YAAwB,QAAO,QAAQ,WAAW;AAG5E,SAAO,SAAS,WAAW;AAC7B;","names":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { introspection, OmnigraphScalars } from 'enssdk/omnigraph';
|
|
2
|
+
import { initGraphQLTada, TadaDocumentNode } from 'gql.tada';
|
|
3
|
+
export { FragmentOf, ResultOf, VariablesOf, readFragment } from 'gql.tada';
|
|
4
|
+
import { AnyVariables, OperationContext } from '@urql/core';
|
|
5
|
+
import { DocumentNode } from 'graphql';
|
|
6
|
+
import { UseQueryResponse } from 'urql';
|
|
7
|
+
import { EnsNodeClient } from 'enssdk/core';
|
|
8
|
+
import { ReactNode, ReactElement } from 'react';
|
|
9
|
+
|
|
10
|
+
declare const graphql: initGraphQLTada<{
|
|
11
|
+
introspection: typeof introspection;
|
|
12
|
+
scalars: Omit<OmnigraphScalars, "BigInt"> & {
|
|
13
|
+
BigInt: bigint;
|
|
14
|
+
};
|
|
15
|
+
}>;
|
|
16
|
+
|
|
17
|
+
type UseOmnigraphQueryArgs<Data = unknown, Variables extends AnyVariables = AnyVariables> = {
|
|
18
|
+
query: DocumentNode | TadaDocumentNode<Data, Variables> | string;
|
|
19
|
+
variables?: Variables;
|
|
20
|
+
pause?: boolean;
|
|
21
|
+
context?: Partial<OperationContext>;
|
|
22
|
+
};
|
|
23
|
+
type UseOmnigraphQueryResult<Data = unknown, Variables extends AnyVariables = AnyVariables> = UseQueryResponse<Data, Variables>;
|
|
24
|
+
declare function useOmnigraphQuery<Data = unknown, Variables extends AnyVariables = AnyVariables>(args: UseOmnigraphQueryArgs<Data, Variables>): UseOmnigraphQueryResult<Data, Variables>;
|
|
25
|
+
|
|
26
|
+
interface OmnigraphProviderProps {
|
|
27
|
+
client: EnsNodeClient;
|
|
28
|
+
children?: ReactNode;
|
|
29
|
+
}
|
|
30
|
+
declare function OmnigraphProvider({ client, children }: OmnigraphProviderProps): ReactElement;
|
|
31
|
+
|
|
32
|
+
export { OmnigraphProvider, type OmnigraphProviderProps, type UseOmnigraphQueryArgs, type UseOmnigraphQueryResult, graphql, useOmnigraphQuery };
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
// src/react/omnigraph/graphql.ts
|
|
2
|
+
import { initGraphQLTada } from "gql.tada";
|
|
3
|
+
import { readFragment } from "gql.tada";
|
|
4
|
+
var graphql = initGraphQLTada();
|
|
5
|
+
|
|
6
|
+
// src/react/omnigraph/hooks.ts
|
|
7
|
+
import { useQuery } from "urql";
|
|
8
|
+
function useOmnigraphQuery(args) {
|
|
9
|
+
return useQuery({
|
|
10
|
+
query: args.query,
|
|
11
|
+
variables: args.variables,
|
|
12
|
+
pause: args.pause,
|
|
13
|
+
context: args.context
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/react/omnigraph/provider.tsx
|
|
18
|
+
import { createElement, useMemo } from "react";
|
|
19
|
+
import { Provider } from "urql";
|
|
20
|
+
|
|
21
|
+
// src/react/omnigraph/client.ts
|
|
22
|
+
import { Client, fetchExchange } from "@urql/core";
|
|
23
|
+
|
|
24
|
+
// src/react/omnigraph/_lib/cache-exchange.ts
|
|
25
|
+
import { cacheExchange } from "@urql/exchange-graphcache";
|
|
26
|
+
import { stringifyAccountId } from "enssdk";
|
|
27
|
+
import { introspection } from "enssdk/omnigraph";
|
|
28
|
+
|
|
29
|
+
// src/react/omnigraph/_lib/by-id-lookup-resolvers.ts
|
|
30
|
+
import {
|
|
31
|
+
makePermissionsId,
|
|
32
|
+
makeRegistryId,
|
|
33
|
+
makeResolverId
|
|
34
|
+
} from "enssdk";
|
|
35
|
+
var passthrough = (args, cache, info) => cache.resolve(info.parentTypeName, info.fieldName, args);
|
|
36
|
+
var byIdLookupResolvers = {
|
|
37
|
+
Query: {
|
|
38
|
+
domain(parent, args, cache, info) {
|
|
39
|
+
const by = args.by;
|
|
40
|
+
if (by.id) {
|
|
41
|
+
const v1Key = cache.keyOfEntity({ __typename: "ENSv1Domain", id: by.id });
|
|
42
|
+
if (v1Key && cache.resolve(v1Key, "id")) return v1Key;
|
|
43
|
+
const v2Key = cache.keyOfEntity({ __typename: "ENSv2Domain", id: by.id });
|
|
44
|
+
if (v2Key && cache.resolve(v2Key, "id")) return v2Key;
|
|
45
|
+
}
|
|
46
|
+
return passthrough(args, cache, info);
|
|
47
|
+
},
|
|
48
|
+
account(parent, args, cache, info) {
|
|
49
|
+
const by = args.by;
|
|
50
|
+
if (by.id) return { __typename: "Account", id: by.id };
|
|
51
|
+
if (by.address) return { __typename: "Account", id: by.address };
|
|
52
|
+
return passthrough(args, cache, info);
|
|
53
|
+
},
|
|
54
|
+
registry(parent, args, cache, info) {
|
|
55
|
+
const by = args.by;
|
|
56
|
+
if (by.id) return { __typename: "Registry", id: by.id };
|
|
57
|
+
if (by.contract) return { __typename: "Registry", id: makeRegistryId(by.contract) };
|
|
58
|
+
return passthrough(args, cache, info);
|
|
59
|
+
},
|
|
60
|
+
resolver(parent, args, cache, info) {
|
|
61
|
+
const by = args.by;
|
|
62
|
+
if (by.id) return { __typename: "Resolver", id: by.id };
|
|
63
|
+
if (by.contract) return { __typename: "Resolver", id: makeResolverId(by.contract) };
|
|
64
|
+
return passthrough(args, cache, info);
|
|
65
|
+
},
|
|
66
|
+
permissions(parent, args, cache, info) {
|
|
67
|
+
const by = args.by;
|
|
68
|
+
if (by.id) return { __typename: "Permissions", id: by.id };
|
|
69
|
+
if (by.contract) return { __typename: "Permissions", id: makePermissionsId(by.contract) };
|
|
70
|
+
return passthrough(args, cache, info);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// src/react/omnigraph/_lib/introspection-helpers.ts
|
|
76
|
+
function unwrapType(type) {
|
|
77
|
+
return type.ofType ? unwrapType(type.ofType) : type;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// src/react/omnigraph/_lib/local-bigint-resolvers.ts
|
|
81
|
+
var toBigInt = (parent, args, cache, info) => {
|
|
82
|
+
const value = parent[info.fieldName];
|
|
83
|
+
if (value == null) return value;
|
|
84
|
+
return BigInt(value);
|
|
85
|
+
};
|
|
86
|
+
var toBigIntList = (parent, args, cache, info) => {
|
|
87
|
+
const value = parent[info.fieldName];
|
|
88
|
+
if (value == null) return value;
|
|
89
|
+
return value.map((v) => v == null ? v : BigInt(v));
|
|
90
|
+
};
|
|
91
|
+
function isBigIntType(type) {
|
|
92
|
+
return unwrapType(type).name === "BigInt";
|
|
93
|
+
}
|
|
94
|
+
function isListType(type) {
|
|
95
|
+
if (type.kind === "LIST") return true;
|
|
96
|
+
return type.ofType ? isListType(type.ofType) : false;
|
|
97
|
+
}
|
|
98
|
+
function localBigIntResolvers(schema) {
|
|
99
|
+
const resolvers = {};
|
|
100
|
+
for (const type of schema.__schema.types) {
|
|
101
|
+
if (type.kind !== "OBJECT" || type.name.startsWith("__")) continue;
|
|
102
|
+
for (const field of type.fields ?? []) {
|
|
103
|
+
if (!isBigIntType(field.type)) continue;
|
|
104
|
+
resolvers[type.name] ??= {};
|
|
105
|
+
resolvers[type.name][field.name] = isListType(field.type) ? toBigIntList : toBigInt;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return resolvers;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/react/omnigraph/_lib/local-connection-resolvers.ts
|
|
112
|
+
import { relayPagination } from "@urql/exchange-graphcache/extras";
|
|
113
|
+
function localConnectionResolvers(schema) {
|
|
114
|
+
const resolvers = {};
|
|
115
|
+
for (const type of schema.__schema.types) {
|
|
116
|
+
if (type.kind !== "OBJECT" || type.name.startsWith("__")) continue;
|
|
117
|
+
for (const field of type.fields ?? []) {
|
|
118
|
+
const leaf = unwrapType(field.type);
|
|
119
|
+
if (leaf.name?.endsWith("Connection")) {
|
|
120
|
+
resolvers[type.name] ??= {};
|
|
121
|
+
resolvers[type.name][field.name] = relayPagination();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return resolvers;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/react/omnigraph/_lib/merge-resolver-maps.ts
|
|
129
|
+
function mergeResolverMaps(...maps) {
|
|
130
|
+
const result = {};
|
|
131
|
+
for (const map of maps) {
|
|
132
|
+
for (const [typeName, fields] of Object.entries(map)) {
|
|
133
|
+
result[typeName] = { ...result[typeName], ...fields };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/react/omnigraph/_lib/cache-exchange.ts
|
|
140
|
+
var EMBEDDED_DATA = () => null;
|
|
141
|
+
var omnigraphCacheExchange = cacheExchange({
|
|
142
|
+
schema: introspection,
|
|
143
|
+
keys: {
|
|
144
|
+
// by default, all Entities are assumed to match the Relay spec, and graphcache treats
|
|
145
|
+
// them as keyable by `id`. if it encounters an Entity with no `id` field and no other
|
|
146
|
+
// special handling here in the cacheExchange.keys definitions, it will issue a warning.
|
|
147
|
+
// AccountIds are keyable by stringifying them
|
|
148
|
+
AccountId: (data) => {
|
|
149
|
+
if (!data.address) return null;
|
|
150
|
+
if (!data.chainId) return null;
|
|
151
|
+
return stringifyAccountId(data);
|
|
152
|
+
},
|
|
153
|
+
// These entities are Embedded Data and don't have a relevant key
|
|
154
|
+
Label: EMBEDDED_DATA,
|
|
155
|
+
WrappedBaseRegistrarRegistration: EMBEDDED_DATA
|
|
156
|
+
},
|
|
157
|
+
resolvers: mergeResolverMaps(
|
|
158
|
+
// produce relayPagination() local resolvers for each t.connection in the schema
|
|
159
|
+
localConnectionResolvers(introspection),
|
|
160
|
+
// produce local resolvers that parse BigInt scalar fields from cached strings into native bigint
|
|
161
|
+
localBigIntResolvers(introspection),
|
|
162
|
+
// produce local cache resolvers for the Query.entity(by: { }) lookups
|
|
163
|
+
byIdLookupResolvers
|
|
164
|
+
)
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// src/react/omnigraph/client.ts
|
|
168
|
+
function createOmnigraphUrqlClient(config) {
|
|
169
|
+
return new Client({
|
|
170
|
+
url: new URL("/api/omnigraph", config.url).href,
|
|
171
|
+
fetch: config.fetch,
|
|
172
|
+
exchanges: [omnigraphCacheExchange, fetchExchange]
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/react/omnigraph/provider.tsx
|
|
177
|
+
function OmnigraphProvider({ client, children }) {
|
|
178
|
+
const urqlClient = useMemo(() => createOmnigraphUrqlClient(client.config), [client]);
|
|
179
|
+
return createElement(Provider, { value: urqlClient }, children);
|
|
180
|
+
}
|
|
181
|
+
export {
|
|
182
|
+
OmnigraphProvider,
|
|
183
|
+
graphql,
|
|
184
|
+
readFragment,
|
|
185
|
+
useOmnigraphQuery
|
|
186
|
+
};
|
|
187
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/react/omnigraph/graphql.ts","../../../src/react/omnigraph/hooks.ts","../../../src/react/omnigraph/provider.tsx","../../../src/react/omnigraph/client.ts","../../../src/react/omnigraph/_lib/cache-exchange.ts","../../../src/react/omnigraph/_lib/by-id-lookup-resolvers.ts","../../../src/react/omnigraph/_lib/introspection-helpers.ts","../../../src/react/omnigraph/_lib/local-bigint-resolvers.ts","../../../src/react/omnigraph/_lib/local-connection-resolvers.ts","../../../src/react/omnigraph/_lib/merge-resolver-maps.ts"],"sourcesContent":["import type { introspection, OmnigraphScalars } from \"enssdk/omnigraph\";\nimport { initGraphQLTada } from \"gql.tada\";\n\nexport const graphql = initGraphQLTada<{\n introspection: typeof introspection;\n scalars: Omit<OmnigraphScalars, \"BigInt\"> & {\n // override the default Omnigraph Scalar definitions to include a deserialized BigInt (see cache-exchange.ts)\n BigInt: bigint;\n };\n}>();\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\n","\"use client\";\n\nimport type { AnyVariables, OperationContext } from \"@urql/core\";\nimport type { TadaDocumentNode } from \"gql.tada\";\nimport type { DocumentNode } from \"graphql\";\nimport { type UseQueryResponse, useQuery } from \"urql\";\n\nexport type UseOmnigraphQueryArgs<Data = unknown, Variables extends AnyVariables = AnyVariables> = {\n query: DocumentNode | TadaDocumentNode<Data, Variables> | string;\n variables?: Variables;\n pause?: boolean;\n context?: Partial<OperationContext>;\n};\n\nexport type UseOmnigraphQueryResult<\n Data = unknown,\n Variables extends AnyVariables = AnyVariables,\n> = UseQueryResponse<Data, Variables>;\n\nexport function useOmnigraphQuery<Data = unknown, Variables extends AnyVariables = AnyVariables>(\n args: UseOmnigraphQueryArgs<Data, Variables>,\n): UseOmnigraphQueryResult<Data, Variables> {\n return useQuery<Data, Variables>({\n query: args.query as DocumentNode,\n variables: args.variables as Variables,\n pause: args.pause,\n context: args.context,\n });\n}\n","\"use client\";\n\nimport type { EnsNodeClient } from \"enssdk/core\";\nimport { createElement, type ReactElement, type ReactNode, useMemo } from \"react\";\nimport { Provider } from \"urql\";\n\nimport { createOmnigraphUrqlClient } from \"./client\";\n\nexport interface OmnigraphProviderProps {\n client: EnsNodeClient;\n children?: ReactNode;\n}\n\nexport function OmnigraphProvider({ client, children }: OmnigraphProviderProps): ReactElement {\n const urqlClient = useMemo(() => createOmnigraphUrqlClient(client.config), [client]);\n\n return createElement(Provider, { value: urqlClient }, children);\n}\n","import { Client, fetchExchange } from \"@urql/core\";\nimport type { EnsNodeClientConfig } from \"enssdk/core\";\n\nimport { omnigraphCacheExchange } from \"./_lib/cache-exchange\";\n\nexport function createOmnigraphUrqlClient(config: EnsNodeClientConfig) {\n return new Client({\n url: new URL(\"/api/omnigraph\", config.url).href,\n fetch: config.fetch,\n exchanges: [omnigraphCacheExchange, fetchExchange],\n });\n}\n","import { cacheExchange } from \"@urql/exchange-graphcache\";\nimport type { AccountId } from \"enssdk\";\nimport { stringifyAccountId } from \"enssdk\";\nimport { introspection } from \"enssdk/omnigraph\";\n\nimport { byIdLookupResolvers } from \"./by-id-lookup-resolvers\";\nimport { localBigIntResolvers } from \"./local-bigint-resolvers\";\nimport { localConnectionResolvers } from \"./local-connection-resolvers\";\nimport { mergeResolverMaps } from \"./merge-resolver-maps\";\n\n/**\n * Entities without keys are 'Embedded Data', and we tell graphcache about them to avoid warnings\n * about the inability to normalize them.\n *\n * @see https://nearform.com/open-source/urql/docs/graphcache/normalized-caching/#custom-keys-and-non-keyable-entities\n */\nconst EMBEDDED_DATA = () => null;\n\nexport const omnigraphCacheExchange = cacheExchange({\n schema: introspection,\n keys: {\n // by default, all Entities are assumed to match the Relay spec, and graphcache treats\n // them as keyable by `id`. if it encounters an Entity with no `id` field and no other\n // special handling here in the cacheExchange.keys definitions, it will issue a warning.\n\n // AccountIds are keyable by stringifying them\n AccountId: (data) => {\n if (!data.address) return null;\n if (!data.chainId) return null;\n\n return stringifyAccountId(data as unknown as AccountId);\n },\n\n // These entities are Embedded Data and don't have a relevant key\n Label: EMBEDDED_DATA,\n WrappedBaseRegistrarRegistration: EMBEDDED_DATA,\n },\n resolvers: mergeResolverMaps(\n // produce relayPagination() local resolvers for each t.connection in the schema\n localConnectionResolvers(introspection),\n\n // produce local resolvers that parse BigInt scalar fields from cached strings into native bigint\n localBigIntResolvers(introspection),\n\n // produce local cache resolvers for the Query.entity(by: { }) lookups\n byIdLookupResolvers,\n ),\n});\n","import type { Cache, ResolveInfo, Resolver, Variables } from \"@urql/exchange-graphcache\";\nimport {\n type AccountId,\n type Address,\n makePermissionsId,\n makeRegistryId,\n makeResolverId,\n type PermissionsId,\n type RegistryId,\n type ResolverId,\n} from \"enssdk\";\n\n/**\n * This local resolver delegates to graphcache's built-in cache resolution with the full argument set,\n * effectively telling urql 'not found locally' and to fetch from the network.\n */\nconst passthrough = (args: Variables, cache: Cache, info: ResolveInfo) =>\n cache.resolve(info.parentTypeName, info.fieldName, args);\n\nexport const byIdLookupResolvers: Record<string, Record<string, Resolver>> = {\n Query: {\n domain(parent, args, cache, info) {\n const by = args.by as { id?: string; name?: string };\n\n if (by.id) {\n const v1Key = cache.keyOfEntity({ __typename: \"ENSv1Domain\", id: by.id });\n if (v1Key && cache.resolve(v1Key, \"id\")) return v1Key;\n\n const v2Key = cache.keyOfEntity({ __typename: \"ENSv2Domain\", id: by.id });\n if (v2Key && cache.resolve(v2Key, \"id\")) return v2Key;\n }\n\n return passthrough(args, cache, info);\n },\n account(parent, args, cache, info) {\n const by = args.by as { id?: Address; address?: Address };\n\n if (by.id) return { __typename: \"Account\", id: by.id };\n if (by.address) return { __typename: \"Account\", id: by.address };\n\n return passthrough(args, cache, info);\n },\n registry(parent, args, cache, info) {\n const by = args.by as { id?: RegistryId; contract?: AccountId };\n\n if (by.id) return { __typename: \"Registry\", id: by.id };\n if (by.contract) return { __typename: \"Registry\", id: makeRegistryId(by.contract) };\n\n return passthrough(args, cache, info);\n },\n resolver(parent, args, cache, info) {\n const by = args.by as { id?: ResolverId; contract?: AccountId };\n\n if (by.id) return { __typename: \"Resolver\", id: by.id };\n if (by.contract) return { __typename: \"Resolver\", id: makeResolverId(by.contract) };\n\n return passthrough(args, cache, info);\n },\n permissions(parent, args, cache, info) {\n const by = args.by as { id?: PermissionsId; contract?: AccountId };\n\n if (by.id) return { __typename: \"Permissions\", id: by.id };\n if (by.contract) return { __typename: \"Permissions\", id: makePermissionsId(by.contract) };\n\n return passthrough(args, cache, info);\n },\n },\n};\n","export interface IntrospectionTypeRef {\n readonly kind: string;\n readonly name?: string;\n readonly ofType?: IntrospectionTypeRef | null;\n}\n\nexport interface IntrospectionField {\n readonly name: string;\n readonly type: IntrospectionTypeRef;\n}\n\nexport interface IntrospectionType {\n readonly kind: string;\n readonly name: string;\n readonly fields?: readonly IntrospectionField[] | null;\n}\n\nexport interface IntrospectionSchema {\n readonly __schema: {\n readonly types: readonly IntrospectionType[];\n };\n}\n\nexport function unwrapType(type: IntrospectionTypeRef): IntrospectionTypeRef {\n return type.ofType ? unwrapType(type.ofType) : type;\n}\n","import type { Resolver, ScalarObject } from \"@urql/exchange-graphcache\";\n\nimport {\n type IntrospectionSchema,\n type IntrospectionTypeRef,\n unwrapType,\n} from \"./introspection-helpers\";\n\n// graphcache's ResolverResult type doesn't include bigint, but the value is stored\n// in the normalized cache and returned to the consumer as-is, so bigint works at runtime\n// the load-bearing piece of type inference is in packages/enskit/src/react/omnigraph/graphql.ts where\n// the GraphQL BigInt Scalar is mapped to the `bigint` primitive, which is only supported by these\n// runtime local resolvers.\nconst toBigInt: Resolver = (parent, args, cache, info) => {\n const value = parent[info.fieldName];\n if (value == null) return value;\n return BigInt(value as string) as unknown as ScalarObject;\n};\n\nconst toBigIntList: Resolver = (parent, args, cache, info) => {\n const value = parent[info.fieldName];\n if (value == null) return value;\n\n // now we know value is a (string | null)[], so map to a (bigint | null)[]\n return (value as readonly (string | null)[]).map((v) => (v == null ? v : BigInt(v)));\n};\n\nfunction isBigIntType(type: IntrospectionTypeRef) {\n return unwrapType(type).name === \"BigInt\";\n}\n\n// NOTE: the recursion is to handle not-null-wrapped lists\nfunction isListType(type: IntrospectionTypeRef): boolean {\n if (type.kind === \"LIST\") return true;\n return type.ofType ? isListType(type.ofType) : false;\n}\n\n/**\n * Derives local resolvers that parse BigInt scalar fields from cached strings into native bigint.\n */\nexport function localBigIntResolvers(\n schema: IntrospectionSchema,\n): Record<string, Record<string, Resolver>> {\n const resolvers: Record<string, Record<string, Resolver>> = {};\n\n for (const type of schema.__schema.types) {\n if (type.kind !== \"OBJECT\" || type.name.startsWith(\"__\")) continue;\n\n for (const field of type.fields ?? []) {\n if (!isBigIntType(field.type)) continue;\n\n resolvers[type.name] ??= {};\n resolvers[type.name][field.name] = isListType(field.type) ? toBigIntList : toBigInt;\n }\n }\n\n return resolvers;\n}\n","import type { Resolver } from \"@urql/exchange-graphcache\";\nimport { relayPagination } from \"@urql/exchange-graphcache/extras\";\n\nimport { type IntrospectionSchema, unwrapType } from \"./introspection-helpers\";\n\n/**\n * Derives `relayPagination()` local resolvers for all connection fields in the schema.\n */\nexport function localConnectionResolvers(\n schema: IntrospectionSchema,\n): Record<string, Record<string, Resolver>> {\n const resolvers: Record<string, Record<string, Resolver>> = {};\n\n for (const type of schema.__schema.types) {\n if (type.kind !== \"OBJECT\" || type.name.startsWith(\"__\")) continue;\n\n for (const field of type.fields ?? []) {\n const leaf = unwrapType(field.type);\n if (leaf.name?.endsWith(\"Connection\")) {\n resolvers[type.name] ??= {};\n resolvers[type.name][field.name] = relayPagination();\n }\n }\n }\n\n return resolvers;\n}\n","import type { Resolver } from \"@urql/exchange-graphcache\";\n\n/**\n * deep-merge resolver maps so types appearing in both get all their field resolvers\n */\nexport function mergeResolverMaps<RESOLVER extends Resolver>(\n ...maps: Record<string, Record<string, RESOLVER>>[]\n): Record<string, Record<string, RESOLVER>> {\n const result: Record<string, Record<string, RESOLVER>> = {};\n for (const map of maps) {\n for (const [typeName, fields] of Object.entries(map)) {\n result[typeName] = { ...result[typeName], ...fields };\n }\n }\n return result;\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,12 +1,66 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "enskit",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
3
|
+
"version": "1.10.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "The ENS toolkit for React applications",
|
|
6
|
+
"license": "MIT",
|
|
5
7
|
"repository": {
|
|
6
8
|
"type": "git",
|
|
7
|
-
"url": "https://github.com/namehash/ensnode.git",
|
|
9
|
+
"url": "git+https://github.com/namehash/ensnode.git",
|
|
8
10
|
"directory": "packages/enskit"
|
|
9
11
|
},
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
12
|
+
"homepage": "https://ensnode.io",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"ENS",
|
|
15
|
+
"ENSNode",
|
|
16
|
+
"React",
|
|
17
|
+
"Omnigraph"
|
|
18
|
+
],
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"exports": {
|
|
23
|
+
"./react": {
|
|
24
|
+
"types": "./dist/react/index.d.ts",
|
|
25
|
+
"default": "./dist/react/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./react/omnigraph": {
|
|
28
|
+
"types": "./dist/react/omnigraph/index.d.ts",
|
|
29
|
+
"default": "./dist/react/omnigraph/index.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"sideEffects": false,
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@urql/core": "^6.0.0",
|
|
38
|
+
"@urql/exchange-graphcache": "^9.0.0",
|
|
39
|
+
"urql": "^5.0.1",
|
|
40
|
+
"enssdk": "1.10.1"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"gql.tada": "^1.8.10",
|
|
44
|
+
"graphql": "^16",
|
|
45
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
46
|
+
"viem": "^2"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/react": "19.2.7",
|
|
50
|
+
"gql.tada": "^1.8.10",
|
|
51
|
+
"graphql": "^16.11.0",
|
|
52
|
+
"react": "19.2.1",
|
|
53
|
+
"tsup": "^8.3.6",
|
|
54
|
+
"typescript": "^5.7.3",
|
|
55
|
+
"viem": "^2.22.13",
|
|
56
|
+
"vitest": "^4.0.2",
|
|
57
|
+
"@ensnode/shared-configs": "1.10.1"
|
|
58
|
+
},
|
|
59
|
+
"scripts": {
|
|
60
|
+
"prepublish": "tsup",
|
|
61
|
+
"lint": "biome check --write .",
|
|
62
|
+
"lint:ci": "biome ci",
|
|
63
|
+
"test": "vitest",
|
|
64
|
+
"typecheck": "tsgo --noEmit"
|
|
65
|
+
}
|
|
66
|
+
}
|