@solana/rpc-graphql 2.0.0-experimental.21e994f
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 +20 -0
- package/README.md +63 -0
- package/dist/index.browser.cjs +78 -0
- package/dist/index.browser.cjs.map +1 -0
- package/dist/index.browser.js +76 -0
- package/dist/index.browser.js.map +1 -0
- package/dist/index.native.js +72 -0
- package/dist/index.native.js.map +1 -0
- package/dist/index.node.cjs +74 -0
- package/dist/index.node.cjs.map +1 -0
- package/dist/index.node.js +72 -0
- package/dist/index.node.js.map +1 -0
- package/dist/types/cache.d.ts +7 -0
- package/dist/types/context.d.ts +9 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/rpc.d.ts +13 -0
- package/package.json +100 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2018 Solana Labs, Inc
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# @solana/rpc-graphql
|
|
2
|
+
|
|
3
|
+
This package defines a GraphQL client resolver built on top of the
|
|
4
|
+
[Solana JSON-RPC](https://docs.solana.com/api/http).
|
|
5
|
+
|
|
6
|
+
# Solana & GraphQL
|
|
7
|
+
|
|
8
|
+
GraphQL is a query language for your API, and a server-side runtime for
|
|
9
|
+
executing queries using a type system you define for your data.
|
|
10
|
+
|
|
11
|
+
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/GraphQL_Logo.svg/1024px-GraphQL_Logo.svg.png?20161105194737" alt="graphql-icon" width="24" align="center"/> [**GraphQL**](https://graphql.org/learn/)
|
|
12
|
+
|
|
13
|
+
This library attempts to define a type system for Solana. With the proper
|
|
14
|
+
type system, developers can take advantage of the best features of GraphQL
|
|
15
|
+
to make interacting with Solana via RPC smoother, faster, more reliable,
|
|
16
|
+
and involve less code.
|
|
17
|
+
|
|
18
|
+
## Design
|
|
19
|
+
|
|
20
|
+
⚠️ **In Development:** The API's query/schema structure may change as the API
|
|
21
|
+
matures.
|
|
22
|
+
|
|
23
|
+
With the exception of many familiar RPC methods for obtaining information about
|
|
24
|
+
a validator or cluster, majority of Solana data required by various
|
|
25
|
+
applications revolves around two components:
|
|
26
|
+
|
|
27
|
+
- Accounts
|
|
28
|
+
- Blocks
|
|
29
|
+
|
|
30
|
+
One can add a third component found within a block:
|
|
31
|
+
|
|
32
|
+
- Transactions
|
|
33
|
+
|
|
34
|
+
With these three main components in mind, consider a GraphQL type system that
|
|
35
|
+
revolves around accounts, blocks, and transactions.
|
|
36
|
+
|
|
37
|
+
### Types
|
|
38
|
+
|
|
39
|
+
Coming soon!
|
|
40
|
+
|
|
41
|
+
#### Account
|
|
42
|
+
|
|
43
|
+
Coming soon!
|
|
44
|
+
|
|
45
|
+
### Queries
|
|
46
|
+
|
|
47
|
+
Coming soon!
|
|
48
|
+
|
|
49
|
+
#### Accounts
|
|
50
|
+
|
|
51
|
+
Coming soon!
|
|
52
|
+
|
|
53
|
+
#### Program Accounts
|
|
54
|
+
|
|
55
|
+
Coming soon!
|
|
56
|
+
|
|
57
|
+
#### Blocks
|
|
58
|
+
|
|
59
|
+
Coming soon!
|
|
60
|
+
|
|
61
|
+
#### Transactions
|
|
62
|
+
|
|
63
|
+
Coming soon!
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var graphql = require('graphql');
|
|
4
|
+
|
|
5
|
+
// src/rpc.ts
|
|
6
|
+
|
|
7
|
+
// src/cache.ts
|
|
8
|
+
var stringifyValue = (value) => JSON.stringify(value, (_, value2) => {
|
|
9
|
+
if (typeof value2 === "bigint") {
|
|
10
|
+
return value2.toString() + "n";
|
|
11
|
+
}
|
|
12
|
+
return value2;
|
|
13
|
+
});
|
|
14
|
+
var parseValue = (value) => JSON.parse(value, (_, value2) => {
|
|
15
|
+
if (typeof value2 === "string" && /\d+n$/.test(value2)) {
|
|
16
|
+
return BigInt(value2.slice(0, -1));
|
|
17
|
+
}
|
|
18
|
+
return value2;
|
|
19
|
+
});
|
|
20
|
+
var cacheKey = (key, variables) => `GraphQLCache:${stringifyValue(key)}:${stringifyValue(variables)}`;
|
|
21
|
+
function createGraphQLCache() {
|
|
22
|
+
return {
|
|
23
|
+
// Browser
|
|
24
|
+
flush: () => {
|
|
25
|
+
for (let i = localStorage.length - 1; i >= 0; i--) {
|
|
26
|
+
const storageKey = localStorage.key(i);
|
|
27
|
+
if (storageKey && storageKey.startsWith("GraphQLCache:")) {
|
|
28
|
+
localStorage.removeItem(storageKey);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
get: (key, variables) => {
|
|
33
|
+
const value = localStorage.getItem(cacheKey(key, variables));
|
|
34
|
+
return value === null ? null : parseValue(value);
|
|
35
|
+
},
|
|
36
|
+
insert: (key, variables, value) => {
|
|
37
|
+
localStorage.setItem(cacheKey(key, variables), stringifyValue(value));
|
|
38
|
+
}
|
|
39
|
+
} ;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/context.ts
|
|
43
|
+
function createSolanaGraphQLContext(rpc) {
|
|
44
|
+
const cache = createGraphQLCache();
|
|
45
|
+
return { cache, rpc };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/rpc.ts
|
|
49
|
+
function createRpcGraphQL(rpc) {
|
|
50
|
+
const context = createSolanaGraphQLContext(rpc);
|
|
51
|
+
const schema = new graphql.GraphQLSchema({
|
|
52
|
+
query: new graphql.GraphQLObjectType({
|
|
53
|
+
fields: {
|
|
54
|
+
/** Root queries */
|
|
55
|
+
},
|
|
56
|
+
name: "RootQuery"
|
|
57
|
+
}),
|
|
58
|
+
types: []
|
|
59
|
+
});
|
|
60
|
+
return {
|
|
61
|
+
context,
|
|
62
|
+
async query(source, variableValues) {
|
|
63
|
+
const result = await graphql.graphql({
|
|
64
|
+
contextValue: this.context,
|
|
65
|
+
schema: this.schema,
|
|
66
|
+
source,
|
|
67
|
+
variableValues
|
|
68
|
+
});
|
|
69
|
+
this.context.cache.flush();
|
|
70
|
+
return result;
|
|
71
|
+
},
|
|
72
|
+
schema
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
exports.createRpcGraphQL = createRpcGraphQL;
|
|
77
|
+
//# sourceMappingURL=out.js.map
|
|
78
|
+
//# sourceMappingURL=index.browser.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rpc.ts","../src/cache.ts","../src/context.ts"],"names":["value"],"mappings":";AAEA,SAAS,SAAS,mBAAmB,qBAA6B;;;ACOlE,IAAM,iBAAiB,CAAC,UACpB,KAAK,UAAU,OAAO,CAAC,GAAGA,WAAU;AAChC,MAAI,OAAOA,WAAU,UAAU;AAC3B,WAAOA,OAAM,SAAS,IAAI;AAAA,EAC9B;AACA,SAAOA;AACX,CAAC;AAEL,IAAM,aAAa,CAAC,UAChB,KAAK,MAAM,OAAO,CAAC,GAAGA,WAAU;AAC5B,MAAI,OAAOA,WAAU,YAAY,QAAQ,KAAKA,MAAK,GAAG;AAClD,WAAO,OAAOA,OAAM,MAAM,GAAG,EAAE,CAAC;AAAA,EACpC;AACA,SAAOA;AACX,CAAC;AAEL,IAAM,WAAW,CAAC,KAAsB,cACpC,gBAAgB,eAAe,GAAG,CAAC,IAAI,eAAe,SAAS,CAAC;AAE7D,SAAS,qBAAmC;AAC/C,SAAO,OACD;AAAA;AAAA,IAEI,OAAO,MAAM;AAET,eAAS,IAAI,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK;AAC/C,cAAM,aAAa,aAAa,IAAI,CAAC;AACrC,YAAI,cAAc,WAAW,WAAW,eAAe,GAAG;AACtD,uBAAa,WAAW,UAAU;AAAA,QACtC;AAAA,MACJ;AAAA,IACJ;AAAA,IACA,KAAK,CAAC,KAAK,cAAc;AACrB,YAAM,QAAQ,aAAa,QAAQ,SAAS,KAAK,SAAS,CAAC;AAC3D,aAAO,UAAU,OAAO,OAAO,WAAW,KAAK;AAAA,IACnD;AAAA,IACA,QAAQ,CAAC,KAAK,WAAW,UAAU;AAC/B,mBAAa,QAAQ,SAAS,KAAK,SAAS,GAAG,eAAe,KAAK,CAAC;AAAA,IACxE;AAAA,EACJ,IACA;AAAA;AAAA,IAEI,OAAO,MAAM;AACT,aAAO,KAAK,aAAa,EAAE,QAAQ,SAAO,OAAO,cAAc,GAAG,CAAC;AAAA,IACvE;AAAA,IACA,KAAK,CAAC,KAAK,cAAc;AACrB,YAAM,QAAQ,cAAc,SAAS,KAAK,SAAS,CAAC;AACpD,aAAO,UAAU,SAAY,OAAO,WAAW,KAAK;AAAA,IACxD;AAAA,IACA,QAAQ,CAAC,KAAK,WAAW,UAAU;AAC/B,oBAAc,SAAS,KAAK,SAAS,CAAC,IAAI,eAAe,KAAK;AAAA,IAClE;AAAA,EACJ;AACV;;;ACpDO,SAAS,2BAA2B,KAA+C;AACtF,QAAM,QAAQ,mBAAmB;AACjC,SAAO,EAAE,OAAO,IAAI;AACxB;;;AFEO,SAAS,iBAAiB,KAAwC;AACrE,QAAM,UAAU,2BAA2B,GAAG;AAC9C,QAAM,SAAS,IAAI,cAAc;AAAA,IAC7B,OAAO,IAAI,kBAAkB;AAAA,MACzB,QAAQ;AAAA;AAAA,MAER;AAAA,MACA,MAAM;AAAA,IACV,CAAC;AAAA,IACD,OAAO,CAAC;AAAA,EACZ,CAAC;AACD,SAAO;AAAA,IACH;AAAA,IACA,MAAM,MAAM,QAAyB,gBAA2D;AAC5F,YAAM,SAAS,MAAM,QAAQ;AAAA,QACzB,cAAc,KAAK;AAAA,QACnB,QAAQ,KAAK;AAAA,QACb;AAAA,QACA;AAAA,MACJ,CAAC;AACD,WAAK,QAAQ,MAAM,MAAM;AACzB,aAAO;AAAA,IACX;AAAA,IACA;AAAA,EACJ;AACJ","sourcesContent":["import { SolanaRpcMethods } from '@solana/rpc-core';\nimport { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\nimport { graphql, GraphQLObjectType, GraphQLSchema, Source } from 'graphql';\n\nimport { createSolanaGraphQLContext, RpcGraphQLContext } from './context';\n\nexport interface RpcGraphQL {\n context: RpcGraphQLContext;\n query(\n source: string | Source,\n variableValues?: { readonly [variable: string]: unknown }\n ): ReturnType<typeof graphql>;\n schema: GraphQLSchema;\n}\n\nexport function createRpcGraphQL(rpc: Rpc<SolanaRpcMethods>): RpcGraphQL {\n const context = createSolanaGraphQLContext(rpc);\n const schema = new GraphQLSchema({\n query: new GraphQLObjectType({\n fields: {\n /** Root queries */\n },\n name: 'RootQuery',\n }),\n types: [],\n });\n return {\n context,\n async query(source: string | Source, variableValues?: { readonly [variable: string]: unknown }) {\n const result = await graphql({\n contextValue: this.context,\n schema: this.schema,\n source,\n variableValues,\n });\n this.context.cache.flush();\n return result;\n },\n schema,\n };\n}\n","export interface GraphQLCache {\n flush(): void;\n get(key: string | bigint, variables: unknown): unknown | null;\n insert(key: string | bigint, variables: unknown, value: unknown): void;\n}\n\n// Basic in-memory cache for Node.js\nconst inMemoryCache: { [key: string]: string } = {};\n\nconst stringifyValue = (value: unknown) =>\n JSON.stringify(value, (_, value) => {\n if (typeof value === 'bigint') {\n return value.toString() + 'n';\n }\n return value;\n });\n\nconst parseValue = (value: string) =>\n JSON.parse(value, (_, value) => {\n if (typeof value === 'string' && /\\d+n$/.test(value)) {\n return BigInt(value.slice(0, -1));\n }\n return value;\n });\n\nconst cacheKey = (key: string | bigint, variables: unknown): string =>\n `GraphQLCache:${stringifyValue(key)}:${stringifyValue(variables)}`;\n\nexport function createGraphQLCache(): GraphQLCache {\n return __BROWSER__\n ? {\n // Browser\n flush: () => {\n // Clear all entries from the localStorage related to this cache\n for (let i = localStorage.length - 1; i >= 0; i--) {\n const storageKey = localStorage.key(i);\n if (storageKey && storageKey.startsWith('GraphQLCache:')) {\n localStorage.removeItem(storageKey);\n }\n }\n },\n get: (key, variables) => {\n const value = localStorage.getItem(cacheKey(key, variables));\n return value === null ? null : parseValue(value);\n },\n insert: (key, variables, value) => {\n localStorage.setItem(cacheKey(key, variables), stringifyValue(value));\n },\n }\n : {\n // Node.js\n flush: () => {\n Object.keys(inMemoryCache).forEach(key => delete inMemoryCache[key]);\n },\n get: (key, variables) => {\n const value = inMemoryCache[cacheKey(key, variables)];\n return value === undefined ? null : parseValue(value);\n },\n insert: (key, variables, value) => {\n inMemoryCache[cacheKey(key, variables)] = stringifyValue(value);\n },\n };\n}\n","import { SolanaRpcMethods } from '@solana/rpc-core';\nimport { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\n\nimport { createGraphQLCache, GraphQLCache } from './cache';\n\nexport interface RpcGraphQLContext {\n cache: GraphQLCache;\n rpc: Rpc<SolanaRpcMethods>;\n}\n\nexport function createSolanaGraphQLContext(rpc: Rpc<SolanaRpcMethods>): RpcGraphQLContext {\n const cache = createGraphQLCache();\n return { cache, rpc };\n}\n"]}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { GraphQLSchema, GraphQLObjectType, graphql } from 'graphql';
|
|
2
|
+
|
|
3
|
+
// src/rpc.ts
|
|
4
|
+
|
|
5
|
+
// src/cache.ts
|
|
6
|
+
var stringifyValue = (value) => JSON.stringify(value, (_, value2) => {
|
|
7
|
+
if (typeof value2 === "bigint") {
|
|
8
|
+
return value2.toString() + "n";
|
|
9
|
+
}
|
|
10
|
+
return value2;
|
|
11
|
+
});
|
|
12
|
+
var parseValue = (value) => JSON.parse(value, (_, value2) => {
|
|
13
|
+
if (typeof value2 === "string" && /\d+n$/.test(value2)) {
|
|
14
|
+
return BigInt(value2.slice(0, -1));
|
|
15
|
+
}
|
|
16
|
+
return value2;
|
|
17
|
+
});
|
|
18
|
+
var cacheKey = (key, variables) => `GraphQLCache:${stringifyValue(key)}:${stringifyValue(variables)}`;
|
|
19
|
+
function createGraphQLCache() {
|
|
20
|
+
return {
|
|
21
|
+
// Browser
|
|
22
|
+
flush: () => {
|
|
23
|
+
for (let i = localStorage.length - 1; i >= 0; i--) {
|
|
24
|
+
const storageKey = localStorage.key(i);
|
|
25
|
+
if (storageKey && storageKey.startsWith("GraphQLCache:")) {
|
|
26
|
+
localStorage.removeItem(storageKey);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
get: (key, variables) => {
|
|
31
|
+
const value = localStorage.getItem(cacheKey(key, variables));
|
|
32
|
+
return value === null ? null : parseValue(value);
|
|
33
|
+
},
|
|
34
|
+
insert: (key, variables, value) => {
|
|
35
|
+
localStorage.setItem(cacheKey(key, variables), stringifyValue(value));
|
|
36
|
+
}
|
|
37
|
+
} ;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/context.ts
|
|
41
|
+
function createSolanaGraphQLContext(rpc) {
|
|
42
|
+
const cache = createGraphQLCache();
|
|
43
|
+
return { cache, rpc };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/rpc.ts
|
|
47
|
+
function createRpcGraphQL(rpc) {
|
|
48
|
+
const context = createSolanaGraphQLContext(rpc);
|
|
49
|
+
const schema = new GraphQLSchema({
|
|
50
|
+
query: new GraphQLObjectType({
|
|
51
|
+
fields: {
|
|
52
|
+
/** Root queries */
|
|
53
|
+
},
|
|
54
|
+
name: "RootQuery"
|
|
55
|
+
}),
|
|
56
|
+
types: []
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
context,
|
|
60
|
+
async query(source, variableValues) {
|
|
61
|
+
const result = await graphql({
|
|
62
|
+
contextValue: this.context,
|
|
63
|
+
schema: this.schema,
|
|
64
|
+
source,
|
|
65
|
+
variableValues
|
|
66
|
+
});
|
|
67
|
+
this.context.cache.flush();
|
|
68
|
+
return result;
|
|
69
|
+
},
|
|
70
|
+
schema
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { createRpcGraphQL };
|
|
75
|
+
//# sourceMappingURL=out.js.map
|
|
76
|
+
//# sourceMappingURL=index.browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rpc.ts","../src/cache.ts","../src/context.ts"],"names":["value"],"mappings":";AAEA,SAAS,SAAS,mBAAmB,qBAA6B;;;ACOlE,IAAM,iBAAiB,CAAC,UACpB,KAAK,UAAU,OAAO,CAAC,GAAGA,WAAU;AAChC,MAAI,OAAOA,WAAU,UAAU;AAC3B,WAAOA,OAAM,SAAS,IAAI;AAAA,EAC9B;AACA,SAAOA;AACX,CAAC;AAEL,IAAM,aAAa,CAAC,UAChB,KAAK,MAAM,OAAO,CAAC,GAAGA,WAAU;AAC5B,MAAI,OAAOA,WAAU,YAAY,QAAQ,KAAKA,MAAK,GAAG;AAClD,WAAO,OAAOA,OAAM,MAAM,GAAG,EAAE,CAAC;AAAA,EACpC;AACA,SAAOA;AACX,CAAC;AAEL,IAAM,WAAW,CAAC,KAAsB,cACpC,gBAAgB,eAAe,GAAG,CAAC,IAAI,eAAe,SAAS,CAAC;AAE7D,SAAS,qBAAmC;AAC/C,SAAO,OACD;AAAA;AAAA,IAEI,OAAO,MAAM;AAET,eAAS,IAAI,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK;AAC/C,cAAM,aAAa,aAAa,IAAI,CAAC;AACrC,YAAI,cAAc,WAAW,WAAW,eAAe,GAAG;AACtD,uBAAa,WAAW,UAAU;AAAA,QACtC;AAAA,MACJ;AAAA,IACJ;AAAA,IACA,KAAK,CAAC,KAAK,cAAc;AACrB,YAAM,QAAQ,aAAa,QAAQ,SAAS,KAAK,SAAS,CAAC;AAC3D,aAAO,UAAU,OAAO,OAAO,WAAW,KAAK;AAAA,IACnD;AAAA,IACA,QAAQ,CAAC,KAAK,WAAW,UAAU;AAC/B,mBAAa,QAAQ,SAAS,KAAK,SAAS,GAAG,eAAe,KAAK,CAAC;AAAA,IACxE;AAAA,EACJ,IACA;AAAA;AAAA,IAEI,OAAO,MAAM;AACT,aAAO,KAAK,aAAa,EAAE,QAAQ,SAAO,OAAO,cAAc,GAAG,CAAC;AAAA,IACvE;AAAA,IACA,KAAK,CAAC,KAAK,cAAc;AACrB,YAAM,QAAQ,cAAc,SAAS,KAAK,SAAS,CAAC;AACpD,aAAO,UAAU,SAAY,OAAO,WAAW,KAAK;AAAA,IACxD;AAAA,IACA,QAAQ,CAAC,KAAK,WAAW,UAAU;AAC/B,oBAAc,SAAS,KAAK,SAAS,CAAC,IAAI,eAAe,KAAK;AAAA,IAClE;AAAA,EACJ;AACV;;;ACpDO,SAAS,2BAA2B,KAA+C;AACtF,QAAM,QAAQ,mBAAmB;AACjC,SAAO,EAAE,OAAO,IAAI;AACxB;;;AFEO,SAAS,iBAAiB,KAAwC;AACrE,QAAM,UAAU,2BAA2B,GAAG;AAC9C,QAAM,SAAS,IAAI,cAAc;AAAA,IAC7B,OAAO,IAAI,kBAAkB;AAAA,MACzB,QAAQ;AAAA;AAAA,MAER;AAAA,MACA,MAAM;AAAA,IACV,CAAC;AAAA,IACD,OAAO,CAAC;AAAA,EACZ,CAAC;AACD,SAAO;AAAA,IACH;AAAA,IACA,MAAM,MAAM,QAAyB,gBAA2D;AAC5F,YAAM,SAAS,MAAM,QAAQ;AAAA,QACzB,cAAc,KAAK;AAAA,QACnB,QAAQ,KAAK;AAAA,QACb;AAAA,QACA;AAAA,MACJ,CAAC;AACD,WAAK,QAAQ,MAAM,MAAM;AACzB,aAAO;AAAA,IACX;AAAA,IACA;AAAA,EACJ;AACJ","sourcesContent":["import { SolanaRpcMethods } from '@solana/rpc-core';\nimport { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\nimport { graphql, GraphQLObjectType, GraphQLSchema, Source } from 'graphql';\n\nimport { createSolanaGraphQLContext, RpcGraphQLContext } from './context';\n\nexport interface RpcGraphQL {\n context: RpcGraphQLContext;\n query(\n source: string | Source,\n variableValues?: { readonly [variable: string]: unknown }\n ): ReturnType<typeof graphql>;\n schema: GraphQLSchema;\n}\n\nexport function createRpcGraphQL(rpc: Rpc<SolanaRpcMethods>): RpcGraphQL {\n const context = createSolanaGraphQLContext(rpc);\n const schema = new GraphQLSchema({\n query: new GraphQLObjectType({\n fields: {\n /** Root queries */\n },\n name: 'RootQuery',\n }),\n types: [],\n });\n return {\n context,\n async query(source: string | Source, variableValues?: { readonly [variable: string]: unknown }) {\n const result = await graphql({\n contextValue: this.context,\n schema: this.schema,\n source,\n variableValues,\n });\n this.context.cache.flush();\n return result;\n },\n schema,\n };\n}\n","export interface GraphQLCache {\n flush(): void;\n get(key: string | bigint, variables: unknown): unknown | null;\n insert(key: string | bigint, variables: unknown, value: unknown): void;\n}\n\n// Basic in-memory cache for Node.js\nconst inMemoryCache: { [key: string]: string } = {};\n\nconst stringifyValue = (value: unknown) =>\n JSON.stringify(value, (_, value) => {\n if (typeof value === 'bigint') {\n return value.toString() + 'n';\n }\n return value;\n });\n\nconst parseValue = (value: string) =>\n JSON.parse(value, (_, value) => {\n if (typeof value === 'string' && /\\d+n$/.test(value)) {\n return BigInt(value.slice(0, -1));\n }\n return value;\n });\n\nconst cacheKey = (key: string | bigint, variables: unknown): string =>\n `GraphQLCache:${stringifyValue(key)}:${stringifyValue(variables)}`;\n\nexport function createGraphQLCache(): GraphQLCache {\n return __BROWSER__\n ? {\n // Browser\n flush: () => {\n // Clear all entries from the localStorage related to this cache\n for (let i = localStorage.length - 1; i >= 0; i--) {\n const storageKey = localStorage.key(i);\n if (storageKey && storageKey.startsWith('GraphQLCache:')) {\n localStorage.removeItem(storageKey);\n }\n }\n },\n get: (key, variables) => {\n const value = localStorage.getItem(cacheKey(key, variables));\n return value === null ? null : parseValue(value);\n },\n insert: (key, variables, value) => {\n localStorage.setItem(cacheKey(key, variables), stringifyValue(value));\n },\n }\n : {\n // Node.js\n flush: () => {\n Object.keys(inMemoryCache).forEach(key => delete inMemoryCache[key]);\n },\n get: (key, variables) => {\n const value = inMemoryCache[cacheKey(key, variables)];\n return value === undefined ? null : parseValue(value);\n },\n insert: (key, variables, value) => {\n inMemoryCache[cacheKey(key, variables)] = stringifyValue(value);\n },\n };\n}\n","import { SolanaRpcMethods } from '@solana/rpc-core';\nimport { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\n\nimport { createGraphQLCache, GraphQLCache } from './cache';\n\nexport interface RpcGraphQLContext {\n cache: GraphQLCache;\n rpc: Rpc<SolanaRpcMethods>;\n}\n\nexport function createSolanaGraphQLContext(rpc: Rpc<SolanaRpcMethods>): RpcGraphQLContext {\n const cache = createGraphQLCache();\n return { cache, rpc };\n}\n"]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { GraphQLSchema, GraphQLObjectType, graphql } from 'graphql';
|
|
2
|
+
|
|
3
|
+
// src/rpc.ts
|
|
4
|
+
|
|
5
|
+
// src/cache.ts
|
|
6
|
+
var inMemoryCache = {};
|
|
7
|
+
var stringifyValue = (value) => JSON.stringify(value, (_, value2) => {
|
|
8
|
+
if (typeof value2 === "bigint") {
|
|
9
|
+
return value2.toString() + "n";
|
|
10
|
+
}
|
|
11
|
+
return value2;
|
|
12
|
+
});
|
|
13
|
+
var parseValue = (value) => JSON.parse(value, (_, value2) => {
|
|
14
|
+
if (typeof value2 === "string" && /\d+n$/.test(value2)) {
|
|
15
|
+
return BigInt(value2.slice(0, -1));
|
|
16
|
+
}
|
|
17
|
+
return value2;
|
|
18
|
+
});
|
|
19
|
+
var cacheKey = (key, variables) => `GraphQLCache:${stringifyValue(key)}:${stringifyValue(variables)}`;
|
|
20
|
+
function createGraphQLCache() {
|
|
21
|
+
return {
|
|
22
|
+
// Node.js
|
|
23
|
+
flush: () => {
|
|
24
|
+
Object.keys(inMemoryCache).forEach((key) => delete inMemoryCache[key]);
|
|
25
|
+
},
|
|
26
|
+
get: (key, variables) => {
|
|
27
|
+
const value = inMemoryCache[cacheKey(key, variables)];
|
|
28
|
+
return value === void 0 ? null : parseValue(value);
|
|
29
|
+
},
|
|
30
|
+
insert: (key, variables, value) => {
|
|
31
|
+
inMemoryCache[cacheKey(key, variables)] = stringifyValue(value);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/context.ts
|
|
37
|
+
function createSolanaGraphQLContext(rpc) {
|
|
38
|
+
const cache = createGraphQLCache();
|
|
39
|
+
return { cache, rpc };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/rpc.ts
|
|
43
|
+
function createRpcGraphQL(rpc) {
|
|
44
|
+
const context = createSolanaGraphQLContext(rpc);
|
|
45
|
+
const schema = new GraphQLSchema({
|
|
46
|
+
query: new GraphQLObjectType({
|
|
47
|
+
fields: {
|
|
48
|
+
/** Root queries */
|
|
49
|
+
},
|
|
50
|
+
name: "RootQuery"
|
|
51
|
+
}),
|
|
52
|
+
types: []
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
context,
|
|
56
|
+
async query(source, variableValues) {
|
|
57
|
+
const result = await graphql({
|
|
58
|
+
contextValue: this.context,
|
|
59
|
+
schema: this.schema,
|
|
60
|
+
source,
|
|
61
|
+
variableValues
|
|
62
|
+
});
|
|
63
|
+
this.context.cache.flush();
|
|
64
|
+
return result;
|
|
65
|
+
},
|
|
66
|
+
schema
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export { createRpcGraphQL };
|
|
71
|
+
//# sourceMappingURL=out.js.map
|
|
72
|
+
//# sourceMappingURL=index.native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rpc.ts","../src/cache.ts","../src/context.ts"],"names":["value"],"mappings":";AAEA,SAAS,SAAS,mBAAmB,qBAA6B;;;ACKlE,IAAM,gBAA2C,CAAC;AAElD,IAAM,iBAAiB,CAAC,UACpB,KAAK,UAAU,OAAO,CAAC,GAAGA,WAAU;AAChC,MAAI,OAAOA,WAAU,UAAU;AAC3B,WAAOA,OAAM,SAAS,IAAI;AAAA,EAC9B;AACA,SAAOA;AACX,CAAC;AAEL,IAAM,aAAa,CAAC,UAChB,KAAK,MAAM,OAAO,CAAC,GAAGA,WAAU;AAC5B,MAAI,OAAOA,WAAU,YAAY,QAAQ,KAAKA,MAAK,GAAG;AAClD,WAAO,OAAOA,OAAM,MAAM,GAAG,EAAE,CAAC;AAAA,EACpC;AACA,SAAOA;AACX,CAAC;AAEL,IAAM,WAAW,CAAC,KAAsB,cACpC,gBAAgB,eAAe,GAAG,CAAC,IAAI,eAAe,SAAS,CAAC;AAE7D,SAAS,qBAAmC;AAC/C,SAAO,QACD;AAAA;AAAA,IAEI,OAAO,MAAM;AAET,eAAS,IAAI,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK;AAC/C,cAAM,aAAa,aAAa,IAAI,CAAC;AACrC,YAAI,cAAc,WAAW,WAAW,eAAe,GAAG;AACtD,uBAAa,WAAW,UAAU;AAAA,QACtC;AAAA,MACJ;AAAA,IACJ;AAAA,IACA,KAAK,CAAC,KAAK,cAAc;AACrB,YAAM,QAAQ,aAAa,QAAQ,SAAS,KAAK,SAAS,CAAC;AAC3D,aAAO,UAAU,OAAO,OAAO,WAAW,KAAK;AAAA,IACnD;AAAA,IACA,QAAQ,CAAC,KAAK,WAAW,UAAU;AAC/B,mBAAa,QAAQ,SAAS,KAAK,SAAS,GAAG,eAAe,KAAK,CAAC;AAAA,IACxE;AAAA,EACJ,IACA;AAAA;AAAA,IAEI,OAAO,MAAM;AACT,aAAO,KAAK,aAAa,EAAE,QAAQ,SAAO,OAAO,cAAc,GAAG,CAAC;AAAA,IACvE;AAAA,IACA,KAAK,CAAC,KAAK,cAAc;AACrB,YAAM,QAAQ,cAAc,SAAS,KAAK,SAAS,CAAC;AACpD,aAAO,UAAU,SAAY,OAAO,WAAW,KAAK;AAAA,IACxD;AAAA,IACA,QAAQ,CAAC,KAAK,WAAW,UAAU;AAC/B,oBAAc,SAAS,KAAK,SAAS,CAAC,IAAI,eAAe,KAAK;AAAA,IAClE;AAAA,EACJ;AACV;;;ACpDO,SAAS,2BAA2B,KAA+C;AACtF,QAAM,QAAQ,mBAAmB;AACjC,SAAO,EAAE,OAAO,IAAI;AACxB;;;AFEO,SAAS,iBAAiB,KAAwC;AACrE,QAAM,UAAU,2BAA2B,GAAG;AAC9C,QAAM,SAAS,IAAI,cAAc;AAAA,IAC7B,OAAO,IAAI,kBAAkB;AAAA,MACzB,QAAQ;AAAA;AAAA,MAER;AAAA,MACA,MAAM;AAAA,IACV,CAAC;AAAA,IACD,OAAO,CAAC;AAAA,EACZ,CAAC;AACD,SAAO;AAAA,IACH;AAAA,IACA,MAAM,MAAM,QAAyB,gBAA2D;AAC5F,YAAM,SAAS,MAAM,QAAQ;AAAA,QACzB,cAAc,KAAK;AAAA,QACnB,QAAQ,KAAK;AAAA,QACb;AAAA,QACA;AAAA,MACJ,CAAC;AACD,WAAK,QAAQ,MAAM,MAAM;AACzB,aAAO;AAAA,IACX;AAAA,IACA;AAAA,EACJ;AACJ","sourcesContent":["import { SolanaRpcMethods } from '@solana/rpc-core';\nimport { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\nimport { graphql, GraphQLObjectType, GraphQLSchema, Source } from 'graphql';\n\nimport { createSolanaGraphQLContext, RpcGraphQLContext } from './context';\n\nexport interface RpcGraphQL {\n context: RpcGraphQLContext;\n query(\n source: string | Source,\n variableValues?: { readonly [variable: string]: unknown }\n ): ReturnType<typeof graphql>;\n schema: GraphQLSchema;\n}\n\nexport function createRpcGraphQL(rpc: Rpc<SolanaRpcMethods>): RpcGraphQL {\n const context = createSolanaGraphQLContext(rpc);\n const schema = new GraphQLSchema({\n query: new GraphQLObjectType({\n fields: {\n /** Root queries */\n },\n name: 'RootQuery',\n }),\n types: [],\n });\n return {\n context,\n async query(source: string | Source, variableValues?: { readonly [variable: string]: unknown }) {\n const result = await graphql({\n contextValue: this.context,\n schema: this.schema,\n source,\n variableValues,\n });\n this.context.cache.flush();\n return result;\n },\n schema,\n };\n}\n","export interface GraphQLCache {\n flush(): void;\n get(key: string | bigint, variables: unknown): unknown | null;\n insert(key: string | bigint, variables: unknown, value: unknown): void;\n}\n\n// Basic in-memory cache for Node.js\nconst inMemoryCache: { [key: string]: string } = {};\n\nconst stringifyValue = (value: unknown) =>\n JSON.stringify(value, (_, value) => {\n if (typeof value === 'bigint') {\n return value.toString() + 'n';\n }\n return value;\n });\n\nconst parseValue = (value: string) =>\n JSON.parse(value, (_, value) => {\n if (typeof value === 'string' && /\\d+n$/.test(value)) {\n return BigInt(value.slice(0, -1));\n }\n return value;\n });\n\nconst cacheKey = (key: string | bigint, variables: unknown): string =>\n `GraphQLCache:${stringifyValue(key)}:${stringifyValue(variables)}`;\n\nexport function createGraphQLCache(): GraphQLCache {\n return __BROWSER__\n ? {\n // Browser\n flush: () => {\n // Clear all entries from the localStorage related to this cache\n for (let i = localStorage.length - 1; i >= 0; i--) {\n const storageKey = localStorage.key(i);\n if (storageKey && storageKey.startsWith('GraphQLCache:')) {\n localStorage.removeItem(storageKey);\n }\n }\n },\n get: (key, variables) => {\n const value = localStorage.getItem(cacheKey(key, variables));\n return value === null ? null : parseValue(value);\n },\n insert: (key, variables, value) => {\n localStorage.setItem(cacheKey(key, variables), stringifyValue(value));\n },\n }\n : {\n // Node.js\n flush: () => {\n Object.keys(inMemoryCache).forEach(key => delete inMemoryCache[key]);\n },\n get: (key, variables) => {\n const value = inMemoryCache[cacheKey(key, variables)];\n return value === undefined ? null : parseValue(value);\n },\n insert: (key, variables, value) => {\n inMemoryCache[cacheKey(key, variables)] = stringifyValue(value);\n },\n };\n}\n","import { SolanaRpcMethods } from '@solana/rpc-core';\nimport { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\n\nimport { createGraphQLCache, GraphQLCache } from './cache';\n\nexport interface RpcGraphQLContext {\n cache: GraphQLCache;\n rpc: Rpc<SolanaRpcMethods>;\n}\n\nexport function createSolanaGraphQLContext(rpc: Rpc<SolanaRpcMethods>): RpcGraphQLContext {\n const cache = createGraphQLCache();\n return { cache, rpc };\n}\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var graphql = require('graphql');
|
|
4
|
+
|
|
5
|
+
// src/rpc.ts
|
|
6
|
+
|
|
7
|
+
// src/cache.ts
|
|
8
|
+
var inMemoryCache = {};
|
|
9
|
+
var stringifyValue = (value) => JSON.stringify(value, (_, value2) => {
|
|
10
|
+
if (typeof value2 === "bigint") {
|
|
11
|
+
return value2.toString() + "n";
|
|
12
|
+
}
|
|
13
|
+
return value2;
|
|
14
|
+
});
|
|
15
|
+
var parseValue = (value) => JSON.parse(value, (_, value2) => {
|
|
16
|
+
if (typeof value2 === "string" && /\d+n$/.test(value2)) {
|
|
17
|
+
return BigInt(value2.slice(0, -1));
|
|
18
|
+
}
|
|
19
|
+
return value2;
|
|
20
|
+
});
|
|
21
|
+
var cacheKey = (key, variables) => `GraphQLCache:${stringifyValue(key)}:${stringifyValue(variables)}`;
|
|
22
|
+
function createGraphQLCache() {
|
|
23
|
+
return {
|
|
24
|
+
// Node.js
|
|
25
|
+
flush: () => {
|
|
26
|
+
Object.keys(inMemoryCache).forEach((key) => delete inMemoryCache[key]);
|
|
27
|
+
},
|
|
28
|
+
get: (key, variables) => {
|
|
29
|
+
const value = inMemoryCache[cacheKey(key, variables)];
|
|
30
|
+
return value === void 0 ? null : parseValue(value);
|
|
31
|
+
},
|
|
32
|
+
insert: (key, variables, value) => {
|
|
33
|
+
inMemoryCache[cacheKey(key, variables)] = stringifyValue(value);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/context.ts
|
|
39
|
+
function createSolanaGraphQLContext(rpc) {
|
|
40
|
+
const cache = createGraphQLCache();
|
|
41
|
+
return { cache, rpc };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/rpc.ts
|
|
45
|
+
function createRpcGraphQL(rpc) {
|
|
46
|
+
const context = createSolanaGraphQLContext(rpc);
|
|
47
|
+
const schema = new graphql.GraphQLSchema({
|
|
48
|
+
query: new graphql.GraphQLObjectType({
|
|
49
|
+
fields: {
|
|
50
|
+
/** Root queries */
|
|
51
|
+
},
|
|
52
|
+
name: "RootQuery"
|
|
53
|
+
}),
|
|
54
|
+
types: []
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
context,
|
|
58
|
+
async query(source, variableValues) {
|
|
59
|
+
const result = await graphql.graphql({
|
|
60
|
+
contextValue: this.context,
|
|
61
|
+
schema: this.schema,
|
|
62
|
+
source,
|
|
63
|
+
variableValues
|
|
64
|
+
});
|
|
65
|
+
this.context.cache.flush();
|
|
66
|
+
return result;
|
|
67
|
+
},
|
|
68
|
+
schema
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
exports.createRpcGraphQL = createRpcGraphQL;
|
|
73
|
+
//# sourceMappingURL=out.js.map
|
|
74
|
+
//# sourceMappingURL=index.node.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rpc.ts","../src/cache.ts","../src/context.ts"],"names":["value"],"mappings":";AAEA,SAAS,SAAS,mBAAmB,qBAA6B;;;ACKlE,IAAM,gBAA2C,CAAC;AAElD,IAAM,iBAAiB,CAAC,UACpB,KAAK,UAAU,OAAO,CAAC,GAAGA,WAAU;AAChC,MAAI,OAAOA,WAAU,UAAU;AAC3B,WAAOA,OAAM,SAAS,IAAI;AAAA,EAC9B;AACA,SAAOA;AACX,CAAC;AAEL,IAAM,aAAa,CAAC,UAChB,KAAK,MAAM,OAAO,CAAC,GAAGA,WAAU;AAC5B,MAAI,OAAOA,WAAU,YAAY,QAAQ,KAAKA,MAAK,GAAG;AAClD,WAAO,OAAOA,OAAM,MAAM,GAAG,EAAE,CAAC;AAAA,EACpC;AACA,SAAOA;AACX,CAAC;AAEL,IAAM,WAAW,CAAC,KAAsB,cACpC,gBAAgB,eAAe,GAAG,CAAC,IAAI,eAAe,SAAS,CAAC;AAE7D,SAAS,qBAAmC;AAC/C,SAAO,QACD;AAAA;AAAA,IAEI,OAAO,MAAM;AAET,eAAS,IAAI,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK;AAC/C,cAAM,aAAa,aAAa,IAAI,CAAC;AACrC,YAAI,cAAc,WAAW,WAAW,eAAe,GAAG;AACtD,uBAAa,WAAW,UAAU;AAAA,QACtC;AAAA,MACJ;AAAA,IACJ;AAAA,IACA,KAAK,CAAC,KAAK,cAAc;AACrB,YAAM,QAAQ,aAAa,QAAQ,SAAS,KAAK,SAAS,CAAC;AAC3D,aAAO,UAAU,OAAO,OAAO,WAAW,KAAK;AAAA,IACnD;AAAA,IACA,QAAQ,CAAC,KAAK,WAAW,UAAU;AAC/B,mBAAa,QAAQ,SAAS,KAAK,SAAS,GAAG,eAAe,KAAK,CAAC;AAAA,IACxE;AAAA,EACJ,IACA;AAAA;AAAA,IAEI,OAAO,MAAM;AACT,aAAO,KAAK,aAAa,EAAE,QAAQ,SAAO,OAAO,cAAc,GAAG,CAAC;AAAA,IACvE;AAAA,IACA,KAAK,CAAC,KAAK,cAAc;AACrB,YAAM,QAAQ,cAAc,SAAS,KAAK,SAAS,CAAC;AACpD,aAAO,UAAU,SAAY,OAAO,WAAW,KAAK;AAAA,IACxD;AAAA,IACA,QAAQ,CAAC,KAAK,WAAW,UAAU;AAC/B,oBAAc,SAAS,KAAK,SAAS,CAAC,IAAI,eAAe,KAAK;AAAA,IAClE;AAAA,EACJ;AACV;;;ACpDO,SAAS,2BAA2B,KAA+C;AACtF,QAAM,QAAQ,mBAAmB;AACjC,SAAO,EAAE,OAAO,IAAI;AACxB;;;AFEO,SAAS,iBAAiB,KAAwC;AACrE,QAAM,UAAU,2BAA2B,GAAG;AAC9C,QAAM,SAAS,IAAI,cAAc;AAAA,IAC7B,OAAO,IAAI,kBAAkB;AAAA,MACzB,QAAQ;AAAA;AAAA,MAER;AAAA,MACA,MAAM;AAAA,IACV,CAAC;AAAA,IACD,OAAO,CAAC;AAAA,EACZ,CAAC;AACD,SAAO;AAAA,IACH;AAAA,IACA,MAAM,MAAM,QAAyB,gBAA2D;AAC5F,YAAM,SAAS,MAAM,QAAQ;AAAA,QACzB,cAAc,KAAK;AAAA,QACnB,QAAQ,KAAK;AAAA,QACb;AAAA,QACA;AAAA,MACJ,CAAC;AACD,WAAK,QAAQ,MAAM,MAAM;AACzB,aAAO;AAAA,IACX;AAAA,IACA;AAAA,EACJ;AACJ","sourcesContent":["import { SolanaRpcMethods } from '@solana/rpc-core';\nimport { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\nimport { graphql, GraphQLObjectType, GraphQLSchema, Source } from 'graphql';\n\nimport { createSolanaGraphQLContext, RpcGraphQLContext } from './context';\n\nexport interface RpcGraphQL {\n context: RpcGraphQLContext;\n query(\n source: string | Source,\n variableValues?: { readonly [variable: string]: unknown }\n ): ReturnType<typeof graphql>;\n schema: GraphQLSchema;\n}\n\nexport function createRpcGraphQL(rpc: Rpc<SolanaRpcMethods>): RpcGraphQL {\n const context = createSolanaGraphQLContext(rpc);\n const schema = new GraphQLSchema({\n query: new GraphQLObjectType({\n fields: {\n /** Root queries */\n },\n name: 'RootQuery',\n }),\n types: [],\n });\n return {\n context,\n async query(source: string | Source, variableValues?: { readonly [variable: string]: unknown }) {\n const result = await graphql({\n contextValue: this.context,\n schema: this.schema,\n source,\n variableValues,\n });\n this.context.cache.flush();\n return result;\n },\n schema,\n };\n}\n","export interface GraphQLCache {\n flush(): void;\n get(key: string | bigint, variables: unknown): unknown | null;\n insert(key: string | bigint, variables: unknown, value: unknown): void;\n}\n\n// Basic in-memory cache for Node.js\nconst inMemoryCache: { [key: string]: string } = {};\n\nconst stringifyValue = (value: unknown) =>\n JSON.stringify(value, (_, value) => {\n if (typeof value === 'bigint') {\n return value.toString() + 'n';\n }\n return value;\n });\n\nconst parseValue = (value: string) =>\n JSON.parse(value, (_, value) => {\n if (typeof value === 'string' && /\\d+n$/.test(value)) {\n return BigInt(value.slice(0, -1));\n }\n return value;\n });\n\nconst cacheKey = (key: string | bigint, variables: unknown): string =>\n `GraphQLCache:${stringifyValue(key)}:${stringifyValue(variables)}`;\n\nexport function createGraphQLCache(): GraphQLCache {\n return __BROWSER__\n ? {\n // Browser\n flush: () => {\n // Clear all entries from the localStorage related to this cache\n for (let i = localStorage.length - 1; i >= 0; i--) {\n const storageKey = localStorage.key(i);\n if (storageKey && storageKey.startsWith('GraphQLCache:')) {\n localStorage.removeItem(storageKey);\n }\n }\n },\n get: (key, variables) => {\n const value = localStorage.getItem(cacheKey(key, variables));\n return value === null ? null : parseValue(value);\n },\n insert: (key, variables, value) => {\n localStorage.setItem(cacheKey(key, variables), stringifyValue(value));\n },\n }\n : {\n // Node.js\n flush: () => {\n Object.keys(inMemoryCache).forEach(key => delete inMemoryCache[key]);\n },\n get: (key, variables) => {\n const value = inMemoryCache[cacheKey(key, variables)];\n return value === undefined ? null : parseValue(value);\n },\n insert: (key, variables, value) => {\n inMemoryCache[cacheKey(key, variables)] = stringifyValue(value);\n },\n };\n}\n","import { SolanaRpcMethods } from '@solana/rpc-core';\nimport { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\n\nimport { createGraphQLCache, GraphQLCache } from './cache';\n\nexport interface RpcGraphQLContext {\n cache: GraphQLCache;\n rpc: Rpc<SolanaRpcMethods>;\n}\n\nexport function createSolanaGraphQLContext(rpc: Rpc<SolanaRpcMethods>): RpcGraphQLContext {\n const cache = createGraphQLCache();\n return { cache, rpc };\n}\n"]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { GraphQLSchema, GraphQLObjectType, graphql } from 'graphql';
|
|
2
|
+
|
|
3
|
+
// src/rpc.ts
|
|
4
|
+
|
|
5
|
+
// src/cache.ts
|
|
6
|
+
var inMemoryCache = {};
|
|
7
|
+
var stringifyValue = (value) => JSON.stringify(value, (_, value2) => {
|
|
8
|
+
if (typeof value2 === "bigint") {
|
|
9
|
+
return value2.toString() + "n";
|
|
10
|
+
}
|
|
11
|
+
return value2;
|
|
12
|
+
});
|
|
13
|
+
var parseValue = (value) => JSON.parse(value, (_, value2) => {
|
|
14
|
+
if (typeof value2 === "string" && /\d+n$/.test(value2)) {
|
|
15
|
+
return BigInt(value2.slice(0, -1));
|
|
16
|
+
}
|
|
17
|
+
return value2;
|
|
18
|
+
});
|
|
19
|
+
var cacheKey = (key, variables) => `GraphQLCache:${stringifyValue(key)}:${stringifyValue(variables)}`;
|
|
20
|
+
function createGraphQLCache() {
|
|
21
|
+
return {
|
|
22
|
+
// Node.js
|
|
23
|
+
flush: () => {
|
|
24
|
+
Object.keys(inMemoryCache).forEach((key) => delete inMemoryCache[key]);
|
|
25
|
+
},
|
|
26
|
+
get: (key, variables) => {
|
|
27
|
+
const value = inMemoryCache[cacheKey(key, variables)];
|
|
28
|
+
return value === void 0 ? null : parseValue(value);
|
|
29
|
+
},
|
|
30
|
+
insert: (key, variables, value) => {
|
|
31
|
+
inMemoryCache[cacheKey(key, variables)] = stringifyValue(value);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/context.ts
|
|
37
|
+
function createSolanaGraphQLContext(rpc) {
|
|
38
|
+
const cache = createGraphQLCache();
|
|
39
|
+
return { cache, rpc };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/rpc.ts
|
|
43
|
+
function createRpcGraphQL(rpc) {
|
|
44
|
+
const context = createSolanaGraphQLContext(rpc);
|
|
45
|
+
const schema = new GraphQLSchema({
|
|
46
|
+
query: new GraphQLObjectType({
|
|
47
|
+
fields: {
|
|
48
|
+
/** Root queries */
|
|
49
|
+
},
|
|
50
|
+
name: "RootQuery"
|
|
51
|
+
}),
|
|
52
|
+
types: []
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
context,
|
|
56
|
+
async query(source, variableValues) {
|
|
57
|
+
const result = await graphql({
|
|
58
|
+
contextValue: this.context,
|
|
59
|
+
schema: this.schema,
|
|
60
|
+
source,
|
|
61
|
+
variableValues
|
|
62
|
+
});
|
|
63
|
+
this.context.cache.flush();
|
|
64
|
+
return result;
|
|
65
|
+
},
|
|
66
|
+
schema
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export { createRpcGraphQL };
|
|
71
|
+
//# sourceMappingURL=out.js.map
|
|
72
|
+
//# sourceMappingURL=index.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rpc.ts","../src/cache.ts","../src/context.ts"],"names":["value"],"mappings":";AAEA,SAAS,SAAS,mBAAmB,qBAA6B;;;ACKlE,IAAM,gBAA2C,CAAC;AAElD,IAAM,iBAAiB,CAAC,UACpB,KAAK,UAAU,OAAO,CAAC,GAAGA,WAAU;AAChC,MAAI,OAAOA,WAAU,UAAU;AAC3B,WAAOA,OAAM,SAAS,IAAI;AAAA,EAC9B;AACA,SAAOA;AACX,CAAC;AAEL,IAAM,aAAa,CAAC,UAChB,KAAK,MAAM,OAAO,CAAC,GAAGA,WAAU;AAC5B,MAAI,OAAOA,WAAU,YAAY,QAAQ,KAAKA,MAAK,GAAG;AAClD,WAAO,OAAOA,OAAM,MAAM,GAAG,EAAE,CAAC;AAAA,EACpC;AACA,SAAOA;AACX,CAAC;AAEL,IAAM,WAAW,CAAC,KAAsB,cACpC,gBAAgB,eAAe,GAAG,CAAC,IAAI,eAAe,SAAS,CAAC;AAE7D,SAAS,qBAAmC;AAC/C,SAAO,QACD;AAAA;AAAA,IAEI,OAAO,MAAM;AAET,eAAS,IAAI,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK;AAC/C,cAAM,aAAa,aAAa,IAAI,CAAC;AACrC,YAAI,cAAc,WAAW,WAAW,eAAe,GAAG;AACtD,uBAAa,WAAW,UAAU;AAAA,QACtC;AAAA,MACJ;AAAA,IACJ;AAAA,IACA,KAAK,CAAC,KAAK,cAAc;AACrB,YAAM,QAAQ,aAAa,QAAQ,SAAS,KAAK,SAAS,CAAC;AAC3D,aAAO,UAAU,OAAO,OAAO,WAAW,KAAK;AAAA,IACnD;AAAA,IACA,QAAQ,CAAC,KAAK,WAAW,UAAU;AAC/B,mBAAa,QAAQ,SAAS,KAAK,SAAS,GAAG,eAAe,KAAK,CAAC;AAAA,IACxE;AAAA,EACJ,IACA;AAAA;AAAA,IAEI,OAAO,MAAM;AACT,aAAO,KAAK,aAAa,EAAE,QAAQ,SAAO,OAAO,cAAc,GAAG,CAAC;AAAA,IACvE;AAAA,IACA,KAAK,CAAC,KAAK,cAAc;AACrB,YAAM,QAAQ,cAAc,SAAS,KAAK,SAAS,CAAC;AACpD,aAAO,UAAU,SAAY,OAAO,WAAW,KAAK;AAAA,IACxD;AAAA,IACA,QAAQ,CAAC,KAAK,WAAW,UAAU;AAC/B,oBAAc,SAAS,KAAK,SAAS,CAAC,IAAI,eAAe,KAAK;AAAA,IAClE;AAAA,EACJ;AACV;;;ACpDO,SAAS,2BAA2B,KAA+C;AACtF,QAAM,QAAQ,mBAAmB;AACjC,SAAO,EAAE,OAAO,IAAI;AACxB;;;AFEO,SAAS,iBAAiB,KAAwC;AACrE,QAAM,UAAU,2BAA2B,GAAG;AAC9C,QAAM,SAAS,IAAI,cAAc;AAAA,IAC7B,OAAO,IAAI,kBAAkB;AAAA,MACzB,QAAQ;AAAA;AAAA,MAER;AAAA,MACA,MAAM;AAAA,IACV,CAAC;AAAA,IACD,OAAO,CAAC;AAAA,EACZ,CAAC;AACD,SAAO;AAAA,IACH;AAAA,IACA,MAAM,MAAM,QAAyB,gBAA2D;AAC5F,YAAM,SAAS,MAAM,QAAQ;AAAA,QACzB,cAAc,KAAK;AAAA,QACnB,QAAQ,KAAK;AAAA,QACb;AAAA,QACA;AAAA,MACJ,CAAC;AACD,WAAK,QAAQ,MAAM,MAAM;AACzB,aAAO;AAAA,IACX;AAAA,IACA;AAAA,EACJ;AACJ","sourcesContent":["import { SolanaRpcMethods } from '@solana/rpc-core';\nimport { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\nimport { graphql, GraphQLObjectType, GraphQLSchema, Source } from 'graphql';\n\nimport { createSolanaGraphQLContext, RpcGraphQLContext } from './context';\n\nexport interface RpcGraphQL {\n context: RpcGraphQLContext;\n query(\n source: string | Source,\n variableValues?: { readonly [variable: string]: unknown }\n ): ReturnType<typeof graphql>;\n schema: GraphQLSchema;\n}\n\nexport function createRpcGraphQL(rpc: Rpc<SolanaRpcMethods>): RpcGraphQL {\n const context = createSolanaGraphQLContext(rpc);\n const schema = new GraphQLSchema({\n query: new GraphQLObjectType({\n fields: {\n /** Root queries */\n },\n name: 'RootQuery',\n }),\n types: [],\n });\n return {\n context,\n async query(source: string | Source, variableValues?: { readonly [variable: string]: unknown }) {\n const result = await graphql({\n contextValue: this.context,\n schema: this.schema,\n source,\n variableValues,\n });\n this.context.cache.flush();\n return result;\n },\n schema,\n };\n}\n","export interface GraphQLCache {\n flush(): void;\n get(key: string | bigint, variables: unknown): unknown | null;\n insert(key: string | bigint, variables: unknown, value: unknown): void;\n}\n\n// Basic in-memory cache for Node.js\nconst inMemoryCache: { [key: string]: string } = {};\n\nconst stringifyValue = (value: unknown) =>\n JSON.stringify(value, (_, value) => {\n if (typeof value === 'bigint') {\n return value.toString() + 'n';\n }\n return value;\n });\n\nconst parseValue = (value: string) =>\n JSON.parse(value, (_, value) => {\n if (typeof value === 'string' && /\\d+n$/.test(value)) {\n return BigInt(value.slice(0, -1));\n }\n return value;\n });\n\nconst cacheKey = (key: string | bigint, variables: unknown): string =>\n `GraphQLCache:${stringifyValue(key)}:${stringifyValue(variables)}`;\n\nexport function createGraphQLCache(): GraphQLCache {\n return __BROWSER__\n ? {\n // Browser\n flush: () => {\n // Clear all entries from the localStorage related to this cache\n for (let i = localStorage.length - 1; i >= 0; i--) {\n const storageKey = localStorage.key(i);\n if (storageKey && storageKey.startsWith('GraphQLCache:')) {\n localStorage.removeItem(storageKey);\n }\n }\n },\n get: (key, variables) => {\n const value = localStorage.getItem(cacheKey(key, variables));\n return value === null ? null : parseValue(value);\n },\n insert: (key, variables, value) => {\n localStorage.setItem(cacheKey(key, variables), stringifyValue(value));\n },\n }\n : {\n // Node.js\n flush: () => {\n Object.keys(inMemoryCache).forEach(key => delete inMemoryCache[key]);\n },\n get: (key, variables) => {\n const value = inMemoryCache[cacheKey(key, variables)];\n return value === undefined ? null : parseValue(value);\n },\n insert: (key, variables, value) => {\n inMemoryCache[cacheKey(key, variables)] = stringifyValue(value);\n },\n };\n}\n","import { SolanaRpcMethods } from '@solana/rpc-core';\nimport { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\n\nimport { createGraphQLCache, GraphQLCache } from './cache';\n\nexport interface RpcGraphQLContext {\n cache: GraphQLCache;\n rpc: Rpc<SolanaRpcMethods>;\n}\n\nexport function createSolanaGraphQLContext(rpc: Rpc<SolanaRpcMethods>): RpcGraphQLContext {\n const cache = createGraphQLCache();\n return { cache, rpc };\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface GraphQLCache {
|
|
2
|
+
flush(): void;
|
|
3
|
+
get(key: string | bigint, variables: unknown): unknown | null;
|
|
4
|
+
insert(key: string | bigint, variables: unknown, value: unknown): void;
|
|
5
|
+
}
|
|
6
|
+
export declare function createGraphQLCache(): GraphQLCache;
|
|
7
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SolanaRpcMethods } from '@solana/rpc-core';
|
|
2
|
+
import { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';
|
|
3
|
+
import { GraphQLCache } from './cache';
|
|
4
|
+
export interface RpcGraphQLContext {
|
|
5
|
+
cache: GraphQLCache;
|
|
6
|
+
rpc: Rpc<SolanaRpcMethods>;
|
|
7
|
+
}
|
|
8
|
+
export declare function createSolanaGraphQLContext(rpc: Rpc<SolanaRpcMethods>): RpcGraphQLContext;
|
|
9
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SolanaRpcMethods } from '@solana/rpc-core';
|
|
2
|
+
import { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';
|
|
3
|
+
import { graphql, GraphQLSchema, Source } from 'graphql';
|
|
4
|
+
import { RpcGraphQLContext } from './context';
|
|
5
|
+
export interface RpcGraphQL {
|
|
6
|
+
context: RpcGraphQLContext;
|
|
7
|
+
query(source: string | Source, variableValues?: {
|
|
8
|
+
readonly [variable: string]: unknown;
|
|
9
|
+
}): ReturnType<typeof graphql>;
|
|
10
|
+
schema: GraphQLSchema;
|
|
11
|
+
}
|
|
12
|
+
export declare function createRpcGraphQL(rpc: Rpc<SolanaRpcMethods>): RpcGraphQL;
|
|
13
|
+
//# sourceMappingURL=rpc.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@solana/rpc-graphql",
|
|
3
|
+
"version": "2.0.0-experimental.21e994f",
|
|
4
|
+
"description": "A library for resolving GraphQl query calls to the Solana JSON RPC API",
|
|
5
|
+
"exports": {
|
|
6
|
+
"browser": {
|
|
7
|
+
"import": "./dist/index.browser.js",
|
|
8
|
+
"require": "./dist/index.browser.cjs"
|
|
9
|
+
},
|
|
10
|
+
"node": {
|
|
11
|
+
"import": "./dist/index.node.js",
|
|
12
|
+
"require": "./dist/index.node.cjs"
|
|
13
|
+
},
|
|
14
|
+
"react-native": "./dist/index.native.js",
|
|
15
|
+
"types": "./dist/types/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"browser": {
|
|
18
|
+
"./dist/index.node.cjs": "./dist/index.browser.cjs",
|
|
19
|
+
"./dist/index.node.js": "./dist/index.browser.js"
|
|
20
|
+
},
|
|
21
|
+
"main": "./dist/index.node.cjs",
|
|
22
|
+
"module": "./dist/index.node.js",
|
|
23
|
+
"react-native": "./dist/index.native.js",
|
|
24
|
+
"types": "./dist/types/index.d.ts",
|
|
25
|
+
"type": "module",
|
|
26
|
+
"files": [
|
|
27
|
+
"./dist/"
|
|
28
|
+
],
|
|
29
|
+
"sideEffects": false,
|
|
30
|
+
"keywords": [
|
|
31
|
+
"blockchain",
|
|
32
|
+
"solana",
|
|
33
|
+
"web3"
|
|
34
|
+
],
|
|
35
|
+
"author": "Solana Labs Maintainers <maintainers@solanalabs.com>",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/solana-labs/solana-web3.js"
|
|
40
|
+
},
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "http://github.com/solana-labs/solana-web3.js/issues"
|
|
43
|
+
},
|
|
44
|
+
"browserslist": [
|
|
45
|
+
"supports bigint and not dead",
|
|
46
|
+
"maintained node versions"
|
|
47
|
+
],
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"graphql": "^16.8.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@solana/eslint-config-solana": "^1.0.2",
|
|
53
|
+
"@swc/jest": "^0.2.28",
|
|
54
|
+
"@types/jest": "^29.5.3",
|
|
55
|
+
"@typescript-eslint/eslint-plugin": "^6.3.0",
|
|
56
|
+
"@typescript-eslint/parser": "^6.3.0",
|
|
57
|
+
"agadoo": "^3.0.0",
|
|
58
|
+
"eslint": "^8.45.0",
|
|
59
|
+
"eslint-plugin-jest": "^27.2.3",
|
|
60
|
+
"eslint-plugin-sort-keys-fix": "^1.1.2",
|
|
61
|
+
"jest": "^29.6.1",
|
|
62
|
+
"jest-environment-jsdom": "^29.6.2",
|
|
63
|
+
"jest-fetch-mock-fork": "^3.0.4",
|
|
64
|
+
"jest-runner-eslint": "^2.1.0",
|
|
65
|
+
"jest-runner-prettier": "^1.0.0",
|
|
66
|
+
"prettier": "^2.8",
|
|
67
|
+
"tsup": "7.2.0",
|
|
68
|
+
"typescript": "^5.1.6",
|
|
69
|
+
"version-from-git": "^1.1.1",
|
|
70
|
+
"build-scripts": "0.0.0",
|
|
71
|
+
"test-config": "0.0.0",
|
|
72
|
+
"tsconfig": "0.0.0",
|
|
73
|
+
"@solana/addresses": "2.0.0-experimental.21e994f",
|
|
74
|
+
"@solana/rpc-core": "2.0.0-experimental.21e994f",
|
|
75
|
+
"@solana/rpc-transport": "2.0.0-experimental.21e994f"
|
|
76
|
+
},
|
|
77
|
+
"bundlewatch": {
|
|
78
|
+
"defaultCompression": "gzip",
|
|
79
|
+
"files": [
|
|
80
|
+
{
|
|
81
|
+
"path": "./dist/index*.js"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
"scripts": {
|
|
86
|
+
"compile:js": "tsup --config build-scripts/tsup.config.package.ts",
|
|
87
|
+
"compile:typedefs": "tsc -p ./tsconfig.declarations.json",
|
|
88
|
+
"dev": "jest -c node_modules/test-config/jest-dev.config.ts --globalSetup test-config/test-validator-setup.js --globalTeardown test-config/test-validator-teardown.js --rootDir . --watch",
|
|
89
|
+
"publish-packages": "pnpm publish --tag experimental --access public --no-git-checks",
|
|
90
|
+
"style:fix": "pnpm eslint --fix src/* && pnpm prettier -w src/*",
|
|
91
|
+
"test:lint": "jest -c node_modules/test-config/jest-lint.config.ts --rootDir . --silent",
|
|
92
|
+
"test:prettier": "jest -c node_modules/test-config/jest-prettier.config.ts --rootDir . --silent",
|
|
93
|
+
"test:treeshakability:browser": "agadoo dist/index.browser.js",
|
|
94
|
+
"test:treeshakability:native": "agadoo dist/index.native.js",
|
|
95
|
+
"test:treeshakability:node": "agadoo dist/index.node.js",
|
|
96
|
+
"test:typecheck": "tsc --noEmit",
|
|
97
|
+
"test:unit:browser": "jest -c node_modules/test-config/jest-unit.config.browser.ts --globalSetup test-config/test-validator-setup.js --globalTeardown test-config/test-validator-teardown.js --rootDir . --silent --passWithNoTests",
|
|
98
|
+
"test:unit:node": "jest -c node_modules/test-config/jest-unit.config.node.ts --globalSetup test-config/test-validator-setup.js --globalTeardown test-config/test-validator-teardown.js --rootDir . --silent --passWithNoTests"
|
|
99
|
+
}
|
|
100
|
+
}
|