@dxos/echo-db 2.33.5-dev.4dcc5349 → 2.33.5-dev.61c93034

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 (112) hide show
  1. package/dist/src/api/selection/queries.d.ts.map +1 -1
  2. package/dist/src/api/selection/queries.js +13 -17
  3. package/dist/src/api/selection/queries.js.map +1 -1
  4. package/dist/src/api/selection/selection.d.ts.map +1 -1
  5. package/dist/src/api/selection/selection.js +1 -3
  6. package/dist/src/api/selection/selection.js.map +1 -1
  7. package/dist/src/api/selection/selection.test.js +4 -12
  8. package/dist/src/api/selection/selection.test.js.map +1 -1
  9. package/dist/src/database/item-demuxer.d.ts +1 -1
  10. package/dist/src/database/item-demuxer.d.ts.map +1 -1
  11. package/dist/src/database/item-demuxer.js +3 -5
  12. package/dist/src/database/item-demuxer.js.map +1 -1
  13. package/dist/src/database/item-manager.js +2 -2
  14. package/dist/src/database/item-manager.js.map +1 -1
  15. package/dist/src/database/testing.js +1 -1
  16. package/dist/src/database/testing.js.map +1 -1
  17. package/dist/src/halo/halo-party.d.ts.map +1 -1
  18. package/dist/src/halo/halo-party.js +3 -1
  19. package/dist/src/halo/halo-party.js.map +1 -1
  20. package/dist/src/halo/identity.js +2 -2
  21. package/dist/src/halo/identity.js.map +1 -1
  22. package/dist/src/halo/party-opener.d.ts +1 -1
  23. package/dist/src/halo/party-opener.d.ts.map +1 -1
  24. package/dist/src/halo/party-opener.js +2 -2
  25. package/dist/src/halo/party-opener.js.map +1 -1
  26. package/dist/src/halo/preferences.d.ts.map +1 -1
  27. package/dist/src/halo/preferences.js +7 -10
  28. package/dist/src/halo/preferences.js.map +1 -1
  29. package/dist/src/invitations/greeting-protocol-provider.d.ts.map +1 -1
  30. package/dist/src/invitations/greeting-protocol-provider.js +5 -9
  31. package/dist/src/invitations/greeting-protocol-provider.js.map +1 -1
  32. package/dist/src/invitations/greeting-responder.d.ts.map +1 -1
  33. package/dist/src/invitations/greeting-responder.js +8 -12
  34. package/dist/src/invitations/greeting-responder.js.map +1 -1
  35. package/dist/src/invitations/offline-invitation-claimer.d.ts.map +1 -1
  36. package/dist/src/invitations/offline-invitation-claimer.js +5 -7
  37. package/dist/src/invitations/offline-invitation-claimer.js.map +1 -1
  38. package/dist/src/parties/data-party.d.ts.map +1 -1
  39. package/dist/src/parties/data-party.js +3 -1
  40. package/dist/src/parties/data-party.js.map +1 -1
  41. package/dist/src/pipeline/message-selector.d.ts +1 -1
  42. package/dist/src/pipeline/message-selector.d.ts.map +1 -1
  43. package/dist/src/pipeline/message-selector.js +29 -32
  44. package/dist/src/pipeline/message-selector.js.map +1 -1
  45. package/dist/src/pipeline/party-core.test.js +2 -1
  46. package/dist/src/pipeline/party-core.test.js.map +1 -1
  47. package/dist/src/protocol/auth-plugin.d.ts +1 -1
  48. package/dist/src/protocol/auth-plugin.d.ts.map +1 -1
  49. package/dist/src/protocol/auth-plugin.js +1 -3
  50. package/dist/src/protocol/auth-plugin.js.map +1 -1
  51. package/dist/src/protocol/authenticator.d.ts +2 -2
  52. package/dist/src/protocol/authenticator.d.ts.map +1 -1
  53. package/dist/src/protocol/authenticator.js +12 -16
  54. package/dist/src/protocol/authenticator.js.map +1 -1
  55. package/dist/src/protocol/halo-recovery-plugin.d.ts +1 -1
  56. package/dist/src/protocol/halo-recovery-plugin.d.ts.map +1 -1
  57. package/dist/src/protocol/halo-recovery-plugin.js +1 -3
  58. package/dist/src/protocol/halo-recovery-plugin.js.map +1 -1
  59. package/dist/src/protocol/identity-credentials.d.ts +2 -2
  60. package/dist/src/protocol/identity-credentials.d.ts.map +1 -1
  61. package/dist/src/protocol/identity-credentials.js +4 -4
  62. package/dist/src/protocol/identity-credentials.js.map +1 -1
  63. package/dist/src/protocol/offline-invitation-plugin.d.ts +1 -1
  64. package/dist/src/protocol/offline-invitation-plugin.d.ts.map +1 -1
  65. package/dist/src/protocol/offline-invitation-plugin.js +1 -3
  66. package/dist/src/protocol/offline-invitation-plugin.js.map +1 -1
  67. package/dist/src/protocol/party-protocol-factory.d.ts +1 -14
  68. package/dist/src/protocol/party-protocol-factory.d.ts.map +1 -1
  69. package/dist/src/protocol/party-protocol-factory.js +2 -55
  70. package/dist/src/protocol/party-protocol-factory.js.map +1 -1
  71. package/dist/src/protocol/replicator-plugin.d.ts +7 -0
  72. package/dist/src/protocol/replicator-plugin.d.ts.map +1 -0
  73. package/dist/src/protocol/replicator-plugin.js +36 -0
  74. package/dist/src/protocol/replicator-plugin.js.map +1 -0
  75. package/dist/src/snapshots/snapshot-generator.d.ts +1 -1
  76. package/dist/src/snapshots/snapshot-generator.d.ts.map +1 -1
  77. package/dist/src/snapshots/snapshot-generator.js +13 -15
  78. package/dist/src/snapshots/snapshot-generator.js.map +1 -1
  79. package/dist/src/testing/benchmark.test.d.ts +2 -0
  80. package/dist/src/testing/benchmark.test.d.ts.map +1 -0
  81. package/dist/src/testing/benchmark.test.js +25 -0
  82. package/dist/src/testing/benchmark.test.js.map +1 -0
  83. package/dist/src/testing/testing-factories.js +2 -2
  84. package/dist/src/testing/testing-factories.js.map +1 -1
  85. package/dist/tsconfig.tsbuildinfo +1 -1
  86. package/package.json +18 -18
  87. package/src/api/selection/queries.ts +14 -18
  88. package/src/api/selection/selection.test.ts +4 -12
  89. package/src/api/selection/selection.ts +1 -7
  90. package/src/database/item-demuxer.ts +2 -4
  91. package/src/database/item-manager.ts +2 -2
  92. package/src/database/testing.ts +1 -1
  93. package/src/halo/halo-party.ts +2 -1
  94. package/src/halo/identity.ts +2 -2
  95. package/src/halo/party-opener.ts +2 -2
  96. package/src/halo/preferences.ts +7 -10
  97. package/src/invitations/greeting-protocol-provider.ts +5 -9
  98. package/src/invitations/greeting-responder.ts +9 -13
  99. package/src/invitations/offline-invitation-claimer.ts +5 -7
  100. package/src/parties/data-party.ts +2 -1
  101. package/src/pipeline/message-selector.ts +30 -36
  102. package/src/pipeline/party-core.test.ts +4 -7
  103. package/src/protocol/auth-plugin.ts +1 -3
  104. package/src/protocol/authenticator.ts +27 -31
  105. package/src/protocol/halo-recovery-plugin.ts +4 -6
  106. package/src/protocol/identity-credentials.ts +4 -4
  107. package/src/protocol/offline-invitation-plugin.ts +4 -6
  108. package/src/protocol/party-protocol-factory.ts +3 -56
  109. package/src/protocol/replicator-plugin.ts +37 -0
  110. package/src/snapshots/snapshot-generator.ts +12 -16
  111. package/src/testing/benchmark.test.ts +30 -0
  112. package/src/testing/testing-factories.ts +2 -2
