@dxos/echo-db 2.33.5-dev.8e942d13 → 2.33.5-dev.97a81dd0

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 (149) 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-factory.d.ts.map +1 -1
  18. package/dist/src/halo/halo-factory.js +5 -11
  19. package/dist/src/halo/halo-factory.js.map +1 -1
  20. package/dist/src/halo/halo-party.d.ts +3 -3
  21. package/dist/src/halo/halo-party.d.ts.map +1 -1
  22. package/dist/src/halo/halo-party.js +6 -4
  23. package/dist/src/halo/halo-party.js.map +1 -1
  24. package/dist/src/halo/identity.js +2 -2
  25. package/dist/src/halo/identity.js.map +1 -1
  26. package/dist/src/halo/party-opener.d.ts +1 -1
  27. package/dist/src/halo/party-opener.d.ts.map +1 -1
  28. package/dist/src/halo/party-opener.js +2 -2
  29. package/dist/src/halo/party-opener.js.map +1 -1
  30. package/dist/src/halo/preferences.d.ts.map +1 -1
  31. package/dist/src/halo/preferences.js +7 -10
  32. package/dist/src/halo/preferences.js.map +1 -1
  33. package/dist/src/invitations/greeting-protocol-provider.d.ts.map +1 -1
  34. package/dist/src/invitations/greeting-protocol-provider.js +5 -9
  35. package/dist/src/invitations/greeting-protocol-provider.js.map +1 -1
  36. package/dist/src/invitations/greeting-responder.d.ts +2 -2
  37. package/dist/src/invitations/greeting-responder.d.ts.map +1 -1
  38. package/dist/src/invitations/greeting-responder.js +8 -12
  39. package/dist/src/invitations/greeting-responder.js.map +1 -1
  40. package/dist/src/invitations/invitation-factory.d.ts +2 -2
  41. package/dist/src/invitations/invitation-factory.d.ts.map +1 -1
  42. package/dist/src/invitations/invitation-factory.js.map +1 -1
  43. package/dist/src/invitations/offline-invitation-claimer.d.ts.map +1 -1
  44. package/dist/src/invitations/offline-invitation-claimer.js +5 -7
  45. package/dist/src/invitations/offline-invitation-claimer.js.map +1 -1
  46. package/dist/src/parties/data-party.d.ts +7 -5
  47. package/dist/src/parties/data-party.d.ts.map +1 -1
  48. package/dist/src/parties/data-party.js +12 -9
  49. package/dist/src/parties/data-party.js.map +1 -1
  50. package/dist/src/parties/data-party.test.js +12 -12
  51. package/dist/src/parties/data-party.test.js.map +1 -1
  52. package/dist/src/parties/party-factory.d.ts +0 -6
  53. package/dist/src/parties/party-factory.d.ts.map +1 -1
  54. package/dist/src/parties/party-factory.js +17 -45
  55. package/dist/src/parties/party-factory.js.map +1 -1
  56. package/dist/src/parties/party-manager.d.ts.map +1 -1
  57. package/dist/src/parties/party-manager.js +2 -1
  58. package/dist/src/parties/party-manager.js.map +1 -1
  59. package/dist/src/pipeline/message-selector.d.ts +2 -2
  60. package/dist/src/pipeline/message-selector.d.ts.map +1 -1
  61. package/dist/src/pipeline/message-selector.js +29 -29
  62. package/dist/src/pipeline/message-selector.js.map +1 -1
  63. package/dist/src/pipeline/party-core.d.ts +3 -2
  64. package/dist/src/pipeline/party-core.d.ts.map +1 -1
  65. package/dist/src/pipeline/party-core.js +5 -0
  66. package/dist/src/pipeline/party-core.js.map +1 -1
  67. package/dist/src/pipeline/party-core.test.js +8 -7
  68. package/dist/src/pipeline/party-core.test.js.map +1 -1
  69. package/dist/src/pipeline/party-processor.d.ts +23 -5
  70. package/dist/src/pipeline/party-processor.d.ts.map +1 -1
  71. package/dist/src/pipeline/party-processor.js.map +1 -1
  72. package/dist/src/pipeline/pipeline.d.ts +2 -4
  73. package/dist/src/pipeline/pipeline.d.ts.map +1 -1
  74. package/dist/src/pipeline/pipeline.js +0 -3
  75. package/dist/src/pipeline/pipeline.js.map +1 -1
  76. package/dist/src/protocol/auth-plugin.d.ts +1 -1
  77. package/dist/src/protocol/auth-plugin.d.ts.map +1 -1
  78. package/dist/src/protocol/auth-plugin.js +1 -3
  79. package/dist/src/protocol/auth-plugin.js.map +1 -1
  80. package/dist/src/protocol/authenticator.d.ts +2 -2
  81. package/dist/src/protocol/authenticator.d.ts.map +1 -1
  82. package/dist/src/protocol/authenticator.js +12 -16
  83. package/dist/src/protocol/authenticator.js.map +1 -1
  84. package/dist/src/protocol/halo-recovery-plugin.d.ts +1 -1
  85. package/dist/src/protocol/halo-recovery-plugin.d.ts.map +1 -1
  86. package/dist/src/protocol/halo-recovery-plugin.js +1 -3
  87. package/dist/src/protocol/halo-recovery-plugin.js.map +1 -1
  88. package/dist/src/protocol/identity-credentials.d.ts +2 -2
  89. package/dist/src/protocol/identity-credentials.d.ts.map +1 -1
  90. package/dist/src/protocol/identity-credentials.js +4 -4
  91. package/dist/src/protocol/identity-credentials.js.map +1 -1
  92. package/dist/src/protocol/offline-invitation-plugin.d.ts +1 -1
  93. package/dist/src/protocol/offline-invitation-plugin.d.ts.map +1 -1
  94. package/dist/src/protocol/offline-invitation-plugin.js +1 -3
  95. package/dist/src/protocol/offline-invitation-plugin.js.map +1 -1
  96. package/dist/src/protocol/party-protocol-factory.d.ts +1 -14
  97. package/dist/src/protocol/party-protocol-factory.d.ts.map +1 -1
  98. package/dist/src/protocol/party-protocol-factory.js +2 -55
  99. package/dist/src/protocol/party-protocol-factory.js.map +1 -1
  100. package/dist/src/protocol/replicator-plugin.d.ts +7 -0
  101. package/dist/src/protocol/replicator-plugin.d.ts.map +1 -0
  102. package/dist/src/protocol/replicator-plugin.js +36 -0
  103. package/dist/src/protocol/replicator-plugin.js.map +1 -0
  104. package/dist/src/snapshots/snapshot-generator.d.ts +1 -1
  105. package/dist/src/snapshots/snapshot-generator.d.ts.map +1 -1
  106. package/dist/src/snapshots/snapshot-generator.js +13 -15
  107. package/dist/src/snapshots/snapshot-generator.js.map +1 -1
  108. package/dist/src/testing/benchmark.test.d.ts +2 -0
  109. package/dist/src/testing/benchmark.test.d.ts.map +1 -0
  110. package/dist/src/testing/benchmark.test.js +25 -0
  111. package/dist/src/testing/benchmark.test.js.map +1 -0
  112. package/dist/src/testing/testing-factories.js +2 -2
  113. package/dist/src/testing/testing-factories.js.map +1 -1
  114. package/dist/tsconfig.tsbuildinfo +1 -1
  115. package/package.json +18 -18
  116. package/src/api/selection/queries.ts +14 -18
  117. package/src/api/selection/selection.test.ts +4 -12
  118. package/src/api/selection/selection.ts +1 -7
  119. package/src/database/item-demuxer.ts +2 -4
  120. package/src/database/item-manager.ts +2 -2
  121. package/src/database/testing.ts +1 -1
  122. package/src/halo/halo-factory.ts +6 -18
  123. package/src/halo/halo-party.ts +8 -7
  124. package/src/halo/identity.ts +2 -2
  125. package/src/halo/party-opener.ts +2 -2
  126. package/src/halo/preferences.ts +7 -10
  127. package/src/invitations/greeting-protocol-provider.ts +5 -9
  128. package/src/invitations/greeting-responder.ts +10 -14
  129. package/src/invitations/invitation-factory.ts +2 -2
  130. package/src/invitations/offline-invitation-claimer.ts +5 -7
  131. package/src/parties/data-party.test.ts +12 -12
  132. package/src/parties/data-party.ts +17 -13
  133. package/src/parties/party-factory.ts +23 -69
  134. package/src/parties/party-manager.ts +2 -1
  135. package/src/pipeline/message-selector.ts +30 -34
  136. package/src/pipeline/party-core.test.ts +10 -13
  137. package/src/pipeline/party-core.ts +7 -2
  138. package/src/pipeline/party-processor.ts +26 -2
  139. package/src/pipeline/pipeline.ts +2 -6
  140. package/src/protocol/auth-plugin.ts +1 -3
  141. package/src/protocol/authenticator.ts +27 -31
  142. package/src/protocol/halo-recovery-plugin.ts +4 -6
  143. package/src/protocol/identity-credentials.ts +4 -4
  144. package/src/protocol/offline-invitation-plugin.ts +4 -6
  145. package/src/protocol/party-protocol-factory.ts +3 -56
  146. package/src/protocol/replicator-plugin.ts +37 -0
  147. package/src/snapshots/snapshot-generator.ts +12 -16
  148. package/src/testing/benchmark.test.ts +30 -0
  149. package/src/testing/testing-factories.ts +2 -2
