@powerhousedao/reactor-api 1.21.2 → 1.22.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/dist/index.d.ts +8 -503
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -27020
- package/dist/src/processors/analytics-processor.d.ts +9 -0
- package/dist/src/processors/analytics-processor.d.ts.map +1 -0
- package/dist/src/processors/analytics-processor.js +9 -0
- package/dist/src/processors/index.d.ts +5 -0
- package/dist/src/processors/index.d.ts.map +1 -0
- package/dist/src/processors/index.js +4 -0
- package/dist/src/processors/manager.d.ts +14 -0
- package/dist/src/processors/manager.d.ts.map +1 -0
- package/dist/src/processors/manager.js +40 -0
- package/dist/src/processors/operational-processor.d.ts +8 -0
- package/dist/src/processors/operational-processor.d.ts.map +1 -0
- package/dist/src/processors/operational-processor.js +12 -0
- package/dist/src/processors/processor.d.ts +20 -0
- package/dist/src/processors/processor.d.ts.map +1 -0
- package/dist/src/processors/processor.js +45 -0
- package/dist/src/server.d.ts +18 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +51 -0
- package/dist/src/subgraphs/analytics/index.d.ts +16 -0
- package/dist/src/subgraphs/analytics/index.d.ts.map +1 -0
- package/dist/src/subgraphs/analytics/index.js +85 -0
- package/dist/src/subgraphs/auth/env/getters.d.ts +3 -0
- package/dist/src/subgraphs/auth/env/getters.d.ts.map +1 -0
- package/dist/src/subgraphs/auth/env/getters.js +26 -0
- package/dist/src/subgraphs/auth/env/index.d.ts +8 -0
- package/dist/src/subgraphs/auth/env/index.d.ts.map +1 -0
- package/{src/subgraphs/auth/env/index.ts → dist/src/subgraphs/auth/env/index.js} +4 -6
- package/dist/src/subgraphs/auth/index.d.ts +11 -0
- package/dist/src/subgraphs/auth/index.d.ts.map +1 -0
- package/dist/src/subgraphs/auth/index.js +259 -0
- package/dist/src/subgraphs/auth/types.d.ts +35 -0
- package/dist/src/subgraphs/auth/types.d.ts.map +1 -0
- package/dist/src/subgraphs/auth/types.js +1 -0
- package/dist/src/subgraphs/auth/utils/helpers.d.ts +12 -0
- package/dist/src/subgraphs/auth/utils/helpers.d.ts.map +1 -0
- package/dist/src/subgraphs/auth/utils/helpers.js +100 -0
- package/dist/src/subgraphs/auth/utils/session.d.ts +22 -0
- package/dist/src/subgraphs/auth/utils/session.d.ts.map +1 -0
- package/dist/src/subgraphs/auth/utils/session.js +100 -0
- package/dist/src/subgraphs/auth/utils/user.d.ts +12 -0
- package/dist/src/subgraphs/auth/utils/user.d.ts.map +1 -0
- package/dist/src/subgraphs/auth/utils/user.js +26 -0
- package/dist/src/subgraphs/base/index.d.ts +16 -0
- package/dist/src/subgraphs/base/index.d.ts.map +1 -0
- package/dist/src/subgraphs/base/index.js +25 -0
- package/dist/src/subgraphs/drive/index.d.ts +11 -0
- package/dist/src/subgraphs/drive/index.d.ts.map +1 -0
- package/dist/src/subgraphs/drive/index.js +341 -0
- package/dist/src/subgraphs/drive/temp-hack-rwa-type-defs.d.ts +57 -0
- package/dist/src/subgraphs/drive/temp-hack-rwa-type-defs.d.ts.map +1 -0
- package/dist/src/subgraphs/drive/temp-hack-rwa-type-defs.js +1 -0
- package/dist/src/subgraphs/index.d.ts +10 -0
- package/dist/src/subgraphs/index.d.ts.map +1 -0
- package/dist/src/subgraphs/index.js +20 -0
- package/dist/src/subgraphs/manager.d.ts +23 -0
- package/dist/src/subgraphs/manager.d.ts.map +1 -0
- package/dist/src/subgraphs/manager.js +102 -0
- package/dist/src/subgraphs/system/env/getters.d.ts +2 -0
- package/dist/src/subgraphs/system/env/getters.d.ts.map +1 -0
- package/dist/src/subgraphs/system/env/getters.js +3 -0
- package/dist/src/subgraphs/system/env/index.d.ts +2 -0
- package/dist/src/subgraphs/system/env/index.d.ts.map +1 -0
- package/{src/subgraphs/system/env/index.ts → dist/src/subgraphs/system/env/index.js} +1 -3
- package/dist/src/subgraphs/system/index.d.ts +19 -0
- package/dist/src/subgraphs/system/index.d.ts.map +1 -0
- package/dist/src/subgraphs/system/index.js +63 -0
- package/dist/src/subgraphs/system/types.d.ts +5 -0
- package/dist/src/subgraphs/system/types.d.ts.map +1 -0
- package/dist/src/subgraphs/system/types.js +1 -0
- package/dist/src/subgraphs/types.d.ts +27 -0
- package/dist/src/subgraphs/types.d.ts.map +1 -0
- package/dist/src/subgraphs/types.js +1 -0
- package/dist/src/sync/utils.d.ts +13 -0
- package/dist/src/sync/utils.d.ts.map +1 -0
- package/dist/src/sync/utils.js +37 -0
- package/dist/src/types.d.ts +29 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +1 -0
- package/dist/src/utils/create-schema.d.ts +7 -0
- package/dist/src/utils/create-schema.d.ts.map +1 -0
- package/dist/src/utils/create-schema.js +122 -0
- package/dist/src/utils/db.d.ts +4 -0
- package/dist/src/utils/db.d.ts.map +1 -0
- package/dist/src/utils/db.js +20 -0
- package/dist/src/utils/index.d.ts +3 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +24 -0
- package/package.json +18 -9
- package/CHANGELOG.md +0 -39
- package/dist/index.js.map +0 -1
- package/src/index.ts +0 -7
- package/src/processors/analytics-processor.ts +0 -18
- package/src/processors/index.ts +0 -4
- package/src/processors/manager.ts +0 -75
- package/src/processors/operational-processor.ts +0 -20
- package/src/processors/processor.ts +0 -75
- package/src/server.ts +0 -65
- package/src/subgraphs/analytics/index.ts +0 -119
- package/src/subgraphs/auth/env/getters.ts +0 -30
- package/src/subgraphs/auth/index.ts +0 -321
- package/src/subgraphs/auth/types.ts +0 -39
- package/src/subgraphs/auth/utils/helpers.ts +0 -132
- package/src/subgraphs/auth/utils/session.ts +0 -144
- package/src/subgraphs/auth/utils/user.ts +0 -40
- package/src/subgraphs/base/index.ts +0 -34
- package/src/subgraphs/drive/index.ts +0 -434
- package/src/subgraphs/drive/temp-hack-rwa-type-defs.ts +0 -39
- package/src/subgraphs/index.ts +0 -24
- package/src/subgraphs/manager.ts +0 -128
- package/src/subgraphs/system/env/getters.ts +0 -7
- package/src/subgraphs/system/index.ts +0 -73
- package/src/subgraphs/system/types.ts +0 -5
- package/src/subgraphs/types.ts +0 -29
- package/src/sync/utils.ts +0 -85
- package/src/types.ts +0 -43
- package/src/utils/create-schema.ts +0 -160
- package/src/utils/db.ts +0 -26
- package/src/utils/index.ts +0 -2
- package/test/benchmarks/load.bench.ts +0 -78
- package/test/benchmarks/sync.bench.ts +0 -151
- package/test/data/BlocktowerAndromeda.zip +0 -0
- package/test/router.test.ts +0 -48
- package/tsconfig.json +0 -21
- package/tsdoc.json +0 -3
- package/tsup.config.ts +0 -17
- package/types.d.ts +0 -5
- package/vitest.config.ts +0 -28
|
@@ -1,434 +0,0 @@
|
|
|
1
|
-
import { GraphQLResolverMap } from "@apollo/subgraph/dist/schema-helper";
|
|
2
|
-
import { pascalCase } from "change-case";
|
|
3
|
-
import {
|
|
4
|
-
generateUUID,
|
|
5
|
-
ListenerRevision,
|
|
6
|
-
StrandUpdateGraphQL,
|
|
7
|
-
} from "document-drive";
|
|
8
|
-
import {
|
|
9
|
-
actions,
|
|
10
|
-
FileNode,
|
|
11
|
-
Listener,
|
|
12
|
-
ListenerFilter,
|
|
13
|
-
TransmitterType,
|
|
14
|
-
} from "document-model-libs/document-drive";
|
|
15
|
-
import { Document, Operation } from "document-model/document";
|
|
16
|
-
import {
|
|
17
|
-
DocumentModelInput,
|
|
18
|
-
DocumentModelState,
|
|
19
|
-
} from "document-model/document-model";
|
|
20
|
-
import { gql } from "graphql-tag";
|
|
21
|
-
import {
|
|
22
|
-
InternalStrandUpdate,
|
|
23
|
-
processAcknowledge,
|
|
24
|
-
processGetStrands,
|
|
25
|
-
processPushUpdate,
|
|
26
|
-
} from "src/sync/utils";
|
|
27
|
-
import { Subgraph } from "../base";
|
|
28
|
-
import { Context, SubgraphArgs } from "../types";
|
|
29
|
-
import { Asset } from "./temp-hack-rwa-type-defs";
|
|
30
|
-
|
|
31
|
-
const ENABLE_SYNC_DEBUG = false;
|
|
32
|
-
|
|
33
|
-
const driveKindTypeNames: Record<string, string> = {
|
|
34
|
-
file: "DocumentDrive_FileNode",
|
|
35
|
-
folder: "DocumentDrive_FolderNode",
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export class DriveSubgraph extends Subgraph {
|
|
39
|
-
private debugID = `[DSG #${Math.floor(Math.random() * 999)}]`;
|
|
40
|
-
|
|
41
|
-
constructor(args: SubgraphArgs) {
|
|
42
|
-
super(args);
|
|
43
|
-
this.debugLog(`constructor()`);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
private debugLog(...data: any[]) {
|
|
47
|
-
if (!ENABLE_SYNC_DEBUG) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (data.length > 0 && typeof data[0] === "string") {
|
|
52
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
53
|
-
console.log(`${this.debugID} ${data[0]}`, ...data.slice(1));
|
|
54
|
-
} else {
|
|
55
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
56
|
-
console.log(this.debugID, ...data);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
name = "d/:drive";
|
|
61
|
-
typeDefs = gql`
|
|
62
|
-
type Query {
|
|
63
|
-
system: System
|
|
64
|
-
drive: DocumentDrive_DocumentDriveState
|
|
65
|
-
document(id: String!): IDocument
|
|
66
|
-
documents: [String!]!
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
type Mutation {
|
|
70
|
-
registerPullResponderListener(
|
|
71
|
-
filter: InputListenerFilter!
|
|
72
|
-
): DocumentDrive_Listener
|
|
73
|
-
pushUpdates(strands: [InputStrandUpdate!]): [ListenerRevision!]!
|
|
74
|
-
acknowledge(
|
|
75
|
-
listenerId: String!
|
|
76
|
-
revisions: [ListenerRevisionInput]
|
|
77
|
-
): Boolean
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
input InputOperationSignerUser {
|
|
81
|
-
address: String!
|
|
82
|
-
networkId: String!
|
|
83
|
-
chainId: Int!
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
type OperationSignerUser {
|
|
87
|
-
address: String!
|
|
88
|
-
networkId: String!
|
|
89
|
-
chainId: Int!
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
input InputOperationSignerApp {
|
|
93
|
-
name: String!
|
|
94
|
-
key: String!
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
type OperationSignerApp {
|
|
98
|
-
name: String!
|
|
99
|
-
key: String!
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
type OperationSigner {
|
|
103
|
-
app: OperationSignerApp
|
|
104
|
-
user: OperationSignerUser
|
|
105
|
-
signatures: [[String!]]!
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
input InputOperationSigner {
|
|
109
|
-
app: InputOperationSignerApp
|
|
110
|
-
user: InputOperationSignerUser
|
|
111
|
-
signatures: [[String!]]!
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
type OperationContext {
|
|
115
|
-
signer: OperationSigner
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
input InputOperationContext {
|
|
119
|
-
signer: InputOperationSigner
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
input InputOperationUpdate {
|
|
123
|
-
index: Int!
|
|
124
|
-
skip: Int
|
|
125
|
-
type: String!
|
|
126
|
-
id: String!
|
|
127
|
-
input: String!
|
|
128
|
-
hash: String!
|
|
129
|
-
timestamp: String!
|
|
130
|
-
error: String
|
|
131
|
-
context: InputOperationContext
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
type OperationUpdate {
|
|
135
|
-
index: Int!
|
|
136
|
-
skip: Int
|
|
137
|
-
type: String!
|
|
138
|
-
id: String!
|
|
139
|
-
input: String!
|
|
140
|
-
hash: String!
|
|
141
|
-
timestamp: String!
|
|
142
|
-
error: String
|
|
143
|
-
context: OperationContext
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
type StrandUpdate {
|
|
147
|
-
driveId: String!
|
|
148
|
-
documentId: String!
|
|
149
|
-
scope: String!
|
|
150
|
-
branch: String!
|
|
151
|
-
operations: [OperationUpdate!]!
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
input InputStrandUpdate {
|
|
155
|
-
driveId: String!
|
|
156
|
-
documentId: String!
|
|
157
|
-
scope: String!
|
|
158
|
-
branch: String!
|
|
159
|
-
operations: [InputOperationUpdate!]!
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
input InputListenerFilter {
|
|
163
|
-
documentType: [String!]
|
|
164
|
-
documentId: [String!]
|
|
165
|
-
scope: [String!]
|
|
166
|
-
branch: [String!]
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
enum UpdateStatus {
|
|
170
|
-
SUCCESS
|
|
171
|
-
MISSING
|
|
172
|
-
CONFLICT
|
|
173
|
-
ERROR
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
input ListenerRevisionInput {
|
|
177
|
-
driveId: String!
|
|
178
|
-
documentId: String!
|
|
179
|
-
scope: String!
|
|
180
|
-
branch: String!
|
|
181
|
-
status: UpdateStatus!
|
|
182
|
-
revision: Int!
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
type ListenerRevision {
|
|
186
|
-
driveId: String!
|
|
187
|
-
documentId: String!
|
|
188
|
-
scope: String!
|
|
189
|
-
branch: String!
|
|
190
|
-
status: UpdateStatus!
|
|
191
|
-
revision: Int!
|
|
192
|
-
error: String
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
type System {
|
|
196
|
-
sync: Sync
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
type Sync {
|
|
200
|
-
strands(listenerId: ID!, since: String): [StrandUpdate!]!
|
|
201
|
-
}
|
|
202
|
-
`;
|
|
203
|
-
|
|
204
|
-
resolvers: GraphQLResolverMap<Context> = {
|
|
205
|
-
Asset: {
|
|
206
|
-
__resolveType: (obj: Asset) => {
|
|
207
|
-
return obj.type;
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
Node: {
|
|
211
|
-
__resolveType: (obj: FileNode) => {
|
|
212
|
-
return obj.documentType ? "FileNode" : "FolderNode";
|
|
213
|
-
},
|
|
214
|
-
},
|
|
215
|
-
Document: {
|
|
216
|
-
operations: async (
|
|
217
|
-
obj: Document,
|
|
218
|
-
{ first, skip }: { first: number; skip: number },
|
|
219
|
-
ctx: Context,
|
|
220
|
-
) => {
|
|
221
|
-
const limit = first ?? 0;
|
|
222
|
-
const start = skip ?? 0;
|
|
223
|
-
return obj.operations.global.slice(start, start + limit);
|
|
224
|
-
},
|
|
225
|
-
},
|
|
226
|
-
Query: {
|
|
227
|
-
drive: async (_: unknown, args: unknown, ctx: Context) => {
|
|
228
|
-
this.debugLog(`drive()`, args);
|
|
229
|
-
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
230
|
-
const drive = await this.reactor.getDrive(ctx.driveId);
|
|
231
|
-
return {
|
|
232
|
-
...drive.state.global,
|
|
233
|
-
nodes: drive.state.global.nodes.map((n) => ({
|
|
234
|
-
...n,
|
|
235
|
-
__typename: driveKindTypeNames[n.kind] || "UnkownDriveNode",
|
|
236
|
-
})),
|
|
237
|
-
};
|
|
238
|
-
},
|
|
239
|
-
documents: async (_: unknown, args: unknown, ctx: Context) => {
|
|
240
|
-
this.debugLog(`documents(drive: ${ctx.driveId})`, args);
|
|
241
|
-
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
242
|
-
const documents = await this.reactor.getDocuments(ctx.driveId);
|
|
243
|
-
return documents;
|
|
244
|
-
},
|
|
245
|
-
document: async (_: unknown, { id }: { id: string }, ctx: Context) => {
|
|
246
|
-
this.debugLog(`document(drive: ${ctx.driveId}, id: ${id})`);
|
|
247
|
-
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
248
|
-
const document = await this.reactor.getDocument(ctx.driveId, id);
|
|
249
|
-
|
|
250
|
-
const dms = this.reactor.getDocumentModels();
|
|
251
|
-
const dm = dms.find(
|
|
252
|
-
({ documentModel }: { documentModel: DocumentModelState }) =>
|
|
253
|
-
documentModel.id === document.documentType,
|
|
254
|
-
);
|
|
255
|
-
const globalState = document.state.global;
|
|
256
|
-
if (!globalState) throw new Error("Document not found");
|
|
257
|
-
const typeName = pascalCase(
|
|
258
|
-
(dm?.documentModel.name || "").replaceAll("/", " "),
|
|
259
|
-
);
|
|
260
|
-
const response = {
|
|
261
|
-
...document,
|
|
262
|
-
id,
|
|
263
|
-
revision: document.revision.global,
|
|
264
|
-
state: document.state.global,
|
|
265
|
-
operations: document.operations.global.map((op: Operation) => ({
|
|
266
|
-
...op,
|
|
267
|
-
inputText:
|
|
268
|
-
typeof op.input === "string"
|
|
269
|
-
? op.input
|
|
270
|
-
: JSON.stringify(op.input),
|
|
271
|
-
})),
|
|
272
|
-
initialState: document.initialState.state.global,
|
|
273
|
-
__typename: typeName,
|
|
274
|
-
};
|
|
275
|
-
return response;
|
|
276
|
-
},
|
|
277
|
-
system: () => ({ sync: {} }),
|
|
278
|
-
},
|
|
279
|
-
Mutation: {
|
|
280
|
-
registerPullResponderListener: async (
|
|
281
|
-
_: unknown,
|
|
282
|
-
{ filter }: { filter: ListenerFilter },
|
|
283
|
-
ctx: Context,
|
|
284
|
-
) => {
|
|
285
|
-
this.debugLog(
|
|
286
|
-
`registerPullResponderListener(drive: ${ctx.driveId})`,
|
|
287
|
-
filter,
|
|
288
|
-
);
|
|
289
|
-
|
|
290
|
-
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
291
|
-
const uuid = generateUUID();
|
|
292
|
-
const listener: Listener = {
|
|
293
|
-
block: false,
|
|
294
|
-
callInfo: {
|
|
295
|
-
data: "",
|
|
296
|
-
name: "PullResponder",
|
|
297
|
-
transmitterType: "PullResponder" as TransmitterType,
|
|
298
|
-
},
|
|
299
|
-
filter: {
|
|
300
|
-
branch: filter.branch ?? [],
|
|
301
|
-
documentId: filter.documentId ?? [],
|
|
302
|
-
documentType: filter.documentType ?? [],
|
|
303
|
-
scope: filter.scope ?? [],
|
|
304
|
-
},
|
|
305
|
-
label: `Pullresponder #${uuid}`,
|
|
306
|
-
listenerId: uuid,
|
|
307
|
-
system: false,
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
const result = await this.reactor.queueDriveAction(
|
|
311
|
-
ctx.driveId,
|
|
312
|
-
actions.addListener({ listener }),
|
|
313
|
-
);
|
|
314
|
-
|
|
315
|
-
if (result.status !== "SUCCESS" && result.error) {
|
|
316
|
-
throw new Error(
|
|
317
|
-
`Listener couldn't be registered: ${result.error.message}`,
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
return listener;
|
|
322
|
-
},
|
|
323
|
-
pushUpdates: async (
|
|
324
|
-
_: unknown,
|
|
325
|
-
{ strands: strandsGql }: { strands: StrandUpdateGraphQL[] },
|
|
326
|
-
ctx: Context,
|
|
327
|
-
) => {
|
|
328
|
-
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
329
|
-
this.debugLog(`pushUpdates(drive: ${ctx.driveId})`, strandsGql);
|
|
330
|
-
|
|
331
|
-
// translate data types
|
|
332
|
-
const strands: InternalStrandUpdate[] = strandsGql.map((strandGql) => {
|
|
333
|
-
return {
|
|
334
|
-
operations: strandGql.operations.map((op) => ({
|
|
335
|
-
...op,
|
|
336
|
-
input: JSON.parse(op.input) as DocumentModelInput,
|
|
337
|
-
skip: op.skip ?? 0,
|
|
338
|
-
scope: strandGql.scope,
|
|
339
|
-
branch: "main",
|
|
340
|
-
})) as Operation[],
|
|
341
|
-
documentId: strandGql.documentId,
|
|
342
|
-
driveId: strandGql.driveId,
|
|
343
|
-
scope: strandGql.scope,
|
|
344
|
-
branch: strandGql.branch,
|
|
345
|
-
};
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
// return a list of listener revisions
|
|
349
|
-
return await Promise.all(
|
|
350
|
-
strands.map((strand) => processPushUpdate(this.reactor, strand)),
|
|
351
|
-
);
|
|
352
|
-
},
|
|
353
|
-
acknowledge: async (
|
|
354
|
-
_: unknown,
|
|
355
|
-
{
|
|
356
|
-
listenerId,
|
|
357
|
-
revisions,
|
|
358
|
-
}: { listenerId: string; revisions: ListenerRevision[] },
|
|
359
|
-
ctx: Context,
|
|
360
|
-
) => {
|
|
361
|
-
this.debugLog(
|
|
362
|
-
`acknowledge(drive: ${ctx.driveId}, listenerId: ${listenerId})`,
|
|
363
|
-
revisions,
|
|
364
|
-
);
|
|
365
|
-
|
|
366
|
-
if (!listenerId || !revisions) return false;
|
|
367
|
-
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
368
|
-
|
|
369
|
-
// translate data types
|
|
370
|
-
const validEntries = revisions
|
|
371
|
-
.filter((r) => r !== null)
|
|
372
|
-
.map((e) => ({
|
|
373
|
-
driveId: e.driveId,
|
|
374
|
-
documentId: e.documentId,
|
|
375
|
-
scope: e.scope,
|
|
376
|
-
branch: e.branch,
|
|
377
|
-
revision: e.revision,
|
|
378
|
-
status: e.status,
|
|
379
|
-
}));
|
|
380
|
-
|
|
381
|
-
// return a boolean indicating if the acknowledge was successful
|
|
382
|
-
return await processAcknowledge(
|
|
383
|
-
this.reactor,
|
|
384
|
-
ctx.driveId,
|
|
385
|
-
listenerId,
|
|
386
|
-
validEntries,
|
|
387
|
-
);
|
|
388
|
-
},
|
|
389
|
-
},
|
|
390
|
-
System: {},
|
|
391
|
-
Sync: {
|
|
392
|
-
strands: async (
|
|
393
|
-
_: unknown,
|
|
394
|
-
{
|
|
395
|
-
listenerId,
|
|
396
|
-
since,
|
|
397
|
-
}: { listenerId: string; since: string | undefined },
|
|
398
|
-
ctx: Context,
|
|
399
|
-
) => {
|
|
400
|
-
this.debugLog(
|
|
401
|
-
`strands(drive: ${ctx.driveId}, listenerId: ${listenerId}, since:${since})`,
|
|
402
|
-
);
|
|
403
|
-
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
404
|
-
|
|
405
|
-
// get the requested strand updates
|
|
406
|
-
const strands = await processGetStrands(
|
|
407
|
-
this.reactor,
|
|
408
|
-
ctx.driveId,
|
|
409
|
-
listenerId,
|
|
410
|
-
since,
|
|
411
|
-
);
|
|
412
|
-
|
|
413
|
-
// translate data types
|
|
414
|
-
return strands.map((update) => ({
|
|
415
|
-
driveId: update.driveId,
|
|
416
|
-
documentId: update.documentId,
|
|
417
|
-
scope: update.scope,
|
|
418
|
-
branch: update.branch,
|
|
419
|
-
operations: update.operations.map((op) => ({
|
|
420
|
-
index: op.index,
|
|
421
|
-
skip: op.skip,
|
|
422
|
-
name: op.type,
|
|
423
|
-
input: JSON.stringify(op.input),
|
|
424
|
-
hash: op.hash,
|
|
425
|
-
timestamp: op.timestamp,
|
|
426
|
-
type: op.type,
|
|
427
|
-
context: op.context,
|
|
428
|
-
id: op.id,
|
|
429
|
-
})),
|
|
430
|
-
}));
|
|
431
|
-
},
|
|
432
|
-
},
|
|
433
|
-
};
|
|
434
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { Maybe } from "document-model/document-model";
|
|
2
|
-
|
|
3
|
-
export type Scalars = {
|
|
4
|
-
ID: { input: string; output: string };
|
|
5
|
-
String: { input: string; output: string };
|
|
6
|
-
Boolean: { input: boolean; output: boolean };
|
|
7
|
-
Int: { input: number; output: number };
|
|
8
|
-
Float: { input: number; output: number };
|
|
9
|
-
DateTime: { input: string; output: string };
|
|
10
|
-
};
|
|
11
|
-
export type Asset = Cash | FixedIncome;
|
|
12
|
-
|
|
13
|
-
export type AssetType = "Cash" | "FixedIncome";
|
|
14
|
-
export type Cash = {
|
|
15
|
-
balance: Scalars["Float"]["output"];
|
|
16
|
-
currency: Scalars["String"]["output"];
|
|
17
|
-
id: Scalars["ID"]["output"];
|
|
18
|
-
spvId: Scalars["ID"]["output"];
|
|
19
|
-
type: AssetType | `${AssetType}`;
|
|
20
|
-
};
|
|
21
|
-
export type FixedIncome = {
|
|
22
|
-
CUSIP: Maybe<Scalars["String"]["output"]>;
|
|
23
|
-
ISIN: Maybe<Scalars["String"]["output"]>;
|
|
24
|
-
assetProceeds: Scalars["Float"]["output"];
|
|
25
|
-
coupon: Maybe<Scalars["Float"]["output"]>;
|
|
26
|
-
fixedIncomeTypeId: Scalars["ID"]["output"];
|
|
27
|
-
id: Scalars["ID"]["output"];
|
|
28
|
-
maturity: Maybe<Scalars["DateTime"]["output"]>;
|
|
29
|
-
name: Scalars["String"]["output"];
|
|
30
|
-
notional: Scalars["Float"]["output"];
|
|
31
|
-
purchaseDate: Scalars["DateTime"]["output"];
|
|
32
|
-
purchasePrice: Scalars["Float"]["output"];
|
|
33
|
-
purchaseProceeds: Scalars["Float"]["output"];
|
|
34
|
-
realizedSurplus: Scalars["Float"]["output"];
|
|
35
|
-
salesProceeds: Scalars["Float"]["output"];
|
|
36
|
-
spvId: Scalars["ID"]["output"];
|
|
37
|
-
totalDiscount: Scalars["Float"]["output"];
|
|
38
|
-
type: AssetType | `${AssetType}`;
|
|
39
|
-
};
|
package/src/subgraphs/index.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Subgraph } from "./base";
|
|
2
|
-
|
|
3
|
-
export * as analyticsSubgraph from "./analytics";
|
|
4
|
-
export * as driveSubgraph from "./drive";
|
|
5
|
-
export * as systemSubgraph from "./system";
|
|
6
|
-
export * as authSubgraph from "./auth";
|
|
7
|
-
export * from "./types";
|
|
8
|
-
export { Subgraph } from "./base";
|
|
9
|
-
|
|
10
|
-
export type SubgraphClass = typeof Subgraph;
|
|
11
|
-
export function isSubgraphClass(
|
|
12
|
-
candidate: unknown,
|
|
13
|
-
): candidate is SubgraphClass {
|
|
14
|
-
if (typeof candidate !== "function") return false;
|
|
15
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
16
|
-
let proto = Object.getPrototypeOf(candidate);
|
|
17
|
-
while (proto) {
|
|
18
|
-
if (Object.prototype.isPrototypeOf.call(proto, Subgraph)) return true;
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
20
|
-
proto = Object.getPrototypeOf(proto);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return false;
|
|
24
|
-
}
|
package/src/subgraphs/manager.ts
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { ApolloServer } from "@apollo/server";
|
|
2
|
-
import { expressMiddleware } from "@apollo/server/express4";
|
|
3
|
-
import { ApolloServerPluginInlineTraceDisabled } from "@apollo/server/plugin/disabled";
|
|
4
|
-
import { IAnalyticsStore } from "@powerhousedao/analytics-engine-core";
|
|
5
|
-
import bodyParser from "body-parser";
|
|
6
|
-
import cors from "cors";
|
|
7
|
-
import { IDocumentDriveServer } from "document-drive";
|
|
8
|
-
import express, { IRouter, Router } from "express";
|
|
9
|
-
import { Db } from "src/types";
|
|
10
|
-
import { authSubgraph, Context, SubgraphArgs, SubgraphClass } from ".";
|
|
11
|
-
import { createSchema } from "../utils/create-schema";
|
|
12
|
-
import { AnalyticsSubgraph } from "./analytics";
|
|
13
|
-
import { Subgraph } from "./base";
|
|
14
|
-
import { DriveSubgraph } from "./drive";
|
|
15
|
-
import { SystemSubgraph } from "./system";
|
|
16
|
-
import { AuthSubgraph } from "./auth";
|
|
17
|
-
|
|
18
|
-
export class SubgraphManager {
|
|
19
|
-
private reactorRouter: IRouter = Router();
|
|
20
|
-
private contextFields: Record<string, any> = {};
|
|
21
|
-
private subgraphs: Subgraph[] = [];
|
|
22
|
-
|
|
23
|
-
constructor(
|
|
24
|
-
private readonly path: string,
|
|
25
|
-
private readonly app: express.Express,
|
|
26
|
-
private readonly reactor: IDocumentDriveServer,
|
|
27
|
-
private readonly operationalStore: Db,
|
|
28
|
-
private readonly analyticsStore: IAnalyticsStore,
|
|
29
|
-
) {
|
|
30
|
-
// Setup Default subgraphs
|
|
31
|
-
this.registerSubgraph(AuthSubgraph);
|
|
32
|
-
this.registerSubgraph(SystemSubgraph);
|
|
33
|
-
this.registerSubgraph(DriveSubgraph);
|
|
34
|
-
this.registerSubgraph(AnalyticsSubgraph);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async init() {
|
|
38
|
-
console.log(`Initializing Subgraph Manager...`);
|
|
39
|
-
const models = this.reactor.getDocumentModels();
|
|
40
|
-
const driveModel = models.find(
|
|
41
|
-
(it) => it.documentModel.name === "DocumentDrive",
|
|
42
|
-
);
|
|
43
|
-
if (!driveModel) {
|
|
44
|
-
throw new Error("DocumentDrive model required");
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
this.reactor.on("documentModels", () => {
|
|
48
|
-
this.updateRouter().catch((error: unknown) => console.error(error));
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
this.app.use(this.path, (req, res, next) =>
|
|
52
|
-
this.reactorRouter(req, res, next),
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
await this.updateRouter();
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async updateRouter() {
|
|
59
|
-
const newRouter = Router();
|
|
60
|
-
newRouter.use(cors());
|
|
61
|
-
newRouter.use(bodyParser.json());
|
|
62
|
-
// Run each subgraph on the same http server, but at different paths
|
|
63
|
-
for (const subgraph of this.subgraphs) {
|
|
64
|
-
const subgraphConfig = this.#getLocalSubgraphConfig(subgraph.name);
|
|
65
|
-
if (!subgraphConfig) continue;
|
|
66
|
-
// get schema
|
|
67
|
-
const schema = createSchema(
|
|
68
|
-
this.reactor,
|
|
69
|
-
subgraphConfig.resolvers,
|
|
70
|
-
subgraphConfig.typeDefs,
|
|
71
|
-
);
|
|
72
|
-
// create apollo server
|
|
73
|
-
const server = new ApolloServer({
|
|
74
|
-
schema,
|
|
75
|
-
introspection: true,
|
|
76
|
-
plugins: [ApolloServerPluginInlineTraceDisabled()],
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// start apollo server
|
|
80
|
-
await server.start();
|
|
81
|
-
|
|
82
|
-
// setup path
|
|
83
|
-
const path = `/${subgraphConfig.name}`;
|
|
84
|
-
newRouter.use(
|
|
85
|
-
path,
|
|
86
|
-
// @ts-ignore
|
|
87
|
-
expressMiddleware(server, {
|
|
88
|
-
context: ({ req }): Context => ({
|
|
89
|
-
headers: req.headers,
|
|
90
|
-
driveId: req.params.drive ?? undefined,
|
|
91
|
-
driveServer: this.reactor,
|
|
92
|
-
db: this.operationalStore,
|
|
93
|
-
...this.getAdditionalContextFields(),
|
|
94
|
-
}),
|
|
95
|
-
}),
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
this.reactorRouter = newRouter;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
async registerSubgraph(subgraph: SubgraphClass) {
|
|
103
|
-
const subgraphInstance = new subgraph({
|
|
104
|
-
operationalStore: this.operationalStore,
|
|
105
|
-
analyticsStore: this.analyticsStore,
|
|
106
|
-
reactor: this.reactor,
|
|
107
|
-
subgraphManager: this,
|
|
108
|
-
});
|
|
109
|
-
await subgraphInstance.onSetup();
|
|
110
|
-
this.subgraphs.unshift(subgraphInstance);
|
|
111
|
-
console.log(
|
|
112
|
-
`> Registered ${this.path.endsWith("/") ? this.path : this.path + "/"}${subgraphInstance.name} subgraph.`,
|
|
113
|
-
);
|
|
114
|
-
await this.updateRouter();
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
#getLocalSubgraphConfig(subgraphName: string) {
|
|
118
|
-
return this.subgraphs.find((it) => it.name === subgraphName);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
getAdditionalContextFields = () => {
|
|
122
|
-
return this.contextFields;
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
setAdditionalContextFields(fields: Record<string, any>) {
|
|
126
|
-
this.contextFields = { ...this.contextFields, ...fields };
|
|
127
|
-
}
|
|
128
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { DriveInput } from "document-drive";
|
|
2
|
-
import { GraphQLError } from "graphql";
|
|
3
|
-
import { gql } from "graphql-tag";
|
|
4
|
-
import { Subgraph } from "../base";
|
|
5
|
-
import { ADMIN_USERS } from "./env";
|
|
6
|
-
import { SystemContext } from "./types";
|
|
7
|
-
|
|
8
|
-
export class SystemSubgraph extends Subgraph {
|
|
9
|
-
name = "system";
|
|
10
|
-
|
|
11
|
-
typeDefs = gql`
|
|
12
|
-
type Query {
|
|
13
|
-
drives: [String!]!
|
|
14
|
-
driveIdBySlug(slug: String!): String
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
type Mutation {
|
|
18
|
-
addDrive(
|
|
19
|
-
global: DocumentDriveStateInput!
|
|
20
|
-
): DocumentDrive_DocumentDriveState
|
|
21
|
-
deleteDrive(id: ID!): Boolean
|
|
22
|
-
setDriveIcon(id: String!, icon: String!): Boolean
|
|
23
|
-
setDriveName(id: String!, name: String!): Boolean
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
input DocumentDriveStateInput {
|
|
27
|
-
name: String
|
|
28
|
-
id: String
|
|
29
|
-
slug: String
|
|
30
|
-
icon: String
|
|
31
|
-
}
|
|
32
|
-
`;
|
|
33
|
-
|
|
34
|
-
resolvers = {
|
|
35
|
-
Query: {
|
|
36
|
-
drives: async () => {
|
|
37
|
-
return await this.reactor.getDrives();
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
Mutation: {
|
|
41
|
-
addDrive: async (
|
|
42
|
-
parent: unknown,
|
|
43
|
-
args: DriveInput,
|
|
44
|
-
ctx: SystemContext,
|
|
45
|
-
) => {
|
|
46
|
-
try {
|
|
47
|
-
const isAdmin = ctx.isAdmin(ctx);
|
|
48
|
-
if (!isAdmin) {
|
|
49
|
-
throw new GraphQLError("Unauthorized");
|
|
50
|
-
}
|
|
51
|
-
const drive = await this.reactor.addDrive(args);
|
|
52
|
-
return drive.state.global;
|
|
53
|
-
} catch (e) {
|
|
54
|
-
console.error(e);
|
|
55
|
-
throw new Error(e as string);
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
async onSetup() {
|
|
62
|
-
await super.onSetup();
|
|
63
|
-
this.subgraphManager.setAdditionalContextFields({
|
|
64
|
-
isAdmin: (ctx: SystemContext) => {
|
|
65
|
-
return (
|
|
66
|
-
ADMIN_USERS.length === 0 ||
|
|
67
|
-
(ctx.session.address &&
|
|
68
|
-
ADMIN_USERS.includes(ctx.session.address.toLocaleLowerCase()))
|
|
69
|
-
);
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
}
|