@codex-data/sdk 2.4.2 → 2.4.3

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.
Files changed (2) hide show
  1. package/dist/edge.mjs +157 -1
  2. package/package.json +5 -3
package/dist/edge.mjs CHANGED
@@ -1 +1,157 @@
1
- export { createClient, createEdgeClient, DEFAULT_EDGE_URL, withEdge, } from "./sdk/edge";
1
+ // src/sdk/edge.ts
2
+ import {
3
+ createClient
4
+ } from "graphql-ws";
5
+
6
+ // src/sdk/edgeSubscription.ts
7
+ import { getOperationAST, Kind, parse, valueFromASTUntyped } from "graphql";
8
+ var SOLANA_NETWORK_ID = 1399811149;
9
+ var SUPPORTED_OPERATIONS = /* @__PURE__ */ new Set([
10
+ "onEventsCreated",
11
+ "onTokenEventsCreated",
12
+ "onBarsUpdated",
13
+ "onTokenBarsUpdated"
14
+ ]);
15
+ function assertEdgeSubscription(payload) {
16
+ function fail() {
17
+ throw new Error(
18
+ "useEdge requires a supported Solana subscription with commitmentLevel including Processed"
19
+ );
20
+ }
21
+ const document = parse(payload.query);
22
+ const operation = getOperationAST(document, payload.operationName);
23
+ if (!operation || operation.operation !== "subscription") fail();
24
+ const selections = operation.selectionSet.selections;
25
+ if (selections.length !== 1) fail();
26
+ const field = selections[0];
27
+ if (field.kind !== Kind.FIELD || !SUPPORTED_OPERATIONS.has(field.name.value))
28
+ fail();
29
+ if (field.directives?.length) fail();
30
+ const variables = { ...payload.variables };
31
+ for (const definition of operation.variableDefinitions ?? []) {
32
+ const name = definition.variable.name.value;
33
+ if (variables[name] === void 0 && definition.defaultValue !== void 0) {
34
+ variables[name] = valueFromASTUntyped(definition.defaultValue);
35
+ }
36
+ }
37
+ const args = Object.fromEntries(
38
+ (field.arguments ?? []).map((argument) => [
39
+ argument.name.value,
40
+ valueFromASTUntyped(argument.value, variables)
41
+ ])
42
+ );
43
+ const levels = Array.isArray(args.commitmentLevel) ? args.commitmentLevel : [args.commitmentLevel];
44
+ if (!levels.includes("Processed") || [...levels].some(
45
+ (level) => level !== "Processed" && level !== "Confirmed" && level !== "Preprocessed"
46
+ ))
47
+ fail();
48
+ const networks = [];
49
+ const collect = (value) => {
50
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
51
+ for (const [name, item] of Object.entries(value)) {
52
+ if (name === "networkId" && item != null) networks.push(item);
53
+ if (["id", "pairId", "tokenId"].includes(name) && item != null) {
54
+ if (typeof item !== "string" || !/^[^:]+:\d+$/.test(item)) fail();
55
+ networks.push(Number(item.slice(item.lastIndexOf(":") + 1)));
56
+ }
57
+ if (name === "input") collect(item);
58
+ }
59
+ };
60
+ collect(args);
61
+ if (!networks.length || networks.some((network) => network !== SOLANA_NETWORK_ID))
62
+ fail();
63
+ if (field.name.value === "onBarsUpdated" && args.quoteToken == null) {
64
+ throw new Error("useEdge onBarsUpdated requires an explicit quoteToken");
65
+ }
66
+ }
67
+
68
+ // src/sdk/edge.ts
69
+ var DEFAULT_EDGE_URL = "wss://fra.edge.codex.io/graphql";
70
+ function createEdgeClient(options) {
71
+ return createClient({ ...options, url: options.url ?? DEFAULT_EDGE_URL });
72
+ }
73
+ function prepareEdgeSubscription(payload, replacer) {
74
+ const snapshot = JSON.parse(
75
+ JSON.stringify(payload, replacer)
76
+ );
77
+ assertEdgeSubscription(snapshot);
78
+ return snapshot;
79
+ }
80
+ function withEdge(main, options) {
81
+ const { edgeUrl = DEFAULT_EDGE_URL, ...wsOptions } = options;
82
+ const mainHandlers = /* @__PURE__ */ new Set();
83
+ const edgeHandlers = new Set(
84
+ wsOptions.on ? [wsOptions.on] : []
85
+ );
86
+ const handlersFor = (useEdge) => {
87
+ const handlers = () => Array.from(useEdge ? edgeHandlers : mainHandlers);
88
+ return {
89
+ connecting: (...args) => handlers().forEach((on) => on?.connecting?.(...args)),
90
+ opened: (...args) => handlers().forEach((on) => on?.opened?.(...args)),
91
+ connected: (...args) => handlers().forEach((on) => on?.connected?.(...args)),
92
+ ping: (...args) => handlers().forEach((on) => on?.ping?.(...args)),
93
+ pong: (...args) => handlers().forEach((on) => on?.pong?.(...args)),
94
+ message: (...args) => handlers().forEach((on) => on?.message?.(...args)),
95
+ closed: (...args) => handlers().forEach((on) => on?.closed?.(...args)),
96
+ error: (...args) => handlers().forEach((on) => on?.error?.(...args))
97
+ };
98
+ };
99
+ const mainEvents = handlersFor(false);
100
+ main.on("connecting", mainEvents.connecting);
101
+ main.on("opened", mainEvents.opened);
102
+ main.on("connected", mainEvents.connected);
103
+ main.on("ping", mainEvents.ping);
104
+ main.on("pong", mainEvents.pong);
105
+ main.on("message", mainEvents.message);
106
+ main.on("closed", mainEvents.closed);
107
+ main.on("error", mainEvents.error);
108
+ let edge;
109
+ let disposed = false;
110
+ return {
111
+ ...main,
112
+ on: (event, listener, subscriptionOptions = {}) => {
113
+ const handlers = { [event]: listener };
114
+ if (subscriptionOptions.useEdge !== true) mainHandlers.add(handlers);
115
+ if (subscriptionOptions.useEdge !== false) edgeHandlers.add(handlers);
116
+ return () => {
117
+ mainHandlers.delete(handlers);
118
+ edgeHandlers.delete(handlers);
119
+ };
120
+ },
121
+ subscribe: (payload, sink, subscriptionOptions = {}) => {
122
+ if (disposed) throw new Error("Edge client has been disposed");
123
+ if (!subscriptionOptions.useEdge) return main.subscribe(payload, sink);
124
+ const snapshot = prepareEdgeSubscription(
125
+ payload,
126
+ wsOptions.jsonMessageReplacer
127
+ );
128
+ if (!edge) {
129
+ let subscriptionMessage = false;
130
+ edge = createEdgeClient({
131
+ ...wsOptions,
132
+ url: edgeUrl,
133
+ on: handlersFor(true),
134
+ jsonMessageReplacer: function(key, value) {
135
+ if (key === "") subscriptionMessage = value?.type === "subscribe";
136
+ return subscriptionMessage ? value : wsOptions.jsonMessageReplacer ? wsOptions.jsonMessageReplacer.call(this, key, value) : value;
137
+ }
138
+ });
139
+ }
140
+ return edge.subscribe(snapshot, sink);
141
+ },
142
+ terminate: () => {
143
+ main.terminate();
144
+ edge?.terminate();
145
+ },
146
+ dispose: async () => {
147
+ disposed = true;
148
+ await Promise.all([main.dispose(), edge?.dispose()]);
149
+ }
150
+ };
151
+ }
152
+ export {
153
+ DEFAULT_EDGE_URL,
154
+ createClient,
155
+ createEdgeClient,
156
+ withEdge
157
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codex-data/sdk",
3
- "version": "2.4.2",
3
+ "version": "2.4.3",
4
4
  "engines": {
5
5
  "node": ">=17.5.0"
6
6
  },
@@ -25,10 +25,11 @@
25
25
  "prebuild": "pnpm run clean && pnpm run generate:configs",
26
26
  "clean": "rm -rf dist dist-esm",
27
27
  "build": "pnpm run copy:schema && pnpm run generate:graphql && pnpm run build:sdk && pnpm run codegen && pnpm run lint ./src/sdk --fix && pnpm run build:types",
28
- "build:types": "pnpm run build:cjs && pnpm run build:esm && pnpm run build:rename-esm",
28
+ "build:types": "pnpm run build:cjs && pnpm run build:esm && pnpm run build:rename-esm && pnpm run build:edge",
29
29
  "build:cjs": "tsc",
30
30
  "build:esm": "tsc -p tsconfig.esm.json",
31
31
  "build:rename-esm": "find dist-esm -name '*.js' -exec sh -c 'mv \"$1\" \"${1%.js}.mjs\"' _ {} \\; && cp -r dist-esm/* dist/ && rm -rf dist-esm",
32
+ "build:edge": "esbuild src/edge.ts --bundle --format=esm --platform=neutral --packages=external --target=es2020 --outfile=dist/edge.mjs",
32
33
  "fetch:schema": "curl -s https://graph.codex.io/schema/latest.graphql --output src/resources/schema.graphql && cp src/resources/schema.graphql schema.graphql",
33
34
  "copy:schema": "cp src/resources/schema.graphql schema.graphql",
34
35
  "schema:diff": "tsx src/scripts/schemaDiff.ts",
@@ -37,7 +38,7 @@
37
38
  "build:sdk": "tsx src/scripts/buildSdk.ts",
38
39
  "codegen": "graphql-codegen --config codegen.ts",
39
40
  "lint": "eslint --ext .ts src",
40
- "test": "jest",
41
+ "test": "pnpm run build:types && jest",
41
42
  "format": "prettier --write .",
42
43
  "prepublishOnly": "pnpm run build",
43
44
  "publish:beta": "pnpm publish --tag beta --access public",
@@ -92,6 +93,7 @@
92
93
  "chalk": "^4.1.2",
93
94
  "cli-spinners": "^2.9.2",
94
95
  "dotenv": "^16.4.5",
96
+ "esbuild": "^0.25.12",
95
97
  "eslint": "^8.50.0",
96
98
  "eslint-config-prettier": "^9.0.0",
97
99
  "eslint-plugin-import": "^2.28.1",