@dxos/echo-pipeline 0.4.8 → 0.4.9-main.1057b49

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 (55) hide show
  1. package/dist/lib/browser/{chunk-WAN2XUWE.mjs → chunk-RTEEJ723.mjs} +273 -1131
  2. package/dist/lib/browser/chunk-RTEEJ723.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +2 -10
  4. package/dist/lib/browser/index.mjs.map +3 -3
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +4 -60
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node/{chunk-U6J2HC4T.cjs → chunk-7VZVCCNF.cjs} +310 -1166
  9. package/dist/lib/node/chunk-7VZVCCNF.cjs.map +7 -0
  10. package/dist/lib/node/index.cjs +22 -30
  11. package/dist/lib/node/index.cjs.map +3 -3
  12. package/dist/lib/node/meta.json +1 -1
  13. package/dist/lib/node/testing/index.cjs +13 -68
  14. package/dist/lib/node/testing/index.cjs.map +4 -4
  15. package/dist/types/src/db-host/data-service.d.ts +3 -13
  16. package/dist/types/src/db-host/data-service.d.ts.map +1 -1
  17. package/dist/types/src/db-host/index.d.ts +0 -2
  18. package/dist/types/src/db-host/index.d.ts.map +1 -1
  19. package/dist/types/src/space/index.d.ts +0 -1
  20. package/dist/types/src/space/index.d.ts.map +1 -1
  21. package/dist/types/src/space/space-manager.d.ts +1 -4
  22. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  23. package/dist/types/src/space/space.d.ts +1 -7
  24. package/dist/types/src/space/space.d.ts.map +1 -1
  25. package/dist/types/src/testing/index.d.ts +0 -1
  26. package/dist/types/src/testing/index.d.ts.map +1 -1
  27. package/dist/types/src/testing/test-agent-builder.d.ts +1 -3
  28. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  29. package/package.json +30 -33
  30. package/src/automerge/automerge-host.ts +1 -1
  31. package/src/db-host/data-service.ts +10 -56
  32. package/src/db-host/index.ts +0 -2
  33. package/src/space/index.ts +0 -1
  34. package/src/space/space-manager.ts +1 -13
  35. package/src/space/space.test.ts +2 -112
  36. package/src/space/space.ts +2 -60
  37. package/src/testing/index.ts +0 -1
  38. package/src/testing/test-agent-builder.ts +3 -8
  39. package/dist/lib/browser/chunk-WAN2XUWE.mjs.map +0 -7
  40. package/dist/lib/node/chunk-U6J2HC4T.cjs.map +0 -7
  41. package/dist/types/src/db-host/data-service-host.d.ts +0 -38
  42. package/dist/types/src/db-host/data-service-host.d.ts.map +0 -1
  43. package/dist/types/src/db-host/database-host.d.ts +0 -27
  44. package/dist/types/src/db-host/database-host.d.ts.map +0 -1
  45. package/dist/types/src/space/data-pipeline.d.ts +0 -79
  46. package/dist/types/src/space/data-pipeline.d.ts.map +0 -1
  47. package/dist/types/src/space/data-pipeline.test.d.ts +0 -1
  48. package/dist/types/src/space/data-pipeline.test.d.ts.map +0 -1
  49. package/dist/types/src/testing/util.d.ts +0 -10
  50. package/dist/types/src/testing/util.d.ts.map +0 -1
  51. package/src/db-host/data-service-host.ts +0 -233
  52. package/src/db-host/database-host.ts +0 -63
  53. package/src/space/data-pipeline.test.ts +0 -3
  54. package/src/space/data-pipeline.ts +0 -425
  55. package/src/testing/util.ts +0 -61
