@dxos/echo-db 2.33.3-dev.138ca606 → 2.33.3-dev.18553f06

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 (89) hide show
  1. package/dist/src/api/schema.d.ts.map +1 -1
  2. package/dist/src/api/schema.js +2 -4
  3. package/dist/src/api/schema.js.map +1 -1
  4. package/dist/src/echo.js +2 -2
  5. package/dist/src/echo.js.map +1 -1
  6. package/dist/src/echo.test.js +10 -10
  7. package/dist/src/echo.test.js.map +1 -1
  8. package/dist/src/halo/halo-party.d.ts.map +1 -1
  9. package/dist/src/halo/halo-party.js +1 -1
  10. package/dist/src/halo/halo-party.js.map +1 -1
  11. package/dist/src/halo/halo.d.ts +1 -0
  12. package/dist/src/halo/halo.d.ts.map +1 -1
  13. package/dist/src/halo/halo.js +10 -1
  14. package/dist/src/halo/halo.js.map +1 -1
  15. package/dist/src/halo/identity-manager.d.ts +0 -1
  16. package/dist/src/halo/identity-manager.d.ts.map +1 -1
  17. package/dist/src/halo/identity-manager.js +11 -11
  18. package/dist/src/halo/identity-manager.js.map +1 -1
  19. package/dist/src/halo/identity.d.ts +18 -13
  20. package/dist/src/halo/identity.d.ts.map +1 -1
  21. package/dist/src/halo/identity.js +24 -27
  22. package/dist/src/halo/identity.js.map +1 -1
  23. package/dist/src/invitations/offline-invitation-claimer.d.ts +2 -2
  24. package/dist/src/invitations/offline-invitation-claimer.d.ts.map +1 -1
  25. package/dist/src/invitations/offline-invitation-claimer.js +2 -4
  26. package/dist/src/invitations/offline-invitation-claimer.js.map +1 -1
  27. package/dist/src/parties/data-party.d.ts.map +1 -1
  28. package/dist/src/parties/data-party.js +1 -1
  29. package/dist/src/parties/data-party.js.map +1 -1
  30. package/dist/src/parties/data-party.test.d.ts +2 -0
  31. package/dist/src/parties/data-party.test.d.ts.map +1 -0
  32. package/dist/src/parties/data-party.test.js +129 -0
  33. package/dist/src/parties/data-party.test.js.map +1 -0
  34. package/dist/src/parties/party-factory.d.ts +2 -2
  35. package/dist/src/parties/party-factory.d.ts.map +1 -1
  36. package/dist/src/parties/party-factory.js +12 -20
  37. package/dist/src/parties/party-factory.js.map +1 -1
  38. package/dist/src/parties/party-manager.d.ts +2 -2
  39. package/dist/src/parties/party-manager.d.ts.map +1 -1
  40. package/dist/src/parties/party-manager.js +2 -1
  41. package/dist/src/parties/party-manager.js.map +1 -1
  42. package/dist/src/parties/party-manager.test.js +7 -22
  43. package/dist/src/parties/party-manager.test.js.map +1 -1
  44. package/dist/src/pipeline/metadata-store.d.ts.map +1 -1
  45. package/dist/src/pipeline/metadata-store.js +5 -6
  46. package/dist/src/pipeline/metadata-store.js.map +1 -1
  47. package/dist/src/pipeline/party-core.test.js +1 -1
  48. package/dist/src/pipeline/party-core.test.js.map +1 -1
  49. package/dist/src/pipeline/party-processor.d.ts +0 -5
  50. package/dist/src/pipeline/party-processor.d.ts.map +1 -1
  51. package/dist/src/pipeline/party-processor.js +0 -7
  52. package/dist/src/pipeline/party-processor.js.map +1 -1
  53. package/dist/src/protocol/credentials-signer.d.ts +4 -4
  54. package/dist/src/protocol/credentials-signer.d.ts.map +1 -1
  55. package/dist/src/protocol/credentials-signer.js +8 -8
  56. package/dist/src/protocol/credentials-signer.js.map +1 -1
  57. package/dist/src/protocol/identity-credentials.d.ts +22 -0
  58. package/dist/src/protocol/identity-credentials.d.ts.map +1 -0
  59. package/dist/src/protocol/identity-credentials.js +50 -0
  60. package/dist/src/protocol/identity-credentials.js.map +1 -0
  61. package/dist/src/protocol/party-protocol-factory.d.ts +3 -4
  62. package/dist/src/protocol/party-protocol-factory.d.ts.map +1 -1
  63. package/dist/src/protocol/party-protocol-factory.js +12 -15
  64. package/dist/src/protocol/party-protocol-factory.js.map +1 -1
  65. package/dist/src/snapshots/snapshot-store.d.ts.map +1 -1
  66. package/dist/src/snapshots/snapshot-store.js +5 -6
  67. package/dist/src/snapshots/snapshot-store.js.map +1 -1
  68. package/dist/tsconfig.tsbuildinfo +1 -1
  69. package/package.json +17 -17
  70. package/src/api/schema.ts +2 -4
  71. package/src/echo.test.ts +10 -10
  72. package/src/echo.ts +1 -1
  73. package/src/halo/halo-party.ts +1 -2
  74. package/src/halo/halo.ts +8 -1
  75. package/src/halo/identity-manager.ts +13 -14
  76. package/src/halo/identity.ts +39 -41
  77. package/src/invitations/offline-invitation-claimer.ts +6 -7
  78. package/src/parties/data-party.test.ts +212 -0
  79. package/src/parties/data-party.ts +1 -2
  80. package/src/parties/party-factory.ts +14 -20
  81. package/src/parties/party-manager.test.ts +8 -42
  82. package/src/parties/party-manager.ts +4 -3
  83. package/src/pipeline/metadata-store.ts +5 -6
  84. package/src/pipeline/party-core.test.ts +2 -4
  85. package/src/pipeline/party-processor.ts +0 -13
  86. package/src/protocol/credentials-signer.ts +9 -9
  87. package/src/protocol/identity-credentials.ts +78 -0
  88. package/src/protocol/party-protocol-factory.ts +13 -17
  89. package/src/snapshots/snapshot-store.ts +5 -6
@@ -33,9 +33,9 @@ import { createStorage, StorageType } from '@dxos/random-access-multi-storage';
33
33
  import { afterTest, testTimeout } from '@dxos/testutils';
34
34
 
35
35
  import { Item } from '../api';
36
- import { HaloFactory, Identity, IdentityManager } from '../halo';
37
36
  import { defaultInvitationAuthenticator, OfflineInvitationClaimer } from '../invitations';
38
37
  import { MetadataStore, PartyFeedProvider } from '../pipeline';
38
+ import { createTestIdentityCredentials } from '../protocol/identity-credentials';
39
39
  import { SnapshotStore } from '../snapshots';
40
40
  import { messageLogger } from '../testing';
41
41
  import { createRamStorage } from '../util';
@@ -58,33 +58,12 @@ const setup = async () => {
58
58
  const keyring = new Keyring();
59
59
  const metadataStore = new MetadataStore(createRamStorage());
60
60
  const feedStore = new FeedStore(createStorage('', StorageType.RAM), { valueEncoding: codec });
61
-
62
- const identityKey = await keyring.createKeyRecord({ type: KeyType.IDENTITY });
63
-
64
- assert(keyring.keys.length === 1);
65
-
66
61
  const snapshotStore = new SnapshotStore(createStorage('', StorageType.RAM));
67
62
  const modelFactory = new ModelFactory().registerModel(ObjectModel);
68
63
  const networkManager = new NetworkManager();
69
64
  const feedProviderFactory = (partyKey: PublicKey) => new PartyFeedProvider(metadataStore, keyring, feedStore, partyKey);
70
65
 
71
- const haloFactory = new HaloFactory(
72
- networkManager,
73
- modelFactory,
74
- snapshotStore,
75
- feedProviderFactory,
76
- keyring,
77
- {
78
- writeLogger: messageLogger('<<<'),
79
- readLogger: messageLogger('>>>')
80
- }
81
- );
82
- const haloParty = await haloFactory.createHalo({
83
- identityDisplayName: identityKey.publicKey.humanize()
84
- });
85
- afterTest(() => haloParty.close());
86
- const identity = new Identity(keyring, haloParty);
87
-
66
+ const identity = await createTestIdentityCredentials(keyring);
88
67
  const partyFactory = new PartyFactory(
89
68
  () => identity,
90
69
  networkManager,
@@ -171,33 +150,22 @@ describe('Party manager', () => {
171
150
  test('Create from cold start', async () => {
172
151
  const storage = createStorage('', StorageType.RAM);
173
152
  const feedStore = new FeedStore(storage, { valueEncoding: codec });
174
-
175
153
  const keyring = new Keyring();
176
154
  const metadataStore = new MetadataStore(createRamStorage());
177
-
178
- const identityKey = await keyring.createKeyRecord({ type: KeyType.IDENTITY });
179
- await keyring.createKeyRecord({ type: KeyType.DEVICE });
180
-
181
155
  const modelFactory = new ModelFactory().registerModel(ObjectModel);
182
156
  const snapshotStore = new SnapshotStore(createStorage('', StorageType.RAM));
183
157
  const networkManager = new NetworkManager();
184
158
  const feedProviderFactory = (partyKey: PublicKey) => new PartyFeedProvider(metadataStore, keyring, feedStore, partyKey);
159
+
160
+ const identity = await createTestIdentityCredentials(keyring);
185
161
  const partyFactory = new PartyFactory(
186
- () => identityManager.identity,
162
+ () => identity,
187
163
  networkManager,
188
164
  modelFactory,
189
165
  snapshotStore,
190
166
  feedProviderFactory
191
167
  );
192
- const haloFactory: HaloFactory = new HaloFactory(
193
- networkManager,
194
- modelFactory,
195
- snapshotStore,
196
- feedProviderFactory,
197
- keyring
198
- );
199
- const identityManager = new IdentityManager(keyring, haloFactory, metadataStore);
200
- const partyManager = new PartyManager(metadataStore, snapshotStore, () => identityManager.identity, partyFactory);
168
+ const partyManager = new PartyManager(metadataStore, snapshotStore, () => identity, partyFactory);
201
169
 
202
170
  /* TODO(telackey): Injecting "raw" Parties into the feeds behind the scenes seems fishy to me, as it writes the
203
171
  * Party messages in a slightly different way than the code inside PartyFactory does, and so could easily diverge
@@ -221,7 +189,7 @@ describe('Party manager', () => {
221
189
  assert(feedKey);
222
190
 
223
191
  const feedStream = createWritableFeedStream(feed);
224
- feedStream.write({ halo: createPartyGenesisMessage(keyring, partyKey, feedKey.publicKey, identityKey) });
192
+ feedStream.write({ halo: createPartyGenesisMessage(keyring, partyKey, feedKey.publicKey, identity.identityKey) });
225
193
  feedStream.write({
226
194
  echo: checkType<EchoEnvelope>({
227
195
  itemId: 'foo',
@@ -235,8 +203,6 @@ describe('Party manager', () => {
235
203
  }
236
204
 
237
205
  // Open.
238
- await identityManager.createHalo();
239
- afterTest(() => identityManager.close());
240
206
  await partyManager.open();
241
207
  expect(partyManager.parties).toHaveLength(numParties);
242
208
  await partyManager.close();
@@ -450,7 +416,7 @@ describe('Party manager', () => {
450
416
  // Redeem the invitation on B.
451
417
  expect(partyManagerB.parties).toHaveLength(0);
452
418
  const partyB = await partyManagerB.joinParty(invitationDescriptor,
453
- OfflineInvitationClaimer.createSecretProvider(identityB));
419
+ OfflineInvitationClaimer.createSecretProvider(identityB.createCredentialsSigner()));
454
420
  expect(partyB).toBeDefined();
455
421
  log(`Joined ${partyB.key.toHex()}`);
456
422
 
@@ -13,9 +13,9 @@ import { timed } from '@dxos/debug';
13
13
  import { PartyKey, PartySnapshot } from '@dxos/echo-protocol';
14
14
  import { ComplexMap, boolGuard } from '@dxos/util';
15
15
 
16
- import { IdentityProvider } from '../halo';
17
16
  import { InvitationDescriptor } from '../invitations';
18
17
  import { MetadataStore } from '../pipeline';
18
+ import { IdentityCredentialsProvider } from '../protocol/identity-credentials';
19
19
  import { SnapshotStore } from '../snapshots';
20
20
  import { DataParty, PARTY_ITEM_TYPE, PARTY_TITLE_PROPERTY } from './data-party';
21
21
  import { PartyFactory } from './party-factory';
@@ -51,7 +51,7 @@ export class PartyManager {
51
51
  constructor (
52
52
  private readonly _metadataStore: MetadataStore,
53
53
  private readonly _snapshotStore: SnapshotStore,
54
- private readonly _identityProvider: IdentityProvider,
54
+ private readonly _identityProvider: IdentityCredentialsProvider,
55
55
  private readonly _partyFactory: PartyFactory
56
56
  ) {}
57
57
 
@@ -74,10 +74,11 @@ export class PartyManager {
74
74
 
75
75
  let partyKeys = this._metadataStore.parties.map(party => party.key).filter(boolGuard);
76
76
 
77
+ // Identity may be undefined, for example, on the first start.
77
78
  const identity = this._identityProvider();
78
79
 
79
80
  // TODO(telackey): Does it make any sense to load other parties if we don't have an HALO?
80
- if (identity?.identityKey) {
81
+ if (identity) {
81
82
  partyKeys = partyKeys.filter(partyKey => !partyKey.equals(identity.identityKey!.publicKey));
82
83
  }
83
84
 
@@ -4,7 +4,6 @@
4
4
 
5
5
  import assert from 'assert';
6
6
  import debug from 'debug';
7
- import pify from 'pify';
8
7
 
9
8
  import { PublicKey } from '@dxos/crypto';
10
9
  import { failUndefined } from '@dxos/debug';
@@ -50,12 +49,12 @@ export class MetadataStore {
50
49
  async load (): Promise<void> {
51
50
  const file = this._storage.createOrOpen('EchoMetadata');
52
51
  try {
53
- const { size } = await pify(file.stat.bind(file))();
52
+ const { size } = await file.stat();
54
53
  if (size === 0) {
55
54
  return;
56
55
  }
57
56
 
58
- const data = await pify(file.read.bind(file))(0, size);
57
+ const data = await file.read(0, size);
59
58
  this._metadata = schema.getCodecForType('dxos.echo.metadata.EchoMetadata').decode(data);
60
59
  } catch (err: any) {
61
60
  if (err.code === 'ENOENT') {
@@ -64,7 +63,7 @@ export class MetadataStore {
64
63
  throw err;
65
64
  }
66
65
  } finally {
67
- await pify(file.close.bind(file))();
66
+ await file.close();
68
67
  }
69
68
  }
70
69
 
@@ -80,9 +79,9 @@ export class MetadataStore {
80
79
 
81
80
  try {
82
81
  const encoded = Buffer.from(schema.getCodecForType('dxos.echo.metadata.EchoMetadata').encode(data));
83
- await pify(file.write.bind(file))(0, encoded);
82
+ await file.write(0, encoded);
84
83
  } finally {
85
- await pify(file.close.bind(file))();
84
+ await file.close();
86
85
  }
87
86
  }
88
87
 
@@ -325,12 +325,10 @@ describe('PartyCore', () => {
325
325
 
326
326
  createTestProtocolPair(
327
327
  new ReplicatorProtocolPluginFactory(
328
- peer1.partyFeedProvider,
329
- peer1.party.processor.getActiveFeedSet()
328
+ peer1.partyFeedProvider
330
329
  ).createPlugins().map(r => r.createExtension()),
331
330
  new ReplicatorProtocolPluginFactory(
332
- partyFeedProvider,
333
- peer1.party.processor.getActiveFeedSet()
331
+ partyFeedProvider
334
332
  ).createPlugins().map(r => r.createExtension())
335
333
  );
336
334
 
@@ -20,11 +20,6 @@ import { jsonReplacer } from '@dxos/util';
20
20
 
21
21
  const log = debug('dxos:echo-db:party-processor');
22
22
 
23
- export interface FeedSetProvider {
24
- get(): FeedKey[]
25
- added: Event<FeedKey>
26
- }
27
-
28
23
  /**
29
24
  * TODO(burdon): Wrapper/Bridge between HALO APIs.
30
25
  */
@@ -108,14 +103,6 @@ export class PartyProcessor {
108
103
  return this._state.getAdmittedBy(feedKey);
109
104
  }
110
105
 
111
- // TODO(burdon): Rename xxxProvider.
112
- getActiveFeedSet (): FeedSetProvider {
113
- return {
114
- get: () => this.feedKeys,
115
- added: this.feedAdded
116
- };
117
- }
118
-
119
106
  getOfflineInvitation (invitationID: Buffer) {
120
107
  return this._state.getInvitation(invitationID);
121
108
  }
@@ -19,17 +19,17 @@ export class CredentialsSigner {
19
19
 
20
20
  return new CredentialsSigner(
21
21
  keyring,
22
- () => identityKey,
23
- () => deviceKey,
24
- () => deviceKey
22
+ identityKey,
23
+ deviceKey,
24
+ deviceKey
25
25
  );
26
26
  }
27
27
 
28
28
  constructor (
29
29
  private readonly _signer: Signer,
30
- private readonly _getIdentityKey: () => KeyRecord,
31
- private readonly _getDeviceKey: () => KeyRecord,
32
- private readonly _getDeviceSigningKeys: () => KeyRecord | KeyChain
30
+ private readonly _identityKey: KeyRecord,
31
+ private readonly _deviceKey: KeyRecord,
32
+ private readonly _signingKeys: KeyRecord | KeyChain
33
33
  ) {}
34
34
 
35
35
  get signer (): Signer {
@@ -37,11 +37,11 @@ export class CredentialsSigner {
37
37
  }
38
38
 
39
39
  getIdentityKey (): KeyRecord {
40
- return this._getIdentityKey();
40
+ return this._identityKey;
41
41
  }
42
42
 
43
43
  getDeviceKey (): KeyRecord {
44
- return this._getDeviceKey();
44
+ return this._deviceKey;
45
45
  }
46
46
 
47
47
  /**
@@ -55,6 +55,6 @@ export class CredentialsSigner {
55
55
  * Devices need to sign with their keyChain including the device key admission credential in the signature.
56
56
  */
57
57
  getDeviceSigningKeys (): KeyRecord | KeyChain {
58
- return this._getDeviceSigningKeys();
58
+ return this._signingKeys;
59
59
  }
60
60
  }
@@ -0,0 +1,78 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import { createIdentityInfoMessage, createKeyAdmitMessage, createPartyGenesisMessage, KeyChain, KeyRecord, Keyring, KeyType, SignedMessage } from '@dxos/credentials';
6
+
7
+ import { ContactManager, Preferences } from '../halo';
8
+ import { CredentialsSigner } from './credentials-signer';
9
+
10
+ /**
11
+ * Provides access to identity credentials without revealing the underlying mechanism (HALO party).
12
+ */
13
+ export interface IdentityCredentials {
14
+ keyring: Keyring
15
+ identityKey: KeyRecord
16
+ deviceKey: KeyRecord
17
+ deviceKeyChain: KeyChain
18
+ identityGenesis: SignedMessage
19
+ identityInfo: SignedMessage | undefined
20
+ displayName: string | undefined
21
+ createCredentialsSigner(): CredentialsSigner
22
+ preferences: Preferences | undefined
23
+ contacts: ContactManager | undefined
24
+ }
25
+
26
+ export type IdentityCredentialsProvider = () => IdentityCredentials | undefined
27
+
28
+ export async function createTestIdentityCredentials (keyring: Keyring): Promise<IdentityCredentials> {
29
+ const identityKey = await keyring.createKeyRecord({ type: KeyType.IDENTITY });
30
+ const deviceKey = await keyring.createKeyRecord({ type: KeyType.DEVICE });
31
+ const feedKey = await keyring.createKeyRecord({ type: KeyType.FEED });
32
+
33
+ const partyGenesis = createPartyGenesisMessage(keyring, identityKey, feedKey.publicKey, deviceKey);
34
+ const keyAdmit = createKeyAdmitMessage(keyring, identityKey.publicKey, identityKey);
35
+
36
+ const messageMap = new Map();
37
+ messageMap.set(identityKey.publicKey.toHex(), keyAdmit);
38
+ messageMap.set(deviceKey.publicKey.toHex(), partyGenesis);
39
+ const deviceKeyChain = Keyring.buildKeyChain(deviceKey.publicKey, messageMap, [feedKey.publicKey]);
40
+
41
+ const displayName = identityKey.publicKey.humanize();
42
+ const identityInfo = createIdentityInfoMessage(keyring, displayName, identityKey);
43
+
44
+ return {
45
+ keyring,
46
+ identityKey,
47
+ deviceKey,
48
+ deviceKeyChain,
49
+ identityGenesis: keyAdmit.payload as SignedMessage,
50
+ identityInfo: identityInfo.payload as SignedMessage,
51
+ displayName,
52
+ createCredentialsSigner: () => new CredentialsSigner(keyring, identityKey, deviceKey, deviceKeyChain),
53
+ preferences: undefined,
54
+ contacts: undefined
55
+ };
56
+ }
57
+
58
+ export async function deriveTestDeviceCredentials (identity: IdentityCredentials): Promise<IdentityCredentials> {
59
+ const deviceKey = await identity.keyring.createKeyRecord({ type: KeyType.DEVICE });
60
+ const keyAdmit = createKeyAdmitMessage(identity.keyring, identity.identityKey.publicKey, deviceKey, [identity.identityKey]);
61
+
62
+ const messageMap = new Map();
63
+ messageMap.set(identity.identityKey.publicKey.toHex(), identity.identityGenesis);
64
+ messageMap.set(deviceKey.publicKey.toHex(), keyAdmit);
65
+ const deviceKeyChain = Keyring.buildKeyChain(deviceKey.publicKey, messageMap, []);
66
+
67
+ return {
68
+ ...identity,
69
+ deviceKey,
70
+ deviceKeyChain,
71
+ createCredentialsSigner: () => new CredentialsSigner(
72
+ identity.keyring,
73
+ identity.identityKey,
74
+ deviceKey,
75
+ deviceKeyChain
76
+ )
77
+ };
78
+ }
@@ -6,7 +6,7 @@ import debug from 'debug';
6
6
 
7
7
  import { synchronized } from '@dxos/async';
8
8
  import { discoveryKey, keyToString, PublicKey } from '@dxos/crypto';
9
- import { FeedKey, FeedSetProvider, PartyKey } from '@dxos/echo-protocol';
9
+ import { FeedKey, PartyKey } from '@dxos/echo-protocol';
10
10
  import type { HypercoreFeed } from '@dxos/feed-store';
11
11
  import { Protocol } from '@dxos/mesh-protocol';
12
12
  import { MMSTTopology, NetworkManager, Plugin } from '@dxos/network-manager';
@@ -32,12 +32,11 @@ export class PartyProtocolFactory {
32
32
  private readonly _networkManager: NetworkManager,
33
33
  private readonly _feedProvider: PartyFeedProvider,
34
34
  private readonly _peerId: PublicKey,
35
- private readonly _credentials: CredentialsProvider,
36
- activeFeeds: FeedSetProvider
35
+ private readonly _credentials: CredentialsProvider
37
36
  ) {
38
37
  // Replication.
39
38
  this._replicatorProtocolPluginFactory =
40
- new ReplicatorProtocolPluginFactory(this._feedProvider, activeFeeds);
39
+ new ReplicatorProtocolPluginFactory(this._feedProvider);
41
40
  }
42
41
 
43
42
  async start (plugins: Plugin[]) {
@@ -125,34 +124,31 @@ export class PartyProtocolFactory {
125
124
  */
126
125
  export class ReplicatorProtocolPluginFactory {
127
126
  constructor (
128
- private readonly _feedProvider: PartyFeedProvider,
129
- private readonly _activeFeeds: FeedSetProvider
127
+ private readonly _feedProvider: PartyFeedProvider
130
128
  ) {}
131
129
 
132
130
  createPlugins () {
133
131
  return [
134
132
  new Replicator({
135
133
  load: async () => {
136
- const partyFeeds = await Promise.all(this._activeFeeds.get().map(feedKey => this._openFeed(feedKey)));
137
- log(`Loading feeds: ${partyFeeds.map(feed => keyToString(feed.key))}`);
138
- return partyFeeds.map((feed) => {
139
- return { discoveryKey: feed.discoveryKey };
140
- });
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 }));
141
137
  },
142
138
 
143
139
  subscribe: (addFeedToReplicatedSet: (feed: any) => void) => {
144
- return this._activeFeeds.added.on(async (feedKey) => {
145
- log(`Adding feed: ${feedKey.toHex()}`);
146
- const feed = await this._openFeed(feedKey);
147
- addFeedToReplicatedSet({ discoveryKey: feed.discoveryKey });
140
+ return this._feedProvider.feedOpened.on(async (feed) => {
141
+ log(`Adding feed: ${feed.key.toHex()}`);
142
+ addFeedToReplicatedSet({ discoveryKey: feed.feed.discoveryKey });
148
143
  });
149
144
  },
150
145
 
151
146
  replicate: async (remoteFeeds, info) => {
152
147
  // We can ignore remoteFeeds entirely, since the set of feeds we want to replicate is dictated by the Party.
153
148
  // TODO(telackey): Why are we opening feeds? Necessary or belt/braces thinking, or because open party does it?
154
- log(`Replicating: peerId=${info.session}; feeds=${this._activeFeeds.get().map(key => key.toHex())}`);
155
- return Promise.all(this._activeFeeds.get().map(feedKey => this._openFeed(feedKey)));
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);
156
152
  }
157
153
  })
158
154
  ];
@@ -4,7 +4,6 @@
4
4
 
5
5
  import assert from 'assert';
6
6
  import debug from 'debug';
7
- import pify from 'pify';
8
7
 
9
8
  import { keyToString } from '@dxos/crypto';
10
9
  import { schema, PartyKey, PartySnapshot } from '@dxos/echo-protocol';
@@ -26,12 +25,12 @@ export class SnapshotStore {
26
25
  const file = this._storage.createOrOpen(partyKey.toHex());
27
26
 
28
27
  try {
29
- const { size } = await pify(file.stat.bind(file))();
28
+ const { size } = await file.stat();
30
29
  if (size === 0) {
31
30
  return undefined;
32
31
  }
33
32
 
34
- const data = await pify(file.read.bind(file))(0, size);
33
+ const data = await file.read(0, size);
35
34
  return schema.getCodecForType('dxos.echo.snapshot.PartySnapshot').decode(data);
36
35
  } catch (err: any) {
37
36
  if (err.code === 'ENOENT') {
@@ -40,7 +39,7 @@ export class SnapshotStore {
40
39
  throw err;
41
40
  }
42
41
  } finally {
43
- await pify(file.close.bind(file))();
42
+ await file.close();
44
43
  }
45
44
  }
46
45
 
@@ -50,9 +49,9 @@ export class SnapshotStore {
50
49
 
51
50
  try {
52
51
  const data = schema.getCodecForType('dxos.echo.snapshot.PartySnapshot').encode(snapshot);
53
- await pify(file.write.bind(file))(0, Buffer.from(data));
52
+ await file.write(0, Buffer.from(data));
54
53
  } finally {
55
- await pify(file.close.bind(file))();
54
+ await file.close();
56
55
  }
57
56
  }
58
57