@powerhousedao/reactor-api 1.20.2 → 1.21.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/CHANGELOG.md +0 -20
- package/dist/index.d.ts +63 -76
- package/dist/index.js +87 -64
- package/dist/index.js.map +1 -1
- package/package.json +9 -6
- package/src/subgraphs/drive/index.ts +55 -74
- 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,23 +1,3 @@
|
|
|
1
|
-
## 1.20.2 (2025-02-10)
|
|
2
|
-
|
|
3
|
-
### 🚀 Features
|
|
4
|
-
|
|
5
|
-
- **design-system:** add danger zone settings page ([572345bc](https://github.com/powerhouse-inc/powerhouse/commit/572345bc))
|
|
6
|
-
|
|
7
|
-
### 🩹 Fixes
|
|
8
|
-
|
|
9
|
-
- **reactor-api:** sanitize document model name before using it as __typename ([adcca457](https://github.com/powerhouse-inc/powerhouse/commit/adcca457))
|
|
10
|
-
|
|
11
|
-
### 🧱 Updated Dependencies
|
|
12
|
-
|
|
13
|
-
- Updated document-model-libs to 1.131.2
|
|
14
|
-
- Updated document-drive to 1.17.2
|
|
15
|
-
|
|
16
|
-
### ❤️ Thank You
|
|
17
|
-
|
|
18
|
-
- ryanwolhuter @ryanwolhuter
|
|
19
|
-
- Wouter Kampmann
|
|
20
|
-
|
|
21
1
|
## 1.2.0 (2024-10-29)
|
|
22
2
|
|
|
23
3
|
### 🚀 Features
|
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>;
|
package/dist/index.js
CHANGED
|
@@ -25926,6 +25926,55 @@ 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
|
+
|
|
25977
|
+
// src/subgraphs/drive/index.ts
|
|
25929
25978
|
var DriveSubgraph = class extends Subgraph {
|
|
25930
25979
|
name = "d/:drive";
|
|
25931
25980
|
typeDefs = gql`
|
|
@@ -26159,49 +26208,26 @@ var DriveSubgraph = class extends Subgraph {
|
|
|
26159
26208
|
}
|
|
26160
26209
|
return listener;
|
|
26161
26210
|
},
|
|
26162
|
-
pushUpdates: async (_, { strands }, ctx) => {
|
|
26211
|
+
pushUpdates: async (_, { strands: strandsGql }, ctx) => {
|
|
26163
26212
|
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
26164
|
-
const
|
|
26165
|
-
|
|
26166
|
-
|
|
26167
|
-
...
|
|
26168
|
-
input: JSON.parse(
|
|
26169
|
-
skip:
|
|
26170
|
-
scope:
|
|
26213
|
+
const strands = strandsGql.map((strandGql) => {
|
|
26214
|
+
return {
|
|
26215
|
+
operations: strandGql.operations.map((op) => ({
|
|
26216
|
+
...op,
|
|
26217
|
+
input: JSON.parse(op.input),
|
|
26218
|
+
skip: op.skip ?? 0,
|
|
26219
|
+
scope: strandGql.scope,
|
|
26171
26220
|
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
|
-
})
|
|
26221
|
+
})),
|
|
26222
|
+
documentId: strandGql.documentId,
|
|
26223
|
+
driveId: strandGql.driveId,
|
|
26224
|
+
scope: strandGql.scope,
|
|
26225
|
+
branch: strandGql.branch
|
|
26226
|
+
};
|
|
26227
|
+
});
|
|
26228
|
+
return await Promise.all(
|
|
26229
|
+
strands.map((strand) => processPushUpdate(this.reactor, strand))
|
|
26203
26230
|
);
|
|
26204
|
-
return listenerRevisions;
|
|
26205
26231
|
},
|
|
26206
26232
|
acknowledge: async (_, {
|
|
26207
26233
|
listenerId,
|
|
@@ -26217,16 +26243,12 @@ var DriveSubgraph = class extends Subgraph {
|
|
|
26217
26243
|
revision: e.revision,
|
|
26218
26244
|
status: e.status
|
|
26219
26245
|
}));
|
|
26220
|
-
|
|
26246
|
+
return await processAcknowledge(
|
|
26247
|
+
this.reactor,
|
|
26221
26248
|
ctx.driveId,
|
|
26222
|
-
listenerId
|
|
26223
|
-
);
|
|
26224
|
-
const result = await transmitter.processAcknowledge(
|
|
26225
|
-
ctx.driveId ?? "1",
|
|
26226
26249
|
listenerId,
|
|
26227
26250
|
validEntries
|
|
26228
26251
|
);
|
|
26229
|
-
return result;
|
|
26230
26252
|
}
|
|
26231
26253
|
},
|
|
26232
26254
|
System: {},
|
|
@@ -26236,26 +26258,27 @@ var DriveSubgraph = class extends Subgraph {
|
|
|
26236
26258
|
since
|
|
26237
26259
|
}, ctx) => {
|
|
26238
26260
|
if (!ctx.driveId) throw new Error("Drive ID is required");
|
|
26239
|
-
const
|
|
26261
|
+
const strands = await processGetStrands(
|
|
26262
|
+
this.reactor,
|
|
26240
26263
|
ctx.driveId,
|
|
26241
|
-
listenerId
|
|
26264
|
+
listenerId,
|
|
26265
|
+
since
|
|
26242
26266
|
);
|
|
26243
|
-
|
|
26244
|
-
|
|
26245
|
-
|
|
26246
|
-
|
|
26247
|
-
|
|
26248
|
-
|
|
26249
|
-
|
|
26250
|
-
|
|
26251
|
-
|
|
26252
|
-
|
|
26253
|
-
|
|
26254
|
-
|
|
26255
|
-
|
|
26256
|
-
|
|
26257
|
-
|
|
26258
|
-
id: o.id
|
|
26267
|
+
return strands.map((update) => ({
|
|
26268
|
+
driveId: update.driveId,
|
|
26269
|
+
documentId: update.documentId,
|
|
26270
|
+
scope: update.scope,
|
|
26271
|
+
branch: update.branch,
|
|
26272
|
+
operations: update.operations.map((op) => ({
|
|
26273
|
+
index: op.index,
|
|
26274
|
+
skip: op.skip,
|
|
26275
|
+
name: op.type,
|
|
26276
|
+
input: JSON.stringify(op.input),
|
|
26277
|
+
hash: op.hash,
|
|
26278
|
+
timestamp: op.timestamp,
|
|
26279
|
+
type: op.type,
|
|
26280
|
+
context: op.context,
|
|
26281
|
+
id: op.id
|
|
26259
26282
|
}))
|
|
26260
26283
|
}));
|
|
26261
26284
|
}
|