@@ -84,25 +84,21 @@ export const itemFilterToPredicate = (filter: ItemFilter | ItemIdFilter): Predic
84
84
  }
85
85
  };
86
86
 
87
- export const linkFilterToPredicate = (filter: LinkFilter): Predicate<Link> => {
88
- return link => (!filter.type || testOneOrMultiple(filter.type, link.type));
89
- };
87
+ export const linkFilterToPredicate = (filter: LinkFilter): Predicate<Link> => link => (!filter.type || testOneOrMultiple(filter.type, link.type));
90
88
 
91
89
  export const createQueryOptionsFilter = ({
92
90
  deleted = ItemFilterDeleted.HIDE_DELETED
93
- }: QueryOptions): Predicate<Entity> => {
94
- return entity => {
95
- if (entity.model === null) {
96
- return false;
97
- }
98
-
99
- switch (deleted) {
100
- case ItemFilterDeleted.HIDE_DELETED:
101
- return !(entity instanceof Item) || !entity.deleted;
102
- case ItemFilterDeleted.SHOW_DELETED:
103
- return true;
104
- case ItemFilterDeleted.SHOW_DELETED_ONLY:
105
- return entity instanceof Item && entity.deleted;
106
- }
107
- };
91
+ }: QueryOptions): Predicate<Entity> => entity => {
92
+ if (entity.model === null) {
93
+ return false;
94
+ }
95
+
96
+ switch (deleted) {
97
+ case ItemFilterDeleted.HIDE_DELETED:
98
+ return !(entity instanceof Item) || !entity.deleted;
99
+ case ItemFilterDeleted.SHOW_DELETED:
100
+ return true;
101
+ case ItemFilterDeleted.SHOW_DELETED_ONLY:
102
+ return entity instanceof Item && entity.deleted;
103
+ }
108
104
  };