@@ -1,233 +0,0 @@
1
- //
2
- // Copyright 2021 DXOS.org
3
- //
4
-
5
- import { UpdateScheduler } from '@dxos/async';
6
- import { Stream } from '@dxos/codec-protobuf';
7
- import { Context } from '@dxos/context';
8
- import { tagMutationsInBatch, type ItemDemuxer, type ItemManager, setMetadataOnObject } from '@dxos/echo-db';
9
- import { type FeedWriter } from '@dxos/feed-store';
10
- import { invariant } from '@dxos/invariant';
11
- import { type PublicKey } from '@dxos/keys';
12
- import { log } from '@dxos/log';
13
- import { type DataMessage } from '@dxos/protocols/proto/dxos/echo/feed';
14
- import { type EchoObject, type EchoObjectBatch } from '@dxos/protocols/proto/dxos/echo/object';
15
- import {
16
- EchoEvent,
17
- type SyncRepoRequest,
18
- type MutationReceipt,
19
- type WriteRequest,
20
- type SyncRepoResponse,
21
- type HostInfo,
22
- } from '@dxos/protocols/proto/dxos/echo/service';
23
- import { ComplexMap } from '@dxos/util';
24
-
25
- // After this limit the incremental object updates will be replaced with the full snapshot of the object.
26
- const MUTATION_LIMIT_PER_OBJECT = 10;
27
-
28
- export type DataServiceHostOptions = {
29
- /**
30
- * @default true
31
- */
32
- deferEvents?: boolean;
33
- };
34
-
35
- /**
36
- * Provides methods for DataService for a single space.
37
- * A DataServiceRouter must be placed before it to route requests to different DataServiceHost instances based on space id.
38
- */
39
- // TODO(burdon): Move to client-services.
40
- export class DataServiceHost {
41
- private readonly _ctx = new Context();
42
-
43
- private readonly _clientTagMap = new ComplexMap<[feedKey: PublicKey, seq: number], string>(
44
- ([feedKey, seq]) => `${feedKey.toHex()}:${seq}`,
45
- );
46
-
47
- constructor(
48
- private readonly _itemManager: ItemManager,
49
- private readonly _itemDemuxer: ItemDemuxer,
50
- private readonly _flush: () => Promise<void>,
51
- private readonly _writeStream: FeedWriter<DataMessage> | undefined,
52
- private readonly _opts: DataServiceHostOptions = {},
53
- ) {}
54
-
55
- async open() {}
56
-
57
- async close() {
58
- await this._ctx.dispose();
59
- }
60
-
61
- private get _deferEvents(): boolean {
62
- return this._opts.deferEvents ?? true;
63
- }
64
-
65
- /**
66
- * Real-time subscription to data objects in a space.
67
- */
68
- subscribe(): Stream<EchoEvent> {
69
- return new Stream(({ next, close, ctx }) => {
70
- // This looks ridiculous..
71
- ctx.onDispose(this._ctx.onDispose(close));
72
-
73
- // send current state
74
- const objects = Array.from(this._itemManager.entities.values()).map((entity) => entity.createSnapshot());
75
- next({
76
- batch: {
77
- objects,
78
- },
79
- });
80
-
81
- const updateScheduler = new UpdateScheduler(
82
- ctx,
83
- async () => {
84
- flushPendingUpdate();
85
- },
86
- {
87
- maxFrequency: 10,
88
- },
89
- );
90
-
91
- const pendingUpdates: EchoObject[] = [];
92
- const mutationsPerObject = new Map<string, number>();
93
-
94
- const clearPendingUpdates = () => {
95
- pendingUpdates.length = 0;
96
- mutationsPerObject.clear();
97
- };
98
-
99
- const flushPendingUpdate = () => {
100
- const stagedEvents: EchoObject[] = [];
101
- const objectsWithSnapshots = new Set<string>();
102
- for (const [id, count] of mutationsPerObject) {
103
- if (count >= MUTATION_LIMIT_PER_OBJECT) {
104
- objectsWithSnapshots.add(id);
105
- const entity = this._itemManager.entities.get(id);
106
- if (entity) {
107
- stagedEvents.push(entity.createSnapshot());
108
- }
109
- }
110
- }
111
-
112
- for (const obj of pendingUpdates) {
113
- if (!objectsWithSnapshots.has(obj.objectId)) {
114
- stagedEvents.push(obj);
115
- }
116
- }
117
-
118
- next({
119
- batch: {
120
- objects: stagedEvents,
121
- },
122
- });
123
- clearPendingUpdates();
124
- };
125
-
126
- // Subscribe to clear events on Epoch processing.
127
- this._itemDemuxer.snapshot.on(ctx, (snapshot) => {
128
- clearPendingUpdates();
129
- next({
130
- action: EchoEvent.DatabaseAction.RESET,
131
- batch: { objects: snapshot.items },
132
- });
133
- });
134
-
135
- // Subscribe to mutations.
136
- this._itemDemuxer.mutation.on(ctx, (message) => {
137
- const { batch, meta } = message;
138
- invariant(!(meta as any).clientTag, 'Unexpected client tag in mutation message');
139
- log('message', { batch: batch.objects?.length, meta });
140
-
141
- const clientTag = this._clientTagMap.get([message.meta.feedKey, message.meta.seq]);
142
- // TODO(dmaretskyi): Memory leak with _clientTagMap not getting cleared.
143
-
144
- // Assign feed metadata
145
- batch.objects?.forEach((object) => {
146
- setMetadataOnObject(object, { ...meta });
147
- });
148
-
149
- // Assign client tag metadata
150
- if (clientTag) {
151
- flushPendingUpdate();
152
-
153
- tagMutationsInBatch(batch, clientTag, 0);
154
-
155
- next({
156
- clientTag,
157
- feedKey: message.meta.feedKey,
158
- seq: message.meta.seq,
159
- batch,
160
- });
161
- } else {
162
- for (const obj of batch.objects ?? []) {
163
- const newCount = (mutationsPerObject.get(obj.objectId) ?? 0) + 1;
164
- mutationsPerObject.set(obj.objectId, newCount);
165
- }
166
-
167
- for (const obj of batch.objects ?? []) {
168
- if ((mutationsPerObject.get(obj.objectId) ?? 0) < MUTATION_LIMIT_PER_OBJECT) {
169
- pendingUpdates.push(obj);
170
- }
171
- }
172
-
173
- if (this._deferEvents) {
174
- updateScheduler.trigger();
175
- } else {
176
- flushPendingUpdate();
177
- }
178
- }
179
- });
180
- });
181
- }
182
-
183
- async write(request: WriteRequest): Promise<MutationReceipt> {
184
- invariant(!this._ctx.disposed, 'Cannot write to closed DataServiceHost');
185
- invariant(this._writeStream, 'Cannot write mutations in readonly mode');
186
-
187
- log('write', { clientTag: request.clientTag, objectCount: request.batch.objects?.length ?? 0 });
188
-
189
- // Clear client metadata.
190
- const message = createDataMessage(request.batch);
191
-
192
- const receipt = await this._writeStream.write(message, {
193
- afterWrite: async (receipt) => {
194
- // Runs before the mutation is read from the pipeline.
195
- if (request.clientTag) {
196
- log('tag', { clientTag: request.clientTag, feedKey: receipt.feedKey, seq: receipt.seq });
197
- this._clientTagMap.set([receipt.feedKey, receipt.seq], request.clientTag);
198
- }
199
- },
200
- });
201
-
202
- return receipt;
203
- }
204
-
205
- async flush(): Promise<void> {
206
- await this._flush();
207
- }
208
-
209
- getHostInfo(): Promise<HostInfo> {
210
- throw new Error('Method not implemented.');
211
- }
212
-
213
- syncRepo(request: SyncRepoRequest): Stream<SyncRepoResponse> {
214
- throw new Error('Method not implemented.');
215
- }
216
-
217
- sendSyncMessage(request: SyncRepoRequest): Promise<void> {
218
- throw new Error('Method not implemented.');
219
- }
220
- }
221
-
222
- const createDataMessage = (batch: EchoObjectBatch) => ({
223
- batch: {
224
- objects: batch.objects?.map((object) => ({
225
- ...object,
226
- mutations: object.mutations?.map((mutation) => ({
227
- ...mutation,
228
- meta: undefined,
229
- })),
230
- meta: undefined,
231
- })),
232
- },
233
- });
@@ -1,63 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import { type EchoProcessor, ItemDemuxer, type ItemManager } from '@dxos/echo-db';
6
- import { type FeedWriter } from '@dxos/feed-store';
7
- import { type ModelFactory } from '@dxos/model-factory';
8
- import { type DataMessage } from '@dxos/protocols/proto/dxos/echo/feed';
9
- import { type EchoSnapshot } from '@dxos/protocols/proto/dxos/echo/snapshot';
10
-
11
- import { DataServiceHost, type DataServiceHostOptions } from './data-service-host';
12
-
13
- /**
14
- * Database backend that operates on two streams: read and write.
15
- * Mutations are read from the incoming streams and applied to the ItemManager via ItemDemuxer.
16
- * Write operations result in mutations being written to the outgoing stream.
17
- */
18
- export class DatabaseHost {
19
- private _echoProcessor!: EchoProcessor;
20
- private _itemManager!: ItemManager;
21
- public _itemDemuxer!: ItemDemuxer;
22
-
23
- constructor(
24
- private readonly _outboundStream: FeedWriter<DataMessage> | undefined,
25
- private readonly _flush: () => Promise<void>,
26
- ) {}
27
-
28
- get isReadOnly(): boolean {
29
- return !!this._outboundStream;
30
- }
31
-
32
- get echoProcessor() {
33
- return this._echoProcessor;
34
- }
35
-
36
- async open(itemManager: ItemManager, modelFactory: ModelFactory) {
37
- this._itemManager = itemManager;
38
- this._itemManager._debugLabel = 'host';
39
-
40
- this._itemDemuxer = new ItemDemuxer(itemManager, modelFactory);
41
- this._echoProcessor = this._itemDemuxer.open();
42
- }
43
-
44
- async close() {}
45
-
46
- getWriteStream(): FeedWriter<DataMessage> | undefined {
47
- return this._outboundStream;
48
- }
49
-
50
- createSnapshot(): EchoSnapshot {
51
- return this._itemDemuxer.createSnapshot();
52
- }
53
-
54
- createDataServiceHost(opts: DataServiceHostOptions = {}) {
55
- return new DataServiceHost(
56
- this._itemManager,
57
- this._itemDemuxer,
58
- this._flush,
59
- this._outboundStream ?? undefined,
60
- opts,
61
- );
62
- }
63
- }
@@ -1,3 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //