@dxos/echo-pipeline 0.1.41 → 0.1.45-next.45667d4

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 (74) hide show
  1. package/dist/lib/browser/{chunk-4YAT2XJW.mjs → chunk-2NGLSBL4.mjs} +1128 -1017
  2. package/dist/lib/browser/chunk-2NGLSBL4.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +1 -3
  4. package/dist/lib/browser/index.mjs.map +1 -1
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +72 -48
  7. package/dist/lib/browser/testing/index.mjs.map +3 -3
  8. package/dist/lib/node/index.cjs +1048 -938
  9. package/dist/lib/node/index.cjs.map +4 -4
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/testing/index.cjs +735 -540
  12. package/dist/lib/node/testing/index.cjs.map +4 -4
  13. package/dist/types/src/dbhost/database-host.d.ts +2 -4
  14. package/dist/types/src/dbhost/database-host.d.ts.map +1 -1
  15. package/dist/types/src/dbhost/snapshot-store.d.ts +2 -0
  16. package/dist/types/src/dbhost/snapshot-store.d.ts.map +1 -1
  17. package/dist/types/src/metadata/metadata-store.d.ts +3 -2
  18. package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
  19. package/dist/types/src/pipeline/pipeline.d.ts +27 -11
  20. package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
  21. package/dist/types/src/pipeline/timeframe-clock.d.ts +1 -0
  22. package/dist/types/src/pipeline/timeframe-clock.d.ts.map +1 -1
  23. package/dist/types/src/space/auth.d.ts +4 -4
  24. package/dist/types/src/space/auth.d.ts.map +1 -1
  25. package/dist/types/src/space/control-pipeline.d.ts +2 -4
  26. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  27. package/dist/types/src/space/data-pipeline.d.ts +19 -10
  28. package/dist/types/src/space/data-pipeline.d.ts.map +1 -1
  29. package/dist/types/src/space/index.d.ts +0 -1
  30. package/dist/types/src/space/index.d.ts.map +1 -1
  31. package/dist/types/src/space/space-manager.d.ts +14 -14
  32. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  33. package/dist/types/src/space/space-protocol.d.ts +2 -2
  34. package/dist/types/src/space/space-protocol.d.ts.map +1 -1
  35. package/dist/types/src/space/space.d.ts +20 -7
  36. package/dist/types/src/space/space.d.ts.map +1 -1
  37. package/dist/types/src/testing/database-test-rig.d.ts.map +1 -1
  38. package/dist/types/src/testing/test-agent-builder.d.ts +15 -5
  39. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  40. package/package.json +30 -30
  41. package/src/common/feeds.ts +2 -2
  42. package/src/dbhost/data-service-host.ts +10 -10
  43. package/src/dbhost/data-service.ts +1 -1
  44. package/src/dbhost/database-host.ts +1 -9
  45. package/src/dbhost/snapshot-store.test.ts +2 -2
  46. package/src/dbhost/snapshot-store.ts +16 -1
  47. package/src/metadata/metadata-store.ts +14 -16
  48. package/src/pipeline/message-selector.ts +1 -1
  49. package/src/pipeline/pipeline.test.ts +68 -44
  50. package/src/pipeline/pipeline.ts +118 -35
  51. package/src/pipeline/timeframe-clock.ts +8 -2
  52. package/src/space/auth.ts +6 -6
  53. package/src/space/control-pipeline.test.ts +19 -20
  54. package/src/space/control-pipeline.ts +3 -5
  55. package/src/space/data-pipeline.ts +131 -69
  56. package/src/space/index.ts +0 -1
  57. package/src/space/replication.browser.test.ts +8 -8
  58. package/src/space/space-manager.browser.test.ts +3 -3
  59. package/src/space/space-manager.ts +25 -20
  60. package/src/space/space-protocol.browser.test.ts +1 -1
  61. package/src/space/space-protocol.test.ts +6 -6
  62. package/src/space/space-protocol.ts +7 -7
  63. package/src/space/space.test.ts +137 -48
  64. package/src/space/space.ts +82 -40
  65. package/src/testing/database-test-rig.ts +25 -24
  66. package/src/testing/test-agent-builder.ts +88 -49
  67. package/src/testing/test-feed-builder.ts +1 -1
  68. package/src/testing/util.ts +15 -15
  69. package/src/tests/database-unit.test.ts +4 -4
  70. package/src/tests/database.test.ts +1 -1
  71. package/dist/lib/browser/chunk-4YAT2XJW.mjs.map +0 -7
  72. package/dist/types/src/space/genesis.d.ts +0 -5
  73. package/dist/types/src/space/genesis.d.ts.map +0 -1
  74. package/src/space/genesis.ts +0 -69
@@ -1 +1 @@
1
- {"version":3,"file":"test-agent-builder.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-agent-builder.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAuB,0BAA0B,EAA0B,MAAM,iBAAiB,CAAC;AAE1G,OAAO,EAAwD,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC7G,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACxE,OAAO,EAAiB,OAAO,EAAe,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAKnE,OAAO,EAA0C,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACtG,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,oBAAY,sBAAsB,GAAG,MAAM,cAAc,CAAC;AAE1D,eAAO,MAAM,4BAA4B,kBACvB,0BAA0B,KAAG,sBAKzC,CAAC;AAEP,eAAO,MAAM,+BAA+B,cAC9B,MAAM,KAAG,sBAKjB,CAAC;AAEP,oBAAY,uBAAuB,GAAG;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;CACjD,CAAC;AAEF;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwD;IAChF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAyB;gBAErD,EAAE,OAAO,EAAE,sBAAsB,EAAE,GAAE,uBAA4B;IAMvE,KAAK;IAIX,IAAI,MAAM,gBAET;IAED,QAAQ,CAAC,SAAS,EAAE,SAAS;IAIvB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC;CAYvC;AAED;;GAEG;AACH,qBAAa,SAAS;IAOlB,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY;aACb,WAAW,EAAE,SAAS;aACtB,SAAS,EAAE,SAAS;IATtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoD;IAE5E,SAAgB,OAAO,EAAE,OAAO,CAAC;IACjC,SAAgB,SAAS,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;gBAG/B,uBAAuB,EAAE,sBAAsB,EAC/C,YAAY,EAAE,eAAe,EAC9B,WAAW,EAAE,SAAS,EACtB,SAAS,EAAE,SAAS;IAMhC,KAAK;IAIX,IAAI,MAAM,YAET;IAED,QAAQ,CAAC,QAAQ,EAAE,SAAS;IAI5B,kBAAkB;IAOZ,WAAW,CACf,WAAW,GAAE,SAA4B,EACzC,QAAQ,CAAC,EAAE,SAAS,EACpB,UAAU,CAAC,EAAE,SAAS,GACrB,OAAO,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IA6CjC,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM;IAkBrD,YAAY;IAMZ,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM;CAQ/B"}
1
+ {"version":3,"file":"test-agent-builder.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-agent-builder.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/echo-pipeline",
3
- "version": "0.1.41",
3
+ "version": "0.1.45-next.45667d4",
4
4
  "description": "ECHO database.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -21,34 +21,34 @@
21
21
  "dependencies": {
22
22
  "crc-32": "^1.2.2",
23
23
  "debug": "^4.3.3",
24
- "@dxos/async": "0.1.41",
25
- "@dxos/codec-protobuf": "0.1.41",
26
- "@dxos/context": "0.1.41",
27
- "@dxos/credentials": "0.1.41",
28
- "@dxos/crypto": "0.1.41",
29
- "@dxos/debug": "0.1.41",
30
- "@dxos/document-model": "0.1.41",
31
- "@dxos/echo-db": "0.1.41",
32
- "@dxos/errors": "0.1.41",
33
- "@dxos/feed-store": "0.1.41",
34
- "@dxos/hypercore": "0.1.41",
35
- "@dxos/keyring": "0.1.41",
36
- "@dxos/keys": "0.1.41",
37
- "@dxos/log": "0.1.41",
38
- "@dxos/messaging": "0.1.41",
39
- "@dxos/model-factory": "0.1.41",
40
- "@dxos/network-manager": "0.1.41",
41
- "@dxos/node-std": "0.1.41",
42
- "@dxos/protocols": "0.1.41",
43
- "@dxos/random-access-storage": "0.1.41",
44
- "@dxos/rpc": "0.1.41",
45
- "@dxos/teleport": "0.1.41",
46
- "@dxos/teleport-extension-gossip": "0.1.41",
47
- "@dxos/teleport-extension-object-sync": "0.1.41",
48
- "@dxos/teleport-extension-replicator": "0.1.41",
49
- "@dxos/timeframe": "0.1.41",
50
- "@dxos/typings": "0.1.41",
51
- "@dxos/util": "0.1.41"
24
+ "@dxos/async": "0.1.45-next.45667d4",
25
+ "@dxos/codec-protobuf": "0.1.45-next.45667d4",
26
+ "@dxos/context": "0.1.45-next.45667d4",
27
+ "@dxos/credentials": "0.1.45-next.45667d4",
28
+ "@dxos/crypto": "0.1.45-next.45667d4",
29
+ "@dxos/debug": "0.1.45-next.45667d4",
30
+ "@dxos/document-model": "0.1.45-next.45667d4",
31
+ "@dxos/echo-db": "0.1.45-next.45667d4",
32
+ "@dxos/errors": "0.1.45-next.45667d4",
33
+ "@dxos/feed-store": "0.1.45-next.45667d4",
34
+ "@dxos/hypercore": "0.1.45-next.45667d4",
35
+ "@dxos/keyring": "0.1.45-next.45667d4",
36
+ "@dxos/keys": "0.1.45-next.45667d4",
37
+ "@dxos/log": "0.1.45-next.45667d4",
38
+ "@dxos/messaging": "0.1.45-next.45667d4",
39
+ "@dxos/model-factory": "0.1.45-next.45667d4",
40
+ "@dxos/network-manager": "0.1.45-next.45667d4",
41
+ "@dxos/node-std": "0.1.45-next.45667d4",
42
+ "@dxos/protocols": "0.1.45-next.45667d4",
43
+ "@dxos/random-access-storage": "0.1.45-next.45667d4",
44
+ "@dxos/rpc": "0.1.45-next.45667d4",
45
+ "@dxos/teleport": "0.1.45-next.45667d4",
46
+ "@dxos/teleport-extension-gossip": "0.1.45-next.45667d4",
47
+ "@dxos/teleport-extension-object-sync": "0.1.45-next.45667d4",
48
+ "@dxos/teleport-extension-replicator": "0.1.45-next.45667d4",
49
+ "@dxos/timeframe": "0.1.45-next.45667d4",
50
+ "@dxos/typings": "0.1.45-next.45667d4",
51
+ "@dxos/util": "0.1.45-next.45667d4"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/debug": "^4.1.7",
@@ -56,7 +56,7 @@
56
56
  "hypercore-protocol": "^8.0.7",
57
57
  "source-map-support": "^0.5.12",
58
58
  "wait-for-expect": "^3.0.2",
59
- "@dxos/text-model": "0.1.41"
59
+ "@dxos/text-model": "0.1.45-next.45667d4"
60
60
  },
61
61
  "publishConfig": {
62
62
  "access": "public"
@@ -12,12 +12,12 @@ import { MaybePromise } from '@dxos/util';
12
12
  */
13
13
  export const createMappedFeedWriter = <Source extends {}, Target extends {}>(
14
14
  mapper: (arg: Source) => MaybePromise<Target>,
15
- writer: FeedWriter<Target>
15
+ writer: FeedWriter<Target>,
16
16
  ): FeedWriter<Source> => {
17
17
  assert(mapper);
18
18
  assert(writer);
19
19
 
20
20
  return {
21
- write: async (data: Source, options) => await writer.write(await mapper(data), options)
21
+ write: async (data: Source, options) => await writer.write(await mapper(data), options),
22
22
  };
23
23
  };
@@ -20,13 +20,13 @@ import { ComplexMap } from '@dxos/util';
20
20
  // TODO(burdon): Move to client-services.
21
21
  export class DataServiceHost {
22
22
  private readonly _clientTagMap = new ComplexMap<[feedKey: PublicKey, seq: number], string>(
23
- ([feedKey, seq]) => `${feedKey.toHex()}:${seq}`
23
+ ([feedKey, seq]) => `${feedKey.toHex()}:${seq}`,
24
24
  );
25
25
 
26
26
  constructor(
27
27
  private readonly _itemManager: ItemManager,
28
28
  private readonly _itemDemuxer: ItemDemuxer,
29
- private readonly _writeStream?: FeedWriter<DataMessage>
29
+ private readonly _writeStream?: FeedWriter<DataMessage>,
30
30
  ) {}
31
31
 
32
32
  /**
@@ -38,8 +38,8 @@ export class DataServiceHost {
38
38
  const objects = Array.from(this._itemManager.entities.values()).map((entity) => entity.createSnapshot());
39
39
  next({
40
40
  batch: {
41
- objects
42
- }
41
+ objects,
42
+ },
43
43
  });
44
44
 
45
45
  // subscribe to mutations
@@ -65,7 +65,7 @@ export class DataServiceHost {
65
65
  clientTag,
66
66
  feedKey: message.meta.feedKey,
67
67
  seq: message.meta.seq,
68
- batch
68
+ batch,
69
69
  });
70
70
  });
71
71
  });
@@ -83,11 +83,11 @@ export class DataServiceHost {
83
83
  ...object,
84
84
  mutations: object.mutations?.map((mutation) => ({
85
85
  ...mutation,
86
- meta: undefined
86
+ meta: undefined,
87
87
  })),
88
- meta: undefined
89
- }))
90
- }
88
+ meta: undefined,
89
+ })),
90
+ },
91
91
  };
92
92
  const receipt = await this._writeStream.write(message, {
93
93
  afterWrite: async (receipt) => {
@@ -96,7 +96,7 @@ export class DataServiceHost {
96
96
  log('tag', { clientTag: request.clientTag, feedKey: receipt.feedKey, seq: receipt.seq });
97
97
  this._clientTagMap.set([receipt.feedKey, receipt.seq], request.clientTag);
98
98
  }
99
- }
99
+ },
100
100
  });
101
101
 
102
102
  return receipt;
@@ -13,7 +13,7 @@ import {
13
13
  MutationReceipt,
14
14
  SubscribeRequest,
15
15
  EchoEvent,
16
- WriteRequest
16
+ WriteRequest,
17
17
  } from '@dxos/protocols/proto/dxos/echo/service';
18
18
  import { ComplexMap } from '@dxos/util';
19
19
 
@@ -8,7 +8,6 @@ import { EchoProcessor, ItemDemuxer, ItemManager } from '@dxos/echo-db';
8
8
  import { FeedWriter } from '@dxos/feed-store';
9
9
  import { ModelFactory } from '@dxos/model-factory';
10
10
  import { DataMessage } from '@dxos/protocols/proto/dxos/echo/feed';
11
- import { EchoSnapshot } from '@dxos/protocols/proto/dxos/echo/snapshot';
12
11
 
13
12
  import { DataServiceHost } from './data-service-host';
14
13
 
@@ -22,10 +21,7 @@ export class DatabaseHost {
22
21
  private _itemManager!: ItemManager;
23
22
  public _itemDemuxer!: ItemDemuxer;
24
23
 
25
- constructor(
26
- private readonly _outboundStream: FeedWriter<DataMessage> | undefined,
27
- private readonly _snapshot?: EchoSnapshot
28
- ) {}
24
+ constructor(private readonly _outboundStream: FeedWriter<DataMessage> | undefined) {}
29
25
 
30
26
  get isReadOnly(): boolean {
31
27
  return !!this._outboundStream;
@@ -41,10 +37,6 @@ export class DatabaseHost {
41
37
 
42
38
  this._itemDemuxer = new ItemDemuxer(itemManager, modelFactory);
43
39
  this._echoProcessor = this._itemDemuxer.open();
44
-
45
- if (this._snapshot) {
46
- this._itemDemuxer.restoreFromSnapshot(this._snapshot);
47
- }
48
40
  }
49
41
 
50
42
  async close() {}
@@ -20,8 +20,8 @@ describe('SnapshotStore', () => {
20
20
  spaceKey: PublicKey.random().asBuffer(),
21
21
  timeframe: new Timeframe(),
22
22
  database: {
23
- items: []
24
- }
23
+ items: [],
24
+ },
25
25
  };
26
26
 
27
27
  const key = await store.saveSnapshot(snapshot);
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { subtleCrypto } from '@dxos/crypto';
6
6
  import { schema } from '@dxos/protocols';
7
+ import { StoredSnapshotInfo } from '@dxos/protocols/proto/dxos/devtools/host';
7
8
  import { SpaceSnapshot } from '@dxos/protocols/proto/dxos/echo/snapshot';
8
9
  import { Directory } from '@dxos/random-access-storage';
9
10
 
@@ -11,7 +12,7 @@ export class SnapshotStore {
11
12
  // prettier-ignore
12
13
  constructor(
13
14
  private readonly _directory: Directory
14
- ) {}
15
+ ) { }
15
16
 
16
17
  async saveSnapshot(snapshot: SpaceSnapshot): Promise<string> {
17
18
  const encoded = schema.getCodecForType('dxos.echo.snapshot.SpaceSnapshot').encode(snapshot);
@@ -42,4 +43,18 @@ export class SnapshotStore {
42
43
  await file.close();
43
44
  }
44
45
  }
46
+
47
+ async listSnapshots(): Promise<StoredSnapshotInfo[]> {
48
+ const entries = await this._directory.list();
49
+
50
+ return await Promise.all(
51
+ entries.map(async (key) => {
52
+ const { size } = await this._directory.getOrCreateFile(key).stat();
53
+ return {
54
+ key,
55
+ size,
56
+ };
57
+ }),
58
+ );
59
+ }
45
60
  }
@@ -10,7 +10,7 @@ import { DataCorruptionError } from '@dxos/errors';
10
10
  import { PublicKey } from '@dxos/keys';
11
11
  import { log } from '@dxos/log';
12
12
  import { schema } from '@dxos/protocols';
13
- import { EchoMetadata, SpaceMetadata, IdentityRecord } from '@dxos/protocols/proto/dxos/echo/metadata';
13
+ import { EchoMetadata, SpaceMetadata, IdentityRecord, SpaceCache } from '@dxos/protocols/proto/dxos/echo/metadata';
14
14
  import { Directory } from '@dxos/random-access-storage';
15
15
  import { Timeframe } from '@dxos/timeframe';
16
16
 
@@ -30,7 +30,7 @@ const emptyEchoMetadata = (): EchoMetadata => ({
30
30
  version: STORAGE_VERSION,
31
31
  spaces: [],
32
32
  created: new Date(),
33
- updated: new Date()
33
+ updated: new Date(),
34
34
  });
35
35
 
36
36
  export class MetadataStore {
@@ -95,7 +95,7 @@ export class MetadataStore {
95
95
  ...this._metadata,
96
96
  version: STORAGE_VERSION,
97
97
  created: this._metadata.created ?? new Date(),
98
- updated: new Date()
98
+ updated: new Date(),
99
99
  };
100
100
 
101
101
  const file = this._directory.getOrCreateFile('EchoMetadata');
@@ -119,6 +119,12 @@ export class MetadataStore {
119
119
  }
120
120
  }
121
121
 
122
+ _getSpace(spaceKey: PublicKey): SpaceMetadata {
123
+ const space = this.spaces.find((space) => space.key === spaceKey);
124
+ assert(space, 'Space not found');
125
+ return space;
126
+ }
127
+
122
128
  /**
123
129
  * Clears storage - doesn't work for now.
124
130
  */
@@ -141,7 +147,7 @@ export class MetadataStore {
141
147
  async addSpace(record: SpaceMetadata) {
142
148
  assert(
143
149
  !(this._metadata.spaces ?? []).find((space) => space.key === record.key),
144
- 'Cannot overwrite existing space in metadata'
150
+ 'Cannot overwrite existing space in metadata',
145
151
  );
146
152
 
147
153
  (this._metadata.spaces ??= []).push(record);
@@ -149,25 +155,17 @@ export class MetadataStore {
149
155
  }
150
156
 
151
157
  async setSpaceLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe) {
152
- const space = this.spaces.find((space) => space.key === spaceKey);
153
- assert(space, 'Space not found');
154
-
155
- space.dataTimeframe = timeframe;
158
+ this._getSpace(spaceKey).dataTimeframe = timeframe;
156
159
  await this._save();
157
160
  }
158
161
 
159
- async setSpaceSnapshot(spaceKey: PublicKey, snapshot: string) {
160
- const space = this.spaces.find((space) => space.key === spaceKey);
161
- assert(space, 'Space not found');
162
-
163
- space.snapshot = snapshot;
162
+ async setCache(spaceKey: PublicKey, cache: SpaceCache) {
163
+ this._getSpace(spaceKey).cache = cache;
164
164
  await this._save();
165
165
  }
166
166
 
167
167
  async setWritableFeedKeys(spaceKey: PublicKey, controlFeedKey: PublicKey, dataFeedKey: PublicKey) {
168
- const space = this.spaces.find((space) => space.key === spaceKey);
169
- assert(space, 'Space not found');
170
-
168
+ const space = this._getSpace(spaceKey);
171
169
  space.controlFeedKey = controlFeedKey;
172
170
  space.dataFeedKey = dataFeedKey;
173
171
  await this._save();
@@ -23,7 +23,7 @@ export const createMessageSelector = (timeframeClock: TimeframeClock): FeedBlock
23
23
  // Pick the first candidate with a valid timeframe that has no gaps.
24
24
  for (let i = 0; i < messages.length; i++) {
25
25
  const {
26
- data: { timeframe }
26
+ data: { timeframe },
27
27
  } = messages[i];
28
28
  assert(timeframe);
29
29
 
@@ -7,7 +7,6 @@ import * as fc from 'fast-check';
7
7
  import { inspect } from 'util';
8
8
 
9
9
  import { asyncTimeout } from '@dxos/async';
10
- import { checkType } from '@dxos/debug';
11
10
  import { FeedStore, FeedWrapper } from '@dxos/feed-store';
12
11
  import { PublicKey } from '@dxos/keys';
13
12
  import { log } from '@dxos/log';
@@ -20,10 +19,14 @@ import { range } from '@dxos/util';
20
19
  import { TestFeedBuilder } from '../testing';
21
20
  import { Pipeline } from './pipeline';
22
21
 
22
+ const TEST_MESSAGE: FeedMessage = {
23
+ timeframe: new Timeframe(),
24
+ payload: {},
25
+ };
26
+
23
27
  describe('pipeline/Pipeline', () => {
24
28
  test('asynchronous reader & writer without ordering', async () => {
25
- const pipeline = new Pipeline(new Timeframe());
26
- afterTest(() => pipeline.stop());
29
+ const pipeline = new Pipeline();
27
30
 
28
31
  const builder = new TestFeedBuilder();
29
32
  const feedStore = builder.createFeedStore();
@@ -31,29 +34,14 @@ describe('pipeline/Pipeline', () => {
31
34
  // Remote feeds from other peers.
32
35
  const numFeeds = 5;
33
36
  const messagesPerFeed = 10;
34
- for (const feedIdx in range(numFeeds)) {
37
+ for (const _ in range(numFeeds)) {
35
38
  const key = await builder.keyring.createKey();
36
39
  const feed = await feedStore.openFeed(key, { writable: true });
37
40
  void pipeline.addFeed(feed);
38
41
 
39
42
  setTimeout(async () => {
40
- for (const msgIdx in range(messagesPerFeed)) {
41
- await feed.append(
42
- checkType<FeedMessage>({
43
- timeframe: new Timeframe(),
44
- payload: {
45
- data: {
46
- batch: {
47
- objects: [
48
- {
49
- objectId: `${feedIdx}-${msgIdx}`
50
- }
51
- ]
52
- }
53
- }
54
- }
55
- })
56
- );
43
+ for (const _ in range(messagesPerFeed)) {
44
+ await feed.append(TEST_MESSAGE);
57
45
  }
58
46
  });
59
47
  }
@@ -64,20 +52,12 @@ describe('pipeline/Pipeline', () => {
64
52
  void pipeline.addFeed(feed);
65
53
  pipeline.setWriteFeed(feed);
66
54
 
67
- for (const msgIdx in range(messagesPerFeed)) {
68
- await pipeline.writer!.write({
69
- data: {
70
- batch: {
71
- objects: [
72
- {
73
- objectId: `local-${msgIdx}`
74
- }
75
- ]
76
- }
77
- }
78
- });
55
+ for (const _ in range(messagesPerFeed)) {
56
+ await pipeline.writer!.write({});
79
57
  }
80
58
 
59
+ await pipeline.start();
60
+
81
61
  let msgCount = 0;
82
62
  for await (const _ of pipeline.consume()) {
83
63
  if (++msgCount === numFeeds * messagesPerFeed) {
@@ -86,6 +66,49 @@ describe('pipeline/Pipeline', () => {
86
66
  }
87
67
  });
88
68
 
69
+ test('reading and writing with cursor changes', async () => {
70
+ const pipeline = new Pipeline();
71
+ afterTest(() => pipeline.stop());
72
+
73
+ const builder = new TestFeedBuilder();
74
+ const feedStore = builder.createFeedStore();
75
+ const key = await builder.keyring.createKey();
76
+ const feed = await feedStore.openFeed(key, { writable: true });
77
+ await pipeline.addFeed(feed);
78
+
79
+ const numMessages = 30;
80
+ const sequenceNumbers: number[] = [];
81
+ for (const _ of range(numMessages)) {
82
+ const { seq } = await feed.appendWithReceipt(TEST_MESSAGE);
83
+ sequenceNumbers.push(seq);
84
+ }
85
+
86
+ const processedSequenceNumbers: number[] = [];
87
+
88
+ // skip first 10, process the rest, and the repeat the last 10.
89
+ const expectedSequenceNumbers = [...sequenceNumbers.slice(10, 30), ...sequenceNumbers.slice(20, 30)];
90
+
91
+ await pipeline.setCursor(new Timeframe([[feed.key, 9]]));
92
+ await pipeline.start();
93
+
94
+ for await (const block of pipeline.consume()) {
95
+ processedSequenceNumbers.push(block.seq);
96
+
97
+ if (processedSequenceNumbers.length === 20) {
98
+ // not awaited to avoid a deadlock.
99
+ void pipeline.pause().then(async () => {
100
+ await pipeline.setCursor(new Timeframe([[feed.key, 19]]));
101
+ await pipeline.unpause();
102
+ });
103
+ }
104
+ if (processedSequenceNumbers.length === 30) {
105
+ void pipeline.stop();
106
+ }
107
+ }
108
+
109
+ expect(processedSequenceNumbers).toEqual(expectedSequenceNumbers);
110
+ });
111
+
89
112
  test
90
113
  .skip('stress', async () => {
91
114
  const builder = new TestFeedBuilder();
@@ -108,7 +131,8 @@ describe('pipeline/Pipeline', () => {
108
131
  }
109
132
 
110
133
  async start() {
111
- this.pipeline = new Pipeline(this.startingTimeframe);
134
+ this.pipeline = new Pipeline();
135
+ await this.pipeline.setCursor(this.startingTimeframe);
112
136
 
113
137
  await this.pipeline.start();
114
138
 
@@ -188,7 +212,7 @@ describe('pipeline/Pipeline', () => {
188
212
  console.log('empty endtimeframe', {
189
213
  id: agent.id,
190
214
  endTimeframe: agent.pipeline.state.endTimeframe,
191
- feeds: agent.pipeline.getFeeds().map((feed) => [feed.key.toString(), feed.length])
215
+ feeds: agent.pipeline.getFeeds().map((feed) => [feed.key.toString(), feed.length]),
192
216
  });
193
217
  }
194
218
  await asyncTimeout(agent.pipeline.state.waitUntilTimeframe(agent.pipeline.state.endTimeframe), 1000);
@@ -212,15 +236,15 @@ describe('pipeline/Pipeline', () => {
212
236
  messages: agent.messages.length,
213
237
  feeds: agent.pipeline.getFeeds().map((feed) => [feed.key, feed.length]),
214
238
  timeframe: agent.pipeline.state.timeframe,
215
- endTimeframe: agent.pipeline.state.endTimeframe
239
+ endTimeframe: agent.pipeline.state.endTimeframe,
216
240
  })),
217
241
  feeds: real.feedStore.feeds.map((feed) => [feed.key, feed.length]),
218
- targets
242
+ targets,
219
243
  },
220
244
  false,
221
245
  null,
222
- true
223
- )
246
+ true,
247
+ ),
224
248
  );
225
249
  throw err;
226
250
  }
@@ -254,9 +278,9 @@ describe('pipeline/Pipeline', () => {
254
278
  [
255
279
  fc.tuple(anAgentId, fc.integer({ min: 1, max: 10 })).map(([agent, count]) => new WriteCommand(agent, count)),
256
280
  fc.constant(new SyncCommand()),
257
- anAgentId.map((agent) => new RestartCommand(agent))
281
+ anAgentId.map((agent) => new RestartCommand(agent)),
258
282
  ],
259
- { size: 'large' }
283
+ { size: 'large' },
260
284
  );
261
285
 
262
286
  const model = fc.asyncProperty(commands, async (commands) => {
@@ -270,8 +294,8 @@ describe('pipeline/Pipeline', () => {
270
294
  model: {},
271
295
  real: {
272
296
  feedStore,
273
- agents
274
- }
297
+ agents,
298
+ },
275
299
  });
276
300
 
277
301
  try {
@@ -284,7 +308,7 @@ describe('pipeline/Pipeline', () => {
284
308
 
285
309
  const examples: [commands: Iterable<fc.AsyncCommand<Model, Real, boolean>>][] = [
286
310
  [[new WriteCommand(agentIds[0], 10), new WriteCommand(agentIds[1], 10), new SyncCommand()]],
287
- [[new WriteCommand(agentIds[0], 4), new RestartCommand(agentIds[0]), new SyncCommand()]]
311
+ [[new WriteCommand(agentIds[0], 4), new RestartCommand(agentIds[0]), new SyncCommand()]],
288
312
  ];
289
313
 
290
314
  await fc.assert(model, { examples });