@@ -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(
@@ -14,8 +14,7 @@ import {
14
14
  KeyType,
15
15
  Filter,
16
16
  SecretProvider,
17
- KeyHint,
18
- createFeedAdmitMessage
17
+ KeyHint
19
18
  } from '@dxos/credentials';
20
19
  import { keyToString, PublicKey, keyPairFromSeedPhrase } from '@dxos/crypto';
21
20
  import { ModelFactory } from '@dxos/model-factory';
@@ -94,21 +93,21 @@ export class HaloFactory {
94
93
  * B. Device key (the first "member" of the Identity's HALO).
95
94
  * C. Feed key (the feed owned by the Device).
96
95
  */
97
- await halo.processor.writeHaloMessage(createPartyGenesisMessage(this._keyring, identityKey, feedKeyPair.publicKey, deviceKey));
96
+ await halo.writeCredentialsMessage(createPartyGenesisMessage(this._keyring, identityKey, feedKeyPair.publicKey, deviceKey));
98
97
 
99
98
  /* 3. Make a special self-signed KeyAdmit message which will serve as an "IdentityGenesis" message. This
100
99
  * message will be copied into other Parties which we create or join.
101
100
  */
102
- await halo.processor.writeHaloMessage(createKeyAdmitMessage(this._keyring, identityKey.publicKey, identityKey));
101
+ await halo.writeCredentialsMessage(createKeyAdmitMessage(this._keyring, identityKey.publicKey, identityKey));
103
102
 
104
103
  if (options.identityDisplayName) {
105
104
  // 4. Write the IdentityInfo message with descriptive details (eg, display name).
106
- await halo.processor.writeHaloMessage(createIdentityInfoMessage(this._keyring, options.identityDisplayName, identityKey));
105
+ await halo.writeCredentialsMessage(createIdentityInfoMessage(this._keyring, options.identityDisplayName, identityKey));
107
106
  }
108
107
 
109
108
  if (options.deviceDisplayName) {
110
109
  // 5. Write the DeviceInfo message with descriptive details (eg, display name).
111
- await halo.processor.writeHaloMessage(createDeviceInfoMessage(this._keyring, options.deviceDisplayName, deviceKey));
110
+ await halo.writeCredentialsMessage(createDeviceInfoMessage(this._keyring, options.deviceDisplayName, deviceKey));
112
111
  }
113
112
 
114
113
  // Create special properties item.
@@ -193,22 +192,11 @@ export class HaloFactory {
193
192
  );
194
193
 
195
194
  await initiator.connect();
196
- const { partyKey, hints } = await initiator.redeemInvitation(secretProvider);
195
+ const { hints } = await initiator.redeemInvitation(secretProvider);
197
196
 
198
- /*
199
- * TODO(telackey): We shouldn't have to add our key here, it should be in the hints, but our hint
200
- * mechanism is broken by not waiting on the messages to be processed before returning.
201
- */
202
197
  const halo = await this.constructParty(hints);
203
198
  await halo.open();
204
199
 
205
- // Write the Feed genesis message.
206
- await halo.processor.writeHaloMessage(createFeedAdmitMessage(
207
- credentialsSigner.signer,
208
- partyKey,
209
- await halo.getWriteFeedKey(),
210
- [credentialsSigner.getDeviceKey()]
211
- ));
212
200
  await initiator.destroy();
213
201
 
214
202
  await halo.database.createItem({
@@ -5,10 +5,10 @@
5
5
  import assert from 'assert';
6
6
 
7
7
  import { Event, synchronized } from '@dxos/async';
8
- import { KeyHint } from '@dxos/credentials';
8
+ import { KeyHint, Message as HaloMessage } from '@dxos/credentials';
9
9
  import { PublicKey } from '@dxos/crypto';
10
10
  import { timed } from '@dxos/debug';
11
- import { Timeframe } from '@dxos/echo-protocol';
11
+ import { Timeframe, WriteReceipt } from '@dxos/echo-protocol';
12
12
  import { ModelFactory } from '@dxos/model-factory';
13
13
  import { NetworkManager } from '@dxos/network-manager';
14
14
 
@@ -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';
@@ -113,10 +114,6 @@ export class HaloParty {
113
114
  return this._partyCore.processor.credentialMessages.get(this._credentialsSigner.getIdentityKey().publicKey.toHex());
114
115
  }
115
116
 
116
- get memberKeys () {
117
- return this._partyCore.processor.memberKeys;
118
- }
119
-
120
117
  get credentialMessages () {
121
118
  return this._partyCore.processor.credentialMessages;
122
119
  }
@@ -161,13 +158,13 @@ export class HaloParty {
161
158
  this._protocol = new PartyProtocolFactory(
162
159
  this._partyCore.key,
163
160
  this._networkManager,
164
- this._feedProvider,
165
161
  peerId,
166
162
  createCredentialsProvider(this._credentialsSigner, this._partyCore.key, writeFeed.key)
167
163
  );
168
164
 
169
165
  // Replication.
170
166
  await this._protocol.start([
167
+ createReplicatorPlugin(this._feedProvider),
171
168
  createAuthPlugin(createAuthenticator(this._partyCore.processor, this._credentialsSigner), peerId),
172
169
  createHaloRecoveryPlugin(this._credentialsSigner.getIdentityKey().publicKey, this._invitationManager, peerId)
173
170
  ]);
@@ -199,6 +196,10 @@ export class HaloParty {
199
196
  return this;
200
197
  }
201
198
 
199
+ writeCredentialsMessage (message: HaloMessage): Promise<WriteReceipt> {
200
+ return this._partyCore.writeCredentialsMessage(message);
201
+ }
202
+
202
203
  async createInvitation (authenticationDetails: InvitationAuthenticator, options?: InvitationOptions): Promise<InvitationDescriptor> {
203
204
  assert(this._invitationManager, 'HALO party not open.');
204
205
  return this._invitationManager.createInvitation(authenticationDetails, options);
@@ -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
+ });
@@ -19,7 +19,7 @@ import { keyToString, randomBytes, PublicKey } from '@dxos/crypto';
19
19
  import { SwarmKey } from '@dxos/echo-protocol';
20
20
  import { FullyConnectedTopology, NetworkManager } from '@dxos/network-manager';
21
21
 
22
- import { PartyProcessor } from '../pipeline';
22
+ import { CredentialWriter, PartyStateProvider } from '../pipeline';
23
23
  import { CredentialsSigner } from '../protocol/credentials-signer';
24
24
  import { InvitationOptions } from './common';
25
25
  import { greetingProtocolProvider } from './greeting-protocol-provider';
@@ -57,7 +57,7 @@ export class GreetingResponder {
57
57
 
58
58
  constructor (
59
59
  private readonly _networkManager: NetworkManager,
60
- private readonly _partyProcessor: PartyProcessor,
60
+ private readonly _partyProcessor: CredentialWriter & PartyStateProvider,
61
61
  private readonly _credentialsSigner: CredentialsSigner
62
62
  ) {
63
63
  this._greeter = new Greeter(
@@ -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
- });
246
+ const memberKeys = this._partyProcessor.memberKeys.map((publicKey) => ({
247
+ publicKey,
248
+ type: KeyType.UNKNOWN
249
+ }));
252
250
 
253
- const memberFeeds = this._partyProcessor.feedKeys.map(publicKey => {
254
- return {
255
- publicKey,
256
- type: KeyType.FEED
257
- };
258
- });
251
+ const memberFeeds = this._partyProcessor.feedKeys.map((publicKey) => ({
252
+ publicKey,
253
+ type: KeyType.FEED
254
+ }));
259
255
 
260
256
  return [...memberKeys, ...memberFeeds];
261
257
  }
@@ -8,7 +8,7 @@ import { createPartyInvitationMessage } from '@dxos/credentials';
8
8
  import { PublicKey } from '@dxos/crypto';
9
9
  import { NetworkManager } from '@dxos/network-manager';
10
10
 
11
- import { PartyProcessor } from '../pipeline';
11
+ import { CredentialWriter, PartyStateProvider } from '../pipeline';
12
12
  import { CredentialsSigner } from '../protocol/credentials-signer';
13
13
  import { defaultInvitationAuthenticator, InvitationAuthenticator, InvitationOptions } from './common';
14
14
  import { GreetingResponder } from './greeting-responder';
@@ -19,7 +19,7 @@ import { InvitationDescriptor, InvitationDescriptorType } from './invitation-des
19
19
  */
20
20
  export class InvitationFactory {
21
21
  constructor (
22
- private readonly _partyProcessor: PartyProcessor,
22
+ private readonly _partyProcessor: CredentialWriter & PartyStateProvider,
23
23
  // This needs to be a provider in case this is a backend for the HALO party.
24
24
  // Then the identity would be changed after this is instantiated.
25
25
  private readonly _credentialsSigner: CredentialsSigner,
@@ -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
  }
@@ -59,8 +59,8 @@ describe('DataParty', () => {
59
59
  const party = await createParty(identity, partyKey.publicKey, []);
60
60
  await party.open();
61
61
 
62
- const feed = await party.feedProvider.createOrOpenWritableFeed();
63
- await party.processor.writeHaloMessage(createPartyGenesisMessage(
62
+ const feed = await party.getWriteFeed();
63
+ await party.writeCredentialsMessage(createPartyGenesisMessage(
64
64
  keyring,
65
65
  partyKey,
66
66
  feed.key,
@@ -79,8 +79,8 @@ describe('DataParty', () => {
79
79
 
80
80
  const party = await createParty(identity, partyKey.publicKey, []);
81
81
  await party.open();
82
- const feed = await party.feedProvider.createOrOpenWritableFeed();
83
- await party.processor.writeHaloMessage(createPartyGenesisMessage(
82
+ const feed = await party.getWriteFeed();
83
+ await party.writeCredentialsMessage(createPartyGenesisMessage(
84
84
  keyring,
85
85
  partyKey,
86
86
  feed.key,
@@ -103,8 +103,8 @@ describe('DataParty', () => {
103
103
 
104
104
  const party = await createParty(identityA, partyKey.publicKey, []);
105
105
  await party.open();
106
- const feed = await party.feedProvider.createOrOpenWritableFeed();
107
- await party.processor.writeHaloMessage(createPartyGenesisMessage(
106
+ const feed = await party.getWriteFeed();
107
+ await party.writeCredentialsMessage(createPartyGenesisMessage(
108
108
  keyring,
109
109
  partyKey,
110
110
  feed.key,
@@ -128,14 +128,14 @@ describe('DataParty', () => {
128
128
 
129
129
  const partyA = await createParty(identityA, partyKey.publicKey, []);
130
130
  await partyA.open();
131
- const feedA = await partyA.feedProvider.createOrOpenWritableFeed();
132
- await partyA.processor.writeHaloMessage(createPartyGenesisMessage(
131
+ const feedA = await partyA.getWriteFeed();
132
+ await partyA.writeCredentialsMessage(createPartyGenesisMessage(
133
133
  keyring,
134
134
  partyKey,
135
135
  feedA.key,
136
136
  partyKey
137
137
  ));
138
- await partyA.processor.writeHaloMessage(createKeyAdmitMessage(
138
+ await partyA.writeCredentialsMessage(createKeyAdmitMessage(
139
139
  keyring,
140
140
  partyKey.publicKey,
141
141
  identityA.identityKey,
@@ -164,14 +164,14 @@ describe('DataParty', () => {
164
164
 
165
165
  const partyA = await createParty(identityA, partyKeyA.publicKey, []);
166
166
  await partyA.open();
167
- const feedA = await partyA.feedProvider.createOrOpenWritableFeed();
168
- await partyA.processor.writeHaloMessage(createPartyGenesisMessage(
167
+ const feedA = await partyA.getWriteFeed();
168
+ await partyA.writeCredentialsMessage(createPartyGenesisMessage(
169
169
  identityA.keyring,
170
170
  partyKeyA,
171
171
  feedA.key,
172
172
  partyKeyA
173
173
  ));
174
- await partyA.processor.writeHaloMessage(createKeyAdmitMessage(
174
+ await partyA.writeCredentialsMessage(createKeyAdmitMessage(
175
175
  identityA.keyring,
176
176
  partyKeyA.publicKey,
177
177
  identityA.identityKey,
@@ -5,10 +5,11 @@
5
5
  import assert from 'assert';
6
6
 
7
7
  import { synchronized, Event } from '@dxos/async';
8
- import { KeyHint } from '@dxos/credentials';
8
+ import { KeyHint, Message as HaloMessage } from '@dxos/credentials';
9
9
  import { PublicKey } from '@dxos/crypto';
10
10
  import { timed } from '@dxos/debug';
11
- import { PartyKey, PartySnapshot, Timeframe } from '@dxos/echo-protocol';
11
+ import { PartyKey, PartySnapshot, Timeframe, WriteReceipt } from '@dxos/echo-protocol';
12
+ import { FeedDescriptor } from '@dxos/feed-store';
12
13
  import { ModelFactory } from '@dxos/model-factory';
13
14
  import { NetworkManager } from '@dxos/network-manager';
14
15
  import { ObjectModel } from '@dxos/object-model';
@@ -19,6 +20,7 @@ import { InvitationFactory } from '../invitations';
19
20
  import { PartyFeedProvider, PartyProtocolFactory, PartyCore, PartyOptions } from '../pipeline';
20
21
  import { createAuthPlugin, createOfflineInvitationPlugin, createAuthenticator, createCredentialsProvider } from '../protocol';
21
22
  import { CredentialsSigner } from '../protocol/credentials-signer';
23
+ import { createReplicatorPlugin } from '../protocol/replicator-plugin';
22
24
  import { SnapshotStore } from '../snapshots';
23
25
  import { CONTACT_DEBOUNCE_INTERVAL } from './party-manager';
24
26
 
@@ -125,16 +127,6 @@ export class DataParty {
125
127
  return this._invitationManager;
126
128
  }
127
129
 
128
- // TODO(burdon): Remove?
129
- get feedProvider (): PartyFeedProvider {
130
- return this._feedProvider;
131
- }
132
-
133
- get preferences (): PartyPreferences {
134
- assert(this._preferences, 'Preferences not available.');
135
- return this._preferences;
136
- }
137
-
138
130
  get title () {
139
131
  return this._preferences?.getLastKnownTitle();
140
132
  }
@@ -173,12 +165,12 @@ export class DataParty {
173
165
  this._protocol = new PartyProtocolFactory(
174
166
  this._partyCore.key,
175
167
  this._networkManager,
176
- this._feedProvider,
177
168
  deviceKey.publicKey,
178
169
  createCredentialsProvider(this._credentialsSigner, this._partyCore.key, writeFeed.key)
179
170
  );
180
171
 
181
172
  await this._protocol.start([
173
+ createReplicatorPlugin(this._feedProvider),
182
174
  createAuthPlugin(createAuthenticator(this._partyCore.processor, this._credentialsSigner), deviceKey.publicKey),
183
175
  createOfflineInvitationPlugin(this._invitationManager, deviceKey.publicKey)
184
176
  ]);
@@ -210,6 +202,18 @@ export class DataParty {
210
202
  return this;
211
203
  }
212
204
 
205
+ async getWriteFeed (): Promise<FeedDescriptor> {
206
+ return this._feedProvider.createOrOpenWritableFeed();
207
+ }
208
+
209
+ getFeeds (): FeedDescriptor[] {
210
+ return this._feedProvider.getFeeds();
211
+ }
212
+
213
+ writeCredentialsMessage (message: HaloMessage): Promise<WriteReceipt> {
214
+ return this._partyCore.writeCredentialsMessage(message);
215
+ }
216
+
213
217
  get isActive (): boolean {
214
218
  assert(this._preferences, 'PartyActivator required');
215
219
  return this._preferences.isActive;