@@ -24,9 +24,7 @@ const modelFactory = new ModelFactory().registerModel(ObjectModel);
24
24
 
25
25
  const createModel = (id: ItemID) => modelFactory.createModel(ObjectModel.meta.type, id, {}, PublicKey.random());
26
26
 
27
- const createItem = (id: ItemID, type: ItemType, parent?: Item<any>) => {
28
- return new Item(null as any, id, type, createModel(id), undefined, parent);
29
- };
27
+ const createItem = (id: ItemID, type: ItemType, parent?: Item<any>) => new Item(null as any, id, type, createModel(id), undefined, parent);
30
28
 
31
29
  const createLink = (id: ItemID, type: ItemType, source: Item<any>, target: Item<any>) => {
32
30
  const link = new Link(null as any, id, type, createModel(id), {
@@ -262,17 +260,11 @@ describe('Selection', () => {
262
260
  test('complex reducer', () => {
263
261
  const query = createReducer({ numItems: 0, numLinks: 0 })
264
262
  .filter({ type: ITEM_ORG })
265
- .call((items: Item[], { numItems, ...rest }) => {
266
- return { ...rest, numItems: numItems + items.length, stage: 'a' };
267
- })
263
+ .call((items: Item[], { numItems, ...rest }) => ({ ...rest, numItems: numItems + items.length, stage: 'a' }))
268
264
  .children({ type: ITEM_PROJECT })
269
- .call((items: Item[], { numItems, ...rest }) => {
270
- return { ...rest, numItems: numItems + items.length, stage: 'b' };
271
- })
265
+ .call((items: Item[], { numItems, ...rest }) => ({ ...rest, numItems: numItems + items.length, stage: 'b' }))
272
266
  .links({ type: LINK_MEMBER })
273
- .call((links: Link[], { numLinks, ...rest }) => {
274
- return { ...rest, numLinks: numLinks + links.length, stage: 'c' };
275
- })
267
+ .call((links: Link[], { numLinks, ...rest }) => ({ ...rest, numLinks: numLinks + links.length, stage: 'c' }))
276
268
  .target()
277
269
  .exec();
278
270
 
@@ -57,13 +57,7 @@ export const createSelection = <R>(
57
57
  * @param update
58
58
  * @param value Initial reducer value.
59
59
  */
60
- export const createItemSelection = <R>(
61
- root: Item<any>,
62
- update: Event<Entity[]>,
63
- value: R
64
- ): Selection<Item<any>, R> => {
65
- return new Selection(() => [[root], value], update, root, value !== undefined);
66
- };
60
+ export const createItemSelection = <R>(root: Item<any>, update: Event<Entity[]>, value: R): Selection<Item<any>, R> => new Selection(() => [[root], value], update, root, value !== undefined);
67
61
 
68
62
  /**
69
63
  * Selections are used to construct database subscriptions.
@@ -10,7 +10,6 @@ import { failUndefined } from '@dxos/debug';
10
10
  import { DatabaseSnapshot, IEchoStream, ItemID, ItemSnapshot, LinkSnapshot } from '@dxos/echo-protocol';
11
11
  import { createWritable } from '@dxos/feed-store';
12
12
  import { Model, ModelFactory, ModelMessage } from '@dxos/model-factory';
13
- import { jsonReplacer } from '@dxos/util';
14
13
 
15
14
  import { Entity, Item, Link } from '../api';
16
15
  import { ItemManager, ModelConstructionOptions } from './item-manager';
@@ -46,7 +45,6 @@ export class ItemDemuxer {
46
45
  // TODO(burdon): Factor out.
47
46
  // TODO(burdon): Should this implement some "back-pressure" (hints) to the PartyProcessor?
48
47
  return createWritable<IEchoStream>(async (message: IEchoStream) => {
49
- log('Reading:', JSON.stringify(message, jsonReplacer));
50
48
  const { data: { itemId, genesis, itemMutation, mutation, snapshot }, meta } = message;
51
49
  assert(itemId);
52
50
 
@@ -187,7 +185,7 @@ export class ItemDemuxer {
187
185
  * Sort based on parents.
188
186
  * @param items
189
187
  */
190
- export function sortItemsTopologically (items: ItemSnapshot[]): ItemSnapshot[] {
188
+ export const sortItemsTopologically = (items: ItemSnapshot[]): ItemSnapshot[] => {
191
189
  const snapshots: ItemSnapshot[] = [];
192
190
  const seenIds = new Set<ItemID>();
193
191
 
@@ -206,4 +204,4 @@ export function sortItemsTopologically (items: ItemSnapshot[]): ItemSnapshot[] {
206
204
  }
207
205
 
208
206
  return snapshots;
209
- }
207
+ };
@@ -375,7 +375,7 @@ export class ItemManager {
375
375
  /**
376
376
  * Returns a new event that groups all of the updates emitted during single tick into a single event emission.
377
377
  */
378
- function debounceEntityUpdateEvent (event: Event<Entity<any>>): Event<Entity<any>[]> {
378
+ const debounceEntityUpdateEvent = (event: Event<Entity<any>>): Event<Entity<any>[]> => {
379
379
  const debouncedEvent = new Event<Entity<any>[]>();
380
380
 
381
381
  let firing = false;
@@ -395,4 +395,4 @@ function debounceEntityUpdateEvent (event: Event<Entity<any>>): Event<Entity<any
395
395
  }));
396
396
 
397
397
  return debouncedEvent;
398
- }
398
+ };
@@ -15,7 +15,7 @@ import { FeedDatabaseBackend, RemoteDatabaseBackend } from './database-backend';
15
15
 
16
16
  export const createInMemoryDatabase = async (modelFactory: ModelFactory) => {
17
17
  const feed = new MockFeedWriter<EchoEnvelope>();
18
- const inboundStream = new Readable({ read () {}, objectMode: true });
18
+ const inboundStream = new Readable({ read: () => {}, objectMode: true });
19
19
  feed.written.on(([data, meta]) => inboundStream.push({ data, meta: { ...meta, memberKey: PublicKey.random(), timeframe: new Timeframe([[meta.feedKey, meta.seq]]) } }));
20
20
 
21
21
  const database = new Database(
@@ -17,6 +17,7 @@ import { PARTY_ITEM_TYPE } from '../parties';
17
17
  import { PartyFeedProvider, PartyProtocolFactory, PartyCore, PartyOptions } from '../pipeline';
18
18
  import { createAuthenticator, createAuthPlugin, createCredentialsProvider, createHaloRecoveryPlugin } from '../protocol';
19
19
  import { CredentialsSigner } from '../protocol/credentials-signer';
20
+ import { createReplicatorPlugin } from '../protocol/replicator-plugin';
20
21
  import { SnapshotStore } from '../snapshots';
21
22
  import { ContactManager } from './contact-manager';
22
23
  import { Preferences } from './preferences';
@@ -161,13 +162,13 @@ export class HaloParty {
161
162
  this._protocol = new PartyProtocolFactory(
162
163
  this._partyCore.key,
163
164
  this._networkManager,
164
- this._feedProvider,
165
165
  peerId,
166
166
  createCredentialsProvider(this._credentialsSigner, this._partyCore.key, writeFeed.key)
167
167
  );
168
168
 
169
169
  // Replication.
170
170
  await this._protocol.start([
171
+ createReplicatorPlugin(this._feedProvider),
171
172
  createAuthPlugin(createAuthenticator(this._partyCore.processor, this._credentialsSigner), peerId),
172
173
  createHaloRecoveryPlugin(this._credentialsSigner.getIdentityKey().publicKey, this._invitationManager, peerId)
173
174
  ]);
@@ -102,7 +102,7 @@ export class Identity implements IdentityCredentials {
102
102
 
103
103
  export type IdentityProvider = () => Identity | undefined;
104
104
 
105
- function getDeviceKeyChainFromHalo (halo: HaloParty, deviceKey: KeyRecord) {
105
+ const getDeviceKeyChainFromHalo = (halo: HaloParty, deviceKey: KeyRecord) => {
106
106
  try {
107
107
  return Keyring.buildKeyChain(
108
108
  deviceKey.publicKey,
@@ -113,4 +113,4 @@ function getDeviceKeyChainFromHalo (halo: HaloParty, deviceKey: KeyRecord) {
113
113
  log('Unable to locate device KeyChain:', err);
114
114
  throw err;
115
115
  }
116
- }
116
+ };
@@ -14,7 +14,7 @@ const log = debug('dxos:echo-db:party-opener');
14
14
  /**
15
15
  * Automatically adds, opens, and clothes parties from HALO preferences.
16
16
  */
17
- export function autoPartyOpener (preferences: Preferences, partyManager: PartyManager): Unsubscribe {
17
+ export const autoPartyOpener = (preferences: Preferences, partyManager: PartyManager): Unsubscribe => {
18
18
  const subs = new SubscriptionGroup();
19
19
 
20
20
  subs.push(preferences.subscribeToJoinedPartyList(async values => {
@@ -46,4 +46,4 @@ export function autoPartyOpener (preferences: Preferences, partyManager: PartyMa
46
46
  }));
47
47
 
48
48
  return () => subs.unsubscribe();
49
- }
49
+ };
@@ -159,16 +159,13 @@ export class Preferences {
159
159
  subscribeToJoinedPartyList (callback: (parties: JoinedParty[]) => void): () => void {
160
160
  const database = this._getDatabase() ?? raise(new IdentityNotInitializedError());
161
161
 
162
- const converter = (partyDesc: Item<any>) => {
163
- // TODO(burdon): Define type.
164
- return {
165
- partyKey: PublicKey.from(partyDesc.model.get('publicKey')),
166
- keyHints: Object.values(partyDesc.model.get('hints')).map((hint: any) => ({
167
- ...hint,
168
- publicKey: PublicKey.from(hint.publicKey)
169
- } as KeyHint))
170
- };
171
- };
162
+ const converter = (partyDesc: Item<any>) => ({
163
+ partyKey: PublicKey.from(partyDesc.model.get('publicKey')),
164
+ keyHints: Object.values(partyDesc.model.get('hints')).map((hint: any) => ({
165
+ ...hint,
166
+ publicKey: PublicKey.from(hint.publicKey)
167
+ } as KeyHint))
168
+ });
172
169
 
173
170
  const result = database.select({ type: HALO_PARTY_DESCRIPTOR_TYPE }).exec();
174
171
 
@@ -14,12 +14,8 @@ import { protocolFactory } from '@dxos/network-manager';
14
14
  */
15
15
  // TODO(burdon): When closed?
16
16
  // TODO(dboreham): Write a test to check resources are released (no resource leaks).
17
- export const greetingProtocolProvider = (rendezvousKey: any, peerId: Buffer | Uint8Array, protocolPlugins: any[]) => {
18
- return protocolFactory({
19
- getTopics: () => {
20
- return [rendezvousKey];
21
- },
22
- session: { peerId: keyToString(peerId) },
23
- plugins: protocolPlugins
24
- });
25
- };
17
+ export const greetingProtocolProvider = (rendezvousKey: any, peerId: Buffer | Uint8Array, protocolPlugins: any[]) => protocolFactory({
18
+ getTopics: () => [rendezvousKey],
19
+ session: { peerId: keyToString(peerId) },
20
+ plugins: protocolPlugins
21
+ });
@@ -243,19 +243,15 @@ export class GreetingResponder {
243
243
  _gatherHints (): KeyHint[] {
244
244
  assert(this._state === GreetingState.SUCCEEDED);
245
245
 
246
- const memberKeys = this._partyProcessor.memberKeys.map(publicKey => {
247
- return {
248
- publicKey,
249
- type: KeyType.UNKNOWN
250
- };
251
- });
252
-
253
- const memberFeeds = this._partyProcessor.feedKeys.map(publicKey => {
254
- return {
255
- publicKey,
256
- type: KeyType.FEED
257
- };
258
- });
246
+ const memberKeys = this._partyProcessor.memberKeys.map((publicKey) => ({
247
+ publicKey,
248
+ type: KeyType.UNKNOWN
249
+ }));
250
+
251
+ const memberFeeds = this._partyProcessor.feedKeys.map((publicKey) => ({
252
+ publicKey,
253
+ type: KeyType.FEED
254
+ }));
259
255
 
260
256
  return [...memberKeys, ...memberFeeds];
261
257
  }
@@ -170,19 +170,17 @@ export class OfflineInvitationClaimer {
170
170
 
171
171
  // The secretProvider should provide an `Auth` message signed directly by the Identity key.
172
172
  static createSecretProvider (credentials: CredentialsSigner): SecretProvider {
173
- return async (info?: SecretInfo) => {
174
- return Buffer.from(codec.encode(
175
- /* The signed portion of the Auth message includes the ID and authNonce provided
173
+ return async (info?: SecretInfo) => Buffer.from(codec.encode(
174
+ /* The signed portion of the Auth message includes the ID and authNonce provided
176
175
  * by the `info` object. These values will be validated on the other end.
177
176
  */
178
- createAuthMessage(
179
- credentials.signer,
177
+ createAuthMessage(
178
+ credentials.signer,
180
179
  info!.id.value,
181
180
  credentials.getIdentityKey(),
182
181
  credentials.getDeviceSigningKeys(),
183
182
  undefined,
184
183
  info!.authNonce.value)
185
- ));
186
- };
184
+ ));
187
185
  }
188
186
  }
@@ -19,6 +19,7 @@ import { InvitationFactory } from '../invitations';
19
19
  import { PartyFeedProvider, PartyProtocolFactory, PartyCore, PartyOptions } from '../pipeline';
20
20
  import { createAuthPlugin, createOfflineInvitationPlugin, createAuthenticator, createCredentialsProvider } from '../protocol';
21
21
  import { CredentialsSigner } from '../protocol/credentials-signer';
22
+ import { createReplicatorPlugin } from '../protocol/replicator-plugin';
22
23
  import { SnapshotStore } from '../snapshots';
23
24
  import { CONTACT_DEBOUNCE_INTERVAL } from './party-manager';
24
25
 
@@ -173,12 +174,12 @@ export class DataParty {
173
174
  this._protocol = new PartyProtocolFactory(
174
175
  this._partyCore.key,
175
176
  this._networkManager,
176
- this._feedProvider,
177
177
  deviceKey.publicKey,
178
178
  createCredentialsProvider(this._credentialsSigner, this._partyCore.key, writeFeed.key)
179
179
  );
180
180
 
181
181
  await this._protocol.start([
182
+ createReplicatorPlugin(this._feedProvider),
182
183
  createAuthPlugin(createAuthenticator(this._partyCore.processor, this._credentialsSigner), deviceKey.publicKey),
183
184
  createOfflineInvitationPlugin(this._invitationManager, deviceKey.publicKey)
184
185
  ]);
@@ -23,47 +23,41 @@ const log = debug('dxos:echo-db:message-selector');
23
23
  * @param partyProcessor
24
24
  * @param timeframeClock
25
25
  */
26
- export function createMessageSelector (
27
- partyProcessor: PartyProcessor,
28
- timeframeClock: TimeframeClock
29
- ): MessageSelector {
30
- // TODO(telackey): Add KeyAdmit checks.
31
- return candidates => {
32
- // Check ECHO message candidates first since they are less expensive than HALO cancidates.
33
- for (let i = 0; i < candidates.length; i++) {
34
- const { data: { echo } } = candidates[i];
35
- const feedKey = PublicKey.from(candidates[i].key);
36
- if (!echo) {
37
- continue;
38
- }
26
+ export const createMessageSelector = (partyProcessor: PartyProcessor, timeframeClock: TimeframeClock): MessageSelector => candidates => {
27
+ // Check ECHO message candidates first since they are less expensive than HALO cancidates.
28
+ for (let i = 0; i < candidates.length; i++) {
29
+ const { data: { echo } } = candidates[i];
30
+ const feedKey = PublicKey.from(candidates[i].key);
31
+ if (!echo) {
32
+ continue;
33
+ }
39
34
 
40
- assert(echo.timeframe);
41
- if (partyProcessor.isFeedAdmitted(feedKey) && !timeframeClock.hasGaps(echo.timeframe)) {
42
- return i;
43
- }
35
+ assert(echo.timeframe);
36
+ if (partyProcessor.isFeedAdmitted(feedKey) && !timeframeClock.hasGaps(echo.timeframe)) {
37
+ return i;
38
+ }
39
+ }
40
+
41
+ // Check HALO message candidates.
42
+ for (let i = 0; i < candidates.length; i++) {
43
+ const { data: { halo } } = candidates[i];
44
+ const feedKey = PublicKey.from(candidates[i].key);
45
+ if (!halo) {
46
+ continue;
44
47
  }
45
48
 
46
- // Check HALO message candidates.
47
- for (let i = 0; i < candidates.length; i++) {
48
- const { data: { halo } } = candidates[i];
49
- const feedKey = PublicKey.from(candidates[i].key);
50
- if (!halo) {
51
- continue;
52
- }
49
+ if (partyProcessor.isFeedAdmitted(feedKey)) {
50
+ return i;
51
+ }
53
52
 
54
- if (partyProcessor.isFeedAdmitted(feedKey)) {
53
+ if (partyProcessor.genesisRequired) {
54
+ // TODO(telackey): Add check that this is for the right Party.
55
+ if (getPartyCredentialMessageType(halo) === PartyCredential.Type.PARTY_GENESIS) {
55
56
  return i;
56
57
  }
57
-
58
- if (partyProcessor.genesisRequired) {
59
- // TODO(telackey): Add check that this is for the right Party.
60
- if (getPartyCredentialMessageType(halo) === PartyCredential.Type.PARTY_GENESIS) {
61
- return i;
62
- }
63
- }
64
58
  }
59
+ }
65
60
 
66
- // Not ready for this message yet.
67
- log('Skipping...');
68
- };
69
- }
61
+ // Not ready for this message yet.
62
+ log('Skipping...');
63
+ };
@@ -16,7 +16,8 @@ import { ObjectModel } from '@dxos/object-model';
16
16
  import { createStorage, StorageType } from '@dxos/random-access-multi-storage';
17
17
  import { afterTest } from '@dxos/testutils';
18
18
 
19
- import { MetadataStore, PartyFeedProvider, ReplicatorProtocolPluginFactory } from '../pipeline';
19
+ import { MetadataStore, PartyFeedProvider } from '../pipeline';
20
+ import { createReplicatorPlugin } from '../protocol/replicator-plugin';
20
21
  import { SnapshotStore } from '../snapshots';
21
22
  import { PartyCore } from './party-core';
22
23
 
@@ -286,12 +287,8 @@ describe('PartyCore', () => {
286
287
  afterTest(async () => party2.close());
287
288
 
288
289
  createTestProtocolPair(
289
- new ReplicatorProtocolPluginFactory(
290
- peer1.partyFeedProvider
291
- ).createPlugins().map(r => r.createExtension()),
292
- new ReplicatorProtocolPluginFactory(
293
- partyFeedProvider
294
- ).createPlugins().map(r => r.createExtension())
290
+ [createReplicatorPlugin(peer1.partyFeedProvider).createExtension()],
291
+ [createReplicatorPlugin(partyFeedProvider).createExtension()]
295
292
  );
296
293
 
297
294
  const item1 = await peer1.party.database.createItem();
@@ -9,6 +9,4 @@ import { Replicator } from '@dxos/protocol-plugin-replicator';
9
9
  /**
10
10
  * Creates authenticator network-protocol plugin that guards access to the replicator.
11
11
  */
12
- export function createAuthPlugin (authenticator: Authenticator, peerId: PublicKey) {
13
- return new AuthPlugin(peerId.asBuffer(), authenticator, [Replicator.extension]);
14
- }
12
+ export const createAuthPlugin = (authenticator: Authenticator, peerId: PublicKey) => new AuthPlugin(peerId.asBuffer(), authenticator, [Replicator.extension]);
@@ -12,19 +12,17 @@ import { CredentialsSigner } from './credentials-signer';
12
12
 
13
13
  const log = debug('dxos:echo-db:authenticator');
14
14
 
15
- export function createAuthenticator (partyProcessor: PartyProcessor, credentialsSigner: CredentialsSigner): Authenticator {
16
- return new PartyAuthenticator(partyProcessor.state, async auth => {
17
- if (auth.feedAdmit && auth.feedKey && !partyProcessor.isFeedAdmitted(auth.feedKey)) {
18
- log(`Admitting feed of authenticated member: ${auth.feedKey}`);
19
- await partyProcessor.writeHaloMessage(createEnvelopeMessage(
20
- credentialsSigner.signer,
21
- partyProcessor.partyKey,
22
- auth.feedAdmit,
23
- [credentialsSigner.getDeviceSigningKeys()]
24
- ));
25
- }
26
- });
27
- }
15
+ export const createAuthenticator = (partyProcessor: PartyProcessor, credentialsSigner: CredentialsSigner): Authenticator => new PartyAuthenticator(partyProcessor.state, async auth => {
16
+ if (auth.feedAdmit && auth.feedKey && !partyProcessor.isFeedAdmitted(auth.feedKey)) {
17
+ log(`Admitting feed of authenticated member: ${auth.feedKey}`);
18
+ await partyProcessor.writeHaloMessage(createEnvelopeMessage(
19
+ credentialsSigner.signer,
20
+ partyProcessor.partyKey,
21
+ auth.feedAdmit,
22
+ [credentialsSigner.getDeviceSigningKeys()]
23
+ ));
24
+ }
25
+ });
28
26
 
29
27
  export interface CredentialsProvider {
30
28
  /**
@@ -33,24 +31,22 @@ export interface CredentialsProvider {
33
31
  get (): Buffer
34
32
  }
35
33
 
36
- export function createCredentialsProvider (credentialsSigner: CredentialsSigner, partyKey: PartyKey, feedKey: FeedKey): CredentialsProvider {
37
- return {
38
- get: () => {
39
- const authMessage = createAuthMessage(
34
+ export const createCredentialsProvider = (credentialsSigner: CredentialsSigner, partyKey: PartyKey, feedKey: FeedKey): CredentialsProvider => ({
35
+ get: () => {
36
+ const authMessage = createAuthMessage(
37
+ credentialsSigner.signer,
38
+ partyKey,
39
+ credentialsSigner.getIdentityKey(),
40
+ credentialsSigner.getDeviceSigningKeys(),
41
+ feedKey,
42
+ undefined,
43
+ createFeedAdmitMessage(
40
44
  credentialsSigner.signer,
41
45
  partyKey,
42
- credentialsSigner.getIdentityKey(),
43
- credentialsSigner.getDeviceSigningKeys(),
44
46
  feedKey,
45
- undefined,
46
- createFeedAdmitMessage(
47
- credentialsSigner.signer,
48
- partyKey,
49
- feedKey,
50
- [feedKey, credentialsSigner.getDeviceSigningKeys()]
51
- )
52
- );
53
- return Buffer.from(codec.encode(authMessage));
54
- }
55
- };
56
- }
47
+ [feedKey, credentialsSigner.getDeviceSigningKeys()]
48
+ )
49
+ );
50
+ return Buffer.from(codec.encode(authMessage));
51
+ }
52
+ });
@@ -12,9 +12,7 @@ import { HaloRecoveryInitiator, InvitationFactory } from '../invitations';
12
12
  * Plugin is intended to be used in HALO party swarm.
13
13
  *
14
14
  */
15
- export function createHaloRecoveryPlugin (identityKey: PublicKey, invitationFactory: InvitationFactory, peerId: PublicKey) {
16
- return new GreetingCommandPlugin(
17
- peerId.asBuffer(),
18
- HaloRecoveryInitiator.createHaloInvitationClaimHandler(identityKey, invitationFactory)
19
- );
20
- }
15
+ export const createHaloRecoveryPlugin = (identityKey: PublicKey, invitationFactory: InvitationFactory, peerId: PublicKey) => new GreetingCommandPlugin(
16
+ peerId.asBuffer(),
17
+ HaloRecoveryInitiator.createHaloInvitationClaimHandler(identityKey, invitationFactory)
18
+ );
@@ -25,7 +25,7 @@ export interface IdentityCredentials {
25
25
 
26
26
  export type IdentityCredentialsProvider = () => IdentityCredentials | undefined
27
27
 
28
- export async function createTestIdentityCredentials (keyring: Keyring): Promise<IdentityCredentials> {
28
+ export const createTestIdentityCredentials = async (keyring: Keyring): Promise<IdentityCredentials> => {
29
29
  const identityKey = await keyring.createKeyRecord({ type: KeyType.IDENTITY });
30
30
  const deviceKey = await keyring.createKeyRecord({ type: KeyType.DEVICE });
31
31
  const feedKey = await keyring.createKeyRecord({ type: KeyType.FEED });
@@ -53,9 +53,9 @@ export async function createTestIdentityCredentials (keyring: Keyring): Promise<
53
53
  preferences: undefined,
54
54
  contacts: undefined
55
55
  };
56
- }
56
+ };
57
57
 
58
- export async function deriveTestDeviceCredentials (identity: IdentityCredentials): Promise<IdentityCredentials> {
58
+ export const deriveTestDeviceCredentials = async (identity: IdentityCredentials): Promise<IdentityCredentials> => {
59
59
  const deviceKey = await identity.keyring.createKeyRecord({ type: KeyType.DEVICE });
60
60
  const keyAdmit = createKeyAdmitMessage(identity.keyring, identity.identityKey.publicKey, deviceKey, [identity.identityKey]);
61
61
 
@@ -75,4 +75,4 @@ export async function deriveTestDeviceCredentials (identity: IdentityCredentials
75
75
  deviceKeyChain
76
76
  )
77
77
  };
78
- }
78
+ };
@@ -11,9 +11,7 @@ import { InvitationFactory, OfflineInvitationClaimer } from '../invitations';
11
11
  * Creates network protocol plugin that allows peers to claim offline invitations.
12
12
  * Plugin is intended to be used in data-party swarms.
13
13
  */
14
- export function createOfflineInvitationPlugin (invitationFactory: InvitationFactory, peerId: PublicKey) {
15
- return new GreetingCommandPlugin(
16
- peerId.asBuffer(),
17
- OfflineInvitationClaimer.createOfflineInvitationClaimHandler(invitationFactory)
18
- );
19
- }
14
+ export const createOfflineInvitationPlugin = (invitationFactory: InvitationFactory, peerId: PublicKey) => new GreetingCommandPlugin(
15
+ peerId.asBuffer(),
16
+ OfflineInvitationClaimer.createOfflineInvitationClaimHandler(invitationFactory)
17
+ );
@@ -4,17 +4,13 @@
4
4
 
5
5
  import debug from 'debug';
6
6
 
7
- import { synchronized } from '@dxos/async';
8
7
  import { discoveryKey, keyToString, PublicKey } from '@dxos/crypto';
9
- import { FeedKey, PartyKey } from '@dxos/echo-protocol';
10
- import type { HypercoreFeed } from '@dxos/feed-store';
8
+ import { PartyKey } from '@dxos/echo-protocol';
11
9
  import { Protocol } from '@dxos/mesh-protocol';
12
10
  import { MMSTTopology, NetworkManager, Plugin } from '@dxos/network-manager';
13
11
  import { PresencePlugin } from '@dxos/protocol-plugin-presence';
14
- import { Replicator } from '@dxos/protocol-plugin-replicator';
15
12
 
16
13
  import { CredentialsProvider } from '.';
17
- import { PartyFeedProvider } from '../pipeline/party-feed-provider';
18
14
 
19
15
  const log = debug('dxos:echo-db:party-protocol-factory');
20
16
 
@@ -23,21 +19,15 @@ const log = debug('dxos:echo-db:party-protocol-factory');
23
19
  */
24
20
  export class PartyProtocolFactory {
25
21
  private readonly _presencePlugin = new PresencePlugin(this._peerId.asBuffer());
26
- private readonly _replicatorProtocolPluginFactory: ReplicatorProtocolPluginFactory;
27
22
 
28
23
  private _started = false;
29
24
 
30
25
  constructor (
31
26
  private readonly _partyKey: PartyKey,
32
27
  private readonly _networkManager: NetworkManager,
33
- private readonly _feedProvider: PartyFeedProvider,
34
28
  private readonly _peerId: PublicKey,
35
29
  private readonly _credentials: CredentialsProvider
36
- ) {
37
- // Replication.
38
- this._replicatorProtocolPluginFactory =
39
- new ReplicatorProtocolPluginFactory(this._feedProvider);
40
- }
30
+ ) {}
41
31
 
42
32
  async start (plugins: Plugin[]) {
43
33
  if (this._started) {
@@ -73,9 +63,8 @@ export class PartyProtocolFactory {
73
63
  await this._networkManager.leaveProtocolSwarm(this._partyKey);
74
64
  }
75
65
 
76
- private _createProtocol (channel: any, opts: {initiator: boolean}, extraPlugins: Plugin[]) {
66
+ private _createProtocol (channel: any, opts: { initiator: boolean }, extraPlugins: Plugin[]) {
77
67
  const plugins: Plugin[] = [
78
- ...this._replicatorProtocolPluginFactory.createPlugins(),
79
68
  ...extraPlugins,
80
69
  this._presencePlugin
81
70
  ];
@@ -118,45 +107,3 @@ export class PartyProtocolFactory {
118
107
  return protocol;
119
108
  }
120
109
  }
121
-
122
- /**
123
- * Creates the protocol plugin for feed replication.
124
- */
125
- export class ReplicatorProtocolPluginFactory {
126
- constructor (
127
- private readonly _feedProvider: PartyFeedProvider
128
- ) {}
129
-
130
- createPlugins () {
131
- return [
132
- new Replicator({
133
- load: async () => {
134
- const feeds = this._feedProvider.getFeeds();
135
- log(`Loading feeds: ${feeds.map(feed => keyToString(feed.key))}`);
136
- return feeds.map((feed) => ({ discoveryKey: feed.feed.discoveryKey }));
137
- },
138
-
139
- subscribe: (addFeedToReplicatedSet: (feed: any) => void) => {
140
- return this._feedProvider.feedOpened.on(async (feed) => {
141
- log(`Adding feed: ${feed.key.toHex()}`);
142
- addFeedToReplicatedSet({ discoveryKey: feed.feed.discoveryKey });
143
- });
144
- },
145
-
146
- replicate: async (remoteFeeds, info) => {
147
- // We can ignore remoteFeeds entirely, since the set of feeds we want to replicate is dictated by the Party.
148
- // TODO(telackey): Why are we opening feeds? Necessary or belt/braces thinking, or because open party does it?
149
- const feeds = this._feedProvider.getFeeds();
150
- log(`Replicating: peerId=${info.session}; feeds=${feeds.map(feed => feed.key.toHex())}`);
151
- return feeds.map(feed => feed.feed);
152
- }
153
- })
154
- ];
155
- }
156
-
157
- @synchronized
158
- private async _openFeed (key: FeedKey): Promise<HypercoreFeed> {
159
- const descriptor = await this._feedProvider.createOrOpenReadOnlyFeed(key);
160
- return descriptor.feed;
161
- }
162
- }