@powerhousedao/reactor-api 1.20.2 → 1.21.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/CHANGELOG.md +6 -9
- package/dist/index.d.ts +66 -76
- package/dist/index.js +121 -65
- package/dist/index.js.map +1 -1
- package/package.json +9 -6
- package/src/subgraphs/drive/index.ts +110 -78
- package/src/sync/utils.ts +85 -0
- package/test/benchmarks/load.bench.ts +78 -0
- package/test/benchmarks/sync.bench.ts +151 -0
- package/test/data/BlocktowerAndromeda.zip +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
## 1.
|
|
2
|
-
|
|
3
|
-
### 🚀 Features
|
|
4
|
-
|
|
5
|
-
- **design-system:** add danger zone settings page ([572345bc](https://github.com/powerhouse-inc/powerhouse/commit/572345bc))
|
|
1
|
+
## 1.21.1 (2025-02-18)
|
|
6
2
|
|
|
7
3
|
### 🩹 Fixes
|
|
8
4
|
|
|
9
|
-
- **reactor-api:**
|
|
5
|
+
- **reactor-api:** inject missing node __typenames in drive subgraph ([8571ba3f](https://github.com/powerhouse-inc/powerhouse/commit/8571ba3f))
|
|
6
|
+
- **reactor-api:** inject missing node __typenames in drive subgraph ([083f711a](https://github.com/powerhouse-inc/powerhouse/commit/083f711a))
|
|
7
|
+
- **reactor-api:** sanitize document model name before using it as __typename ([07c3be7d](https://github.com/powerhouse-inc/powerhouse/commit/07c3be7d))
|
|
10
8
|
|
|
11
9
|
### 🧱 Updated Dependencies
|
|
12
10
|
|
|
13
|
-
- Updated document-model-libs to 1.
|
|
14
|
-
- Updated document-drive to 1.
|
|
11
|
+
- Updated document-model-libs to 1.132.1
|
|
12
|
+
- Updated document-drive to 1.19.0
|
|
15
13
|
|
|
16
14
|
### ❤️ Thank You
|
|
17
15
|
|
|
18
|
-
- ryanwolhuter @ryanwolhuter
|
|
19
16
|
- Wouter Kampmann
|
|
20
17
|
|
|
21
18
|
## 1.2.0 (2024-10-29)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PGlite } from '@electric-sql/pglite';
|
|
2
2
|
import * as document_model_libs_document_drive from 'document-model-libs/document-drive';
|
|
3
|
-
import {
|
|
4
|
-
import { Operation, Document, DocumentModel, Action, OperationScope, State, BaseAction,
|
|
3
|
+
import { DocumentDriveDocument, ListenerFilter, Trigger, PullResponderTriggerData, DocumentDriveState, DocumentDriveLocalState, ListenerCallInfo, DocumentDriveAction } from 'document-model-libs/document-drive';
|
|
4
|
+
import { Operation, Document, DocumentModel, Action, OperationScope, State, BaseAction, ActionContext, ReducerOptions, Signal } from 'document-model/document';
|
|
5
5
|
import { Unsubscribe } from 'nanoevents';
|
|
6
6
|
import express, { Express } from 'express';
|
|
7
7
|
import { Pool } from 'pg';
|
|
@@ -15,21 +15,6 @@ import { GraphQLResolverMap as GraphQLResolverMap$1 } from '@apollo/subgraph/dis
|
|
|
15
15
|
import { AnalyticsModel } from '@powerhousedao/analytics-engine-graphql';
|
|
16
16
|
import { GraphQLResolverMap } from '@apollo/subgraph/dist/schema-helper/resolverMap.js';
|
|
17
17
|
|
|
18
|
-
type StrandUpdateSource = {
|
|
19
|
-
type: "local";
|
|
20
|
-
} | {
|
|
21
|
-
type: "trigger";
|
|
22
|
-
trigger: Trigger;
|
|
23
|
-
};
|
|
24
|
-
interface ITransmitter {
|
|
25
|
-
transmit?(strands: StrandUpdate[], source: StrandUpdateSource): Promise<ListenerRevision[]>;
|
|
26
|
-
disconnect?(): Promise<void>;
|
|
27
|
-
}
|
|
28
|
-
type PullResponderTrigger = Omit<Trigger, "data" | "type"> & {
|
|
29
|
-
data: PullResponderTriggerData;
|
|
30
|
-
type: "PullResponder";
|
|
31
|
-
};
|
|
32
|
-
|
|
33
18
|
declare class DocumentModelNotFoundError extends Error {
|
|
34
19
|
id: string;
|
|
35
20
|
constructor(id: string, cause?: unknown);
|
|
@@ -93,6 +78,28 @@ interface IReadModeDriveService {
|
|
|
93
78
|
deleteReadDrive(id: string): Promise<ReadDriveNotFoundError | undefined>;
|
|
94
79
|
}
|
|
95
80
|
|
|
81
|
+
interface IDefaultDrivesManager {
|
|
82
|
+
initializeDefaultRemoteDrives(): Promise<void>;
|
|
83
|
+
getDefaultRemoteDrives(): Map<string, DefaultRemoteDriveInfo>;
|
|
84
|
+
setDefaultDriveAccessLevel(url: string, level: RemoteDriveAccessLevel): Promise<void>;
|
|
85
|
+
setAllDefaultDrivesAccessLevel(level: RemoteDriveAccessLevel): Promise<void>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
type StrandUpdateSource = {
|
|
89
|
+
type: "local";
|
|
90
|
+
} | {
|
|
91
|
+
type: "trigger";
|
|
92
|
+
trigger: Trigger;
|
|
93
|
+
};
|
|
94
|
+
interface ITransmitter {
|
|
95
|
+
transmit?(strands: StrandUpdate[], source: StrandUpdateSource): Promise<ListenerRevision[]>;
|
|
96
|
+
disconnect?(): Promise<void>;
|
|
97
|
+
}
|
|
98
|
+
type PullResponderTrigger = Omit<Trigger, "data" | "type"> & {
|
|
99
|
+
data: PullResponderTriggerData;
|
|
100
|
+
type: "PullResponder";
|
|
101
|
+
};
|
|
102
|
+
|
|
96
103
|
interface IReceiver<T extends Document = Document, S extends OperationScope = OperationScope> {
|
|
97
104
|
onStrands: (strands: InternalTransmitterUpdate<T, S>[]) => Promise<void>;
|
|
98
105
|
onDisconnect: () => Promise<void>;
|
|
@@ -113,13 +120,6 @@ interface IInternalTransmitter extends ITransmitter {
|
|
|
113
120
|
setReceiver(receiver: IReceiver): void;
|
|
114
121
|
}
|
|
115
122
|
|
|
116
|
-
interface IDefaultDrivesManager {
|
|
117
|
-
initializeDefaultRemoteDrives(): Promise<void>;
|
|
118
|
-
getDefaultRemoteDrives(): Map<string, DefaultRemoteDriveInfo>;
|
|
119
|
-
setDefaultDriveAccessLevel(url: string, level: RemoteDriveAccessLevel): Promise<void>;
|
|
120
|
-
setAllDefaultDrivesAccessLevel(level: RemoteDriveAccessLevel): Promise<void>;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
123
|
type DriveInput = State<Omit<DocumentDriveState, "__typename" | "id" | "nodes"> & {
|
|
124
124
|
id?: string;
|
|
125
125
|
}, DocumentDriveLocalState>;
|
|
@@ -130,7 +130,6 @@ type RemoteDriveOptions = DocumentDriveLocalState & {
|
|
|
130
130
|
expectedDriveInfo?: DriveInfo;
|
|
131
131
|
accessLevel?: RemoteDriveAccessLevel;
|
|
132
132
|
};
|
|
133
|
-
type CreateDocumentInput = CreateChildDocumentInput;
|
|
134
133
|
type SignalResult = {
|
|
135
134
|
signal: Signal;
|
|
136
135
|
result: unknown;
|
|
@@ -161,6 +160,7 @@ type Listener = {
|
|
|
161
160
|
system: boolean;
|
|
162
161
|
filter: ListenerFilter;
|
|
163
162
|
callInfo?: ListenerCallInfo;
|
|
163
|
+
transmitter?: ITransmitter;
|
|
164
164
|
};
|
|
165
165
|
type ListenerRevision = {
|
|
166
166
|
driveId: string;
|
|
@@ -232,65 +232,52 @@ type GetStrandsOptions = {
|
|
|
232
232
|
since?: string;
|
|
233
233
|
fromRevision?: number;
|
|
234
234
|
};
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
abstract addInternalListener(driveId: string, receiver: IReceiver, options: {
|
|
235
|
+
interface IBaseDocumentDriveServer {
|
|
236
|
+
initialize(): Promise<Error[] | null>;
|
|
237
|
+
setDocumentModels(models: DocumentModel[]): void;
|
|
238
|
+
getDrives(): Promise<string[]>;
|
|
239
|
+
addDrive(input: DriveInput): Promise<DocumentDriveDocument>;
|
|
240
|
+
addRemoteDrive(url: string, options: RemoteDriveOptions): Promise<DocumentDriveDocument>;
|
|
241
|
+
deleteDrive(driveId: string): Promise<void>;
|
|
242
|
+
getDrive(driveId: string, options?: GetDocumentOptions): Promise<DocumentDriveDocument>;
|
|
243
|
+
getDriveBySlug(slug: string): Promise<DocumentDriveDocument>;
|
|
244
|
+
getDocuments(driveId: string): Promise<string[]>;
|
|
245
|
+
getDocument(driveId: string, documentId: string, options?: GetDocumentOptions): Promise<Document>;
|
|
246
|
+
addOperation(driveId: string, documentId: string, operation: Operation, options?: AddOperationOptions): Promise<IOperationResult>;
|
|
247
|
+
addOperations(driveId: string, documentId: string, operations: Operation[], options?: AddOperationOptions): Promise<IOperationResult>;
|
|
248
|
+
queueOperation(driveId: string, documentId: string, operation: Operation, options?: AddOperationOptions): Promise<IOperationResult>;
|
|
249
|
+
queueOperations(driveId: string, documentId: string, operations: Operation[], options?: AddOperationOptions): Promise<IOperationResult>;
|
|
250
|
+
queueAction(driveId: string, documentId: string, action: Action, options?: AddOperationOptions): Promise<IOperationResult>;
|
|
251
|
+
queueActions(driveId: string, documentId: string, actions: Action[], options?: AddOperationOptions): Promise<IOperationResult>;
|
|
252
|
+
addDriveOperation(driveId: string, operation: Operation<DocumentDriveAction | BaseAction>, options?: AddOperationOptions): Promise<IOperationResult<DocumentDriveDocument>>;
|
|
253
|
+
addDriveOperations(driveId: string, operations: Operation<DocumentDriveAction | BaseAction>[], options?: AddOperationOptions): Promise<IOperationResult<DocumentDriveDocument>>;
|
|
254
|
+
queueDriveOperation(driveId: string, operation: Operation<DocumentDriveAction | BaseAction>, options?: AddOperationOptions): Promise<IOperationResult<DocumentDriveDocument>>;
|
|
255
|
+
queueDriveOperations(driveId: string, operations: Operation<DocumentDriveAction | BaseAction>[], options?: AddOperationOptions): Promise<IOperationResult<DocumentDriveDocument>>;
|
|
256
|
+
queueDriveAction(driveId: string, action: DocumentDriveAction | BaseAction, options?: AddOperationOptions): Promise<IOperationResult<DocumentDriveDocument>>;
|
|
257
|
+
queueDriveActions(driveId: string, actions: Array<DocumentDriveAction | BaseAction>, options?: AddOperationOptions): Promise<IOperationResult<DocumentDriveDocument>>;
|
|
258
|
+
addAction(driveId: string, documentId: string, action: Action, options?: AddOperationOptions): Promise<IOperationResult>;
|
|
259
|
+
addActions(driveId: string, documentId: string, actions: Action[], options?: AddOperationOptions): Promise<IOperationResult>;
|
|
260
|
+
addDriveAction(driveId: string, action: DocumentDriveAction | BaseAction, options?: AddOperationOptions): Promise<IOperationResult<DocumentDriveDocument>>;
|
|
261
|
+
addDriveActions(driveId: string, actions: (DocumentDriveAction | BaseAction)[], options?: AddOperationOptions): Promise<IOperationResult<DocumentDriveDocument>>;
|
|
262
|
+
getSyncStatus(syncUnitId: string): SyncStatus | SynchronizationUnitNotFoundError;
|
|
263
|
+
addInternalListener(driveId: string, receiver: IReceiver, options: {
|
|
265
264
|
listenerId: string;
|
|
266
265
|
label: string;
|
|
267
266
|
block: boolean;
|
|
268
267
|
filter: ListenerFilter;
|
|
269
268
|
}): Promise<IInternalTransmitter>;
|
|
270
269
|
/** Synchronization methods */
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
270
|
+
getSynchronizationUnits(driveId: string, documentId?: string[], scope?: string[], branch?: string[], documentType?: string[], loadedDrive?: DocumentDriveDocument): Promise<SynchronizationUnit[]>;
|
|
271
|
+
getSynchronizationUnit(driveId: string, syncId: string, loadedDrive?: DocumentDriveDocument): Promise<SynchronizationUnit | undefined>;
|
|
272
|
+
getSynchronizationUnitsIds(driveId: string, documentId?: string[], scope?: string[], branch?: string[], documentType?: string[]): Promise<SynchronizationUnitQuery[]>;
|
|
273
|
+
getOperationData(driveId: string, syncId: string, filter: GetStrandsOptions, loadedDrive?: DocumentDriveDocument): Promise<OperationUpdate[]>;
|
|
275
274
|
/** Internal methods **/
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
protected abstract emit<K extends keyof DriveEvents>(event: K, ...args: Parameters<DriveEvents[K]>): void;
|
|
282
|
-
abstract on<K extends keyof DriveEvents>(event: K, cb: DriveEvents[K]): Unsubscribe;
|
|
283
|
-
abstract getTransmitter(driveId: string, listenerId: string): Promise<ITransmitter | undefined>;
|
|
284
|
-
abstract clearStorage(): Promise<void>;
|
|
285
|
-
abstract registerPullResponderTrigger(id: string, url: string, options: Pick<RemoteDriveOptions, "pullFilter" | "pullInterval">): Promise<PullResponderTrigger>;
|
|
275
|
+
getDocumentModels(): DocumentModel[];
|
|
276
|
+
getTransmitter(driveId: string, listenerId: string): Promise<ITransmitter | undefined>;
|
|
277
|
+
clearStorage(): Promise<void>;
|
|
278
|
+
registerPullResponderTrigger(id: string, url: string, options: Pick<RemoteDriveOptions, "pullFilter" | "pullInterval">): Promise<PullResponderTrigger>;
|
|
279
|
+
on<K extends keyof DriveEvents>(event: K, cb: DriveEvents[K]): Unsubscribe;
|
|
286
280
|
}
|
|
287
|
-
type PublicKeys<T> = {
|
|
288
|
-
[K in keyof T]: T extends {
|
|
289
|
-
[P in K]: T[K];
|
|
290
|
-
} ? K : never;
|
|
291
|
-
}[keyof T];
|
|
292
|
-
type PublicPart<T> = Pick<T, PublicKeys<T>>;
|
|
293
|
-
type IBaseDocumentDriveServer = PublicPart<AbstractDocumentDriveServer>;
|
|
294
281
|
type IDocumentDriveServer = IBaseDocumentDriveServer & IDefaultDrivesManager & IReadModeDriveServer;
|
|
295
282
|
|
|
296
283
|
type ProcessorUpdate<D extends Document = Document, S extends OperationScope = OperationScope> = InternalTransmitterUpdate<D, S>;
|
|
@@ -360,6 +347,9 @@ declare namespace index$3 {
|
|
|
360
347
|
}
|
|
361
348
|
|
|
362
349
|
declare class DriveSubgraph extends Subgraph {
|
|
350
|
+
private debugID;
|
|
351
|
+
constructor(args: SubgraphArgs);
|
|
352
|
+
private debugLog;
|
|
363
353
|
name: string;
|
|
364
354
|
typeDefs: graphql.DocumentNode;
|
|
365
355
|
resolvers: GraphQLResolverMap$1<Context>;
|
package/dist/index.js
CHANGED
|
@@ -25926,7 +25926,68 @@ index.documentHelpers;
|
|
|
25926
25926
|
|
|
25927
25927
|
// ../document-drive/src/server/listener/transmitter/switchboard-push.ts
|
|
25928
25928
|
__toESM(require_lib4());
|
|
25929
|
+
|
|
25930
|
+
// src/sync/utils.ts
|
|
25931
|
+
var processPushUpdate = async (reactor, strand) => {
|
|
25932
|
+
const result = await (strand.documentId !== undefined ? reactor.queueOperations(
|
|
25933
|
+
strand.driveId,
|
|
25934
|
+
strand.documentId,
|
|
25935
|
+
strand.operations
|
|
25936
|
+
) : reactor.queueDriveOperations(
|
|
25937
|
+
strand.driveId,
|
|
25938
|
+
strand.operations
|
|
25939
|
+
));
|
|
25940
|
+
const scopeOperations = result.document?.operations[strand.scope] ?? [];
|
|
25941
|
+
if (scopeOperations.length === 0) {
|
|
25942
|
+
return {
|
|
25943
|
+
revision: -1,
|
|
25944
|
+
branch: strand.branch,
|
|
25945
|
+
documentId: strand.documentId ?? "",
|
|
25946
|
+
driveId: strand.driveId,
|
|
25947
|
+
scope: strand.scope,
|
|
25948
|
+
status: result.status
|
|
25949
|
+
};
|
|
25950
|
+
}
|
|
25951
|
+
const revision = scopeOperations.slice().pop()?.index ?? -1;
|
|
25952
|
+
return {
|
|
25953
|
+
revision,
|
|
25954
|
+
branch: strand.branch,
|
|
25955
|
+
documentId: strand.documentId ?? "",
|
|
25956
|
+
driveId: strand.driveId,
|
|
25957
|
+
scope: strand.scope,
|
|
25958
|
+
status: result.status,
|
|
25959
|
+
error: result.error?.message || undefined
|
|
25960
|
+
};
|
|
25961
|
+
};
|
|
25962
|
+
var processAcknowledge = async (reactor, driveId, listenerId, revisions) => {
|
|
25963
|
+
const transmitter = await reactor.getTransmitter(
|
|
25964
|
+
driveId,
|
|
25965
|
+
listenerId
|
|
25966
|
+
);
|
|
25967
|
+
return transmitter.processAcknowledge(driveId, listenerId, revisions);
|
|
25968
|
+
};
|
|
25969
|
+
var processGetStrands = async (reactor, driveId, listenerId, since) => {
|
|
25970
|
+
const transmitter = await reactor.getTransmitter(
|
|
25971
|
+
driveId,
|
|
25972
|
+
listenerId
|
|
25973
|
+
);
|
|
25974
|
+
return transmitter.getStrands({ since });
|
|
25975
|
+
};
|
|
25976
|
+
var driveKindTypeNames = {
|
|
25977
|
+
file: "DocumentDrive_FileNode",
|
|
25978
|
+
folder: "DocumentDrive_FolderNode"
|
|
25979
|
+
};
|
|
25929
25980
|
var DriveSubgraph = class extends Subgraph {
|
|
25981
|
+
debugID = `[DSG #${Math.floor(Math.random() * 999)}]`;
|
|
25982
|
+
constructor(args) {
|
|
25983
|
+
super(args);
|
|
25984
|
+
this.debugLog(`constructor()`);
|
|
25985
|
+
}
|
|
25986
|
+
debugLog(...data) {
|
|
25987
|
+
{
|
|
25988
|
+
return;
|
|
25989
|
+
}
|
|
25990
|
+
}
|
|
25930
25991
|
name = "d/:drive";
|
|
25931
25992
|
typeDefs = gql`
|
|
25932
25993
|
type Query {
|
|
@@ -26090,16 +26151,25 @@ var DriveSubgraph = class extends Subgraph {
|
|
|
26090
26151
|
},
|
|
26091
26152
|
Query: {
|
|
26092
26153
|
drive: async (_, args, ctx) => {
|
|
26154
|
+
this.debugLog(`drive()`, args);
|
|
26093
26155
|
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
26094
26156
|
const drive = await this.reactor.getDrive(ctx.driveId);
|
|
26095
|
-
return
|
|
26157
|
+
return {
|
|
26158
|
+
...drive.state.global,
|
|
26159
|
+
nodes: drive.state.global.nodes.map((n2) => ({
|
|
26160
|
+
...n2,
|
|
26161
|
+
__typename: driveKindTypeNames[n2.kind] || "UnkownDriveNode"
|
|
26162
|
+
}))
|
|
26163
|
+
};
|
|
26096
26164
|
},
|
|
26097
26165
|
documents: async (_, args, ctx) => {
|
|
26166
|
+
this.debugLog(`documents(drive: ${ctx.driveId})`, args);
|
|
26098
26167
|
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
26099
26168
|
const documents = await this.reactor.getDocuments(ctx.driveId);
|
|
26100
26169
|
return documents;
|
|
26101
26170
|
},
|
|
26102
26171
|
document: async (_, { id }, ctx) => {
|
|
26172
|
+
this.debugLog(`document(drive: ${ctx.driveId}, id: ${id})`);
|
|
26103
26173
|
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
26104
26174
|
const document = await this.reactor.getDocument(ctx.driveId, id);
|
|
26105
26175
|
const dms = this.reactor.getDocumentModels();
|
|
@@ -26129,6 +26199,10 @@ var DriveSubgraph = class extends Subgraph {
|
|
|
26129
26199
|
},
|
|
26130
26200
|
Mutation: {
|
|
26131
26201
|
registerPullResponderListener: async (_, { filter }, ctx) => {
|
|
26202
|
+
this.debugLog(
|
|
26203
|
+
`registerPullResponderListener(drive: ${ctx.driveId})`,
|
|
26204
|
+
filter
|
|
26205
|
+
);
|
|
26132
26206
|
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
26133
26207
|
const uuid = generateUUID2();
|
|
26134
26208
|
const listener = {
|
|
@@ -26159,54 +26233,36 @@ var DriveSubgraph = class extends Subgraph {
|
|
|
26159
26233
|
}
|
|
26160
26234
|
return listener;
|
|
26161
26235
|
},
|
|
26162
|
-
pushUpdates: async (_, { strands }, ctx) => {
|
|
26236
|
+
pushUpdates: async (_, { strands: strandsGql }, ctx) => {
|
|
26163
26237
|
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
26164
|
-
|
|
26165
|
-
|
|
26166
|
-
|
|
26167
|
-
|
|
26168
|
-
|
|
26169
|
-
|
|
26170
|
-
|
|
26238
|
+
this.debugLog(`pushUpdates(drive: ${ctx.driveId})`, strandsGql);
|
|
26239
|
+
const strands = strandsGql.map((strandGql) => {
|
|
26240
|
+
return {
|
|
26241
|
+
operations: strandGql.operations.map((op) => ({
|
|
26242
|
+
...op,
|
|
26243
|
+
input: JSON.parse(op.input),
|
|
26244
|
+
skip: op.skip ?? 0,
|
|
26245
|
+
scope: strandGql.scope,
|
|
26171
26246
|
branch: "main"
|
|
26172
|
-
}))
|
|
26173
|
-
|
|
26174
|
-
|
|
26175
|
-
|
|
26176
|
-
|
|
26177
|
-
|
|
26178
|
-
|
|
26179
|
-
|
|
26180
|
-
|
|
26181
|
-
const scopeOperations = result.document?.operations[s2.scope] ?? [];
|
|
26182
|
-
if (scopeOperations.length === 0) {
|
|
26183
|
-
return {
|
|
26184
|
-
revision: -1,
|
|
26185
|
-
branch: s2.branch,
|
|
26186
|
-
documentId: s2.documentId ?? "",
|
|
26187
|
-
driveId: s2.driveId,
|
|
26188
|
-
scope: s2.scope,
|
|
26189
|
-
status: result.status
|
|
26190
|
-
};
|
|
26191
|
-
}
|
|
26192
|
-
const revision = scopeOperations.slice().pop()?.index ?? -1;
|
|
26193
|
-
return {
|
|
26194
|
-
revision,
|
|
26195
|
-
branch: s2.branch,
|
|
26196
|
-
documentId: s2.documentId ?? "",
|
|
26197
|
-
driveId: s2.driveId,
|
|
26198
|
-
scope: s2.scope,
|
|
26199
|
-
status: result.status,
|
|
26200
|
-
error: result.error?.message || undefined
|
|
26201
|
-
};
|
|
26202
|
-
})
|
|
26247
|
+
})),
|
|
26248
|
+
documentId: strandGql.documentId,
|
|
26249
|
+
driveId: strandGql.driveId,
|
|
26250
|
+
scope: strandGql.scope,
|
|
26251
|
+
branch: strandGql.branch
|
|
26252
|
+
};
|
|
26253
|
+
});
|
|
26254
|
+
return await Promise.all(
|
|
26255
|
+
strands.map((strand) => processPushUpdate(this.reactor, strand))
|
|
26203
26256
|
);
|
|
26204
|
-
return listenerRevisions;
|
|
26205
26257
|
},
|
|
26206
26258
|
acknowledge: async (_, {
|
|
26207
26259
|
listenerId,
|
|
26208
26260
|
revisions
|
|
26209
26261
|
}, ctx) => {
|
|
26262
|
+
this.debugLog(
|
|
26263
|
+
`acknowledge(drive: ${ctx.driveId}, listenerId: ${listenerId})`,
|
|
26264
|
+
revisions
|
|
26265
|
+
);
|
|
26210
26266
|
if (!listenerId || !revisions) return false;
|
|
26211
26267
|
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
26212
26268
|
const validEntries = revisions.filter((r) => r !== null).map((e) => ({
|
|
@@ -26217,16 +26273,12 @@ var DriveSubgraph = class extends Subgraph {
|
|
|
26217
26273
|
revision: e.revision,
|
|
26218
26274
|
status: e.status
|
|
26219
26275
|
}));
|
|
26220
|
-
|
|
26276
|
+
return await processAcknowledge(
|
|
26277
|
+
this.reactor,
|
|
26221
26278
|
ctx.driveId,
|
|
26222
|
-
listenerId
|
|
26223
|
-
);
|
|
26224
|
-
const result = await transmitter.processAcknowledge(
|
|
26225
|
-
ctx.driveId ?? "1",
|
|
26226
26279
|
listenerId,
|
|
26227
26280
|
validEntries
|
|
26228
26281
|
);
|
|
26229
|
-
return result;
|
|
26230
26282
|
}
|
|
26231
26283
|
},
|
|
26232
26284
|
System: {},
|
|
@@ -26235,27 +26287,31 @@ var DriveSubgraph = class extends Subgraph {
|
|
|
26235
26287
|
listenerId,
|
|
26236
26288
|
since
|
|
26237
26289
|
}, ctx) => {
|
|
26290
|
+
this.debugLog(
|
|
26291
|
+
`strands(drive: ${ctx.driveId}, listenerId: ${listenerId}, since:${since})`
|
|
26292
|
+
);
|
|
26238
26293
|
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
26239
|
-
const
|
|
26294
|
+
const strands = await processGetStrands(
|
|
26295
|
+
this.reactor,
|
|
26240
26296
|
ctx.driveId,
|
|
26241
|
-
listenerId
|
|
26297
|
+
listenerId,
|
|
26298
|
+
since
|
|
26242
26299
|
);
|
|
26243
|
-
|
|
26244
|
-
|
|
26245
|
-
|
|
26246
|
-
|
|
26247
|
-
|
|
26248
|
-
|
|
26249
|
-
|
|
26250
|
-
|
|
26251
|
-
|
|
26252
|
-
|
|
26253
|
-
|
|
26254
|
-
|
|
26255
|
-
|
|
26256
|
-
|
|
26257
|
-
|
|
26258
|
-
id: o.id
|
|
26300
|
+
return strands.map((update) => ({
|
|
26301
|
+
driveId: update.driveId,
|
|
26302
|
+
documentId: update.documentId,
|
|
26303
|
+
scope: update.scope,
|
|
26304
|
+
branch: update.branch,
|
|
26305
|
+
operations: update.operations.map((op) => ({
|
|
26306
|
+
index: op.index,
|
|
26307
|
+
skip: op.skip,
|
|
26308
|
+
name: op.type,
|
|
26309
|
+
input: JSON.stringify(op.input),
|
|
26310
|
+
hash: op.hash,
|
|
26311
|
+
timestamp: op.timestamp,
|
|
26312
|
+
type: op.type,
|
|
26313
|
+
context: op.context,
|
|
26314
|
+
id: op.id
|
|
26259
26315
|
}))
|
|
26260
26316
|
}));
|
|
26261
26317
|
}
|