@dxos/echo-db 2.33.5-dev.0d84e06f → 2.33.5-dev.33d2877e
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.
- package/dist/src/halo/halo-factory.d.ts +2 -2
- package/dist/src/halo/halo-factory.d.ts.map +1 -1
- package/dist/src/halo/halo-factory.js +2 -2
- package/dist/src/halo/halo-factory.js.map +1 -1
- package/dist/src/halo/halo-party.d.ts +3 -2
- package/dist/src/halo/halo-party.d.ts.map +1 -1
- package/dist/src/halo/halo-party.js +8 -4
- package/dist/src/halo/halo-party.js.map +1 -1
- package/dist/src/halo/party-opener.d.ts.map +1 -1
- package/dist/src/halo/party-opener.js +3 -1
- package/dist/src/halo/party-opener.js.map +1 -1
- package/dist/src/invitations/greeting-initiator.d.ts +2 -2
- package/dist/src/invitations/greeting-initiator.d.ts.map +1 -1
- package/dist/src/invitations/greeting-initiator.js +2 -1
- package/dist/src/invitations/greeting-initiator.js.map +1 -1
- package/dist/src/parties/data-party.d.ts +3 -3
- package/dist/src/parties/data-party.d.ts.map +1 -1
- package/dist/src/parties/data-party.js +8 -4
- package/dist/src/parties/data-party.js.map +1 -1
- package/dist/src/parties/data-party.test.js +5 -5
- package/dist/src/parties/data-party.test.js.map +1 -1
- package/dist/src/parties/party-factory.d.ts +2 -2
- package/dist/src/parties/party-factory.d.ts.map +1 -1
- package/dist/src/parties/party-factory.js +2 -2
- package/dist/src/parties/party-factory.js.map +1 -1
- package/dist/src/parties/party-manager.d.ts +3 -4
- package/dist/src/parties/party-manager.d.ts.map +1 -1
- package/dist/src/parties/party-manager.js +3 -5
- package/dist/src/parties/party-manager.js.map +1 -1
- package/dist/src/parties/party-manager.test.js +1 -4
- package/dist/src/parties/party-manager.test.js.map +1 -1
- package/dist/src/pipeline/metadata-store.js +1 -1
- package/dist/src/pipeline/metadata-store.js.map +1 -1
- package/dist/src/pipeline/party-core.d.ts +18 -4
- package/dist/src/pipeline/party-core.d.ts.map +1 -1
- package/dist/src/pipeline/party-core.js +7 -10
- package/dist/src/pipeline/party-core.js.map +1 -1
- package/dist/src/pipeline/party-core.test.js +4 -5
- package/dist/src/pipeline/party-core.test.js.map +1 -1
- package/dist/src/snapshots/snapshot-store.js +1 -1
- package/dist/src/snapshots/snapshot-store.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +17 -17
- package/src/halo/halo-factory.ts +3 -4
- package/src/halo/halo-party.ts +6 -4
- package/src/halo/party-opener.ts +3 -1
- package/src/invitations/greeting-initiator.ts +5 -4
- package/src/parties/data-party.test.ts +7 -6
- package/src/parties/data-party.ts +6 -5
- package/src/parties/party-factory.ts +2 -3
- package/src/parties/party-manager.test.ts +1 -4
- package/src/parties/party-manager.ts +3 -5
- package/src/pipeline/metadata-store.ts +1 -1
- package/src/pipeline/party-core.test.ts +4 -5
- package/src/pipeline/party-core.ts +27 -11
- package/src/snapshots/snapshot-store.ts +1 -1
package/src/halo/party-opener.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import debug from 'debug';
|
|
6
6
|
|
|
7
|
+
import { KeyType } from '@dxos/credentials';
|
|
7
8
|
import { SubscriptionGroup, Unsubscribe } from '@dxos/util';
|
|
8
9
|
|
|
9
10
|
import { PartyManager } from '../parties';
|
|
@@ -25,7 +26,8 @@ export const autoPartyOpener = (preferences: Preferences, partyManager: PartyMan
|
|
|
25
26
|
for (const partyDesc of values) {
|
|
26
27
|
if (!partyManager.parties.some(x => x.key === partyDesc.partyKey)) {
|
|
27
28
|
log(`Auto-opening new Party from HALO: ${partyDesc.partyKey.toHex()} hints=${JSON.stringify(partyDesc.keyHints)}`);
|
|
28
|
-
|
|
29
|
+
const feedHints = partyDesc.keyHints.filter(hint => hint.type === KeyType.FEED).map(hint => hint.publicKey!);
|
|
30
|
+
await partyManager.addParty(partyDesc.partyKey, feedHints);
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
}));
|
|
@@ -20,7 +20,8 @@ import {
|
|
|
20
20
|
SecretProvider,
|
|
21
21
|
WithTypeUrl,
|
|
22
22
|
ERR_GREET_CONNECTED_TO_SWARM_TIMEOUT,
|
|
23
|
-
SignedMessage
|
|
23
|
+
SignedMessage,
|
|
24
|
+
NotarizeResponse
|
|
24
25
|
} from '@dxos/credentials';
|
|
25
26
|
import { keyToString, PublicKey } from '@dxos/crypto';
|
|
26
27
|
import { FullyConnectedTopology, NetworkManager } from '@dxos/network-manager';
|
|
@@ -111,7 +112,7 @@ export class GreetingInitiator {
|
|
|
111
112
|
/**
|
|
112
113
|
* Called after connecting to initiate greeting protocol exchange.
|
|
113
114
|
*/
|
|
114
|
-
async redeemInvitation (secretProvider: SecretProvider) {
|
|
115
|
+
async redeemInvitation (secretProvider: SecretProvider): Promise<{ partyKey: PublicKey, hints: PublicKey[] }> {
|
|
115
116
|
assert(this._state === GreetingState.CONNECTED);
|
|
116
117
|
const { swarmKey } = this._invitationDescriptor;
|
|
117
118
|
|
|
@@ -150,7 +151,7 @@ export class GreetingInitiator {
|
|
|
150
151
|
const credentialMessages = await this._getMessagesToNotarize(PublicKey.from(partyKey), nonce);
|
|
151
152
|
|
|
152
153
|
// Send the signed payload to the greeting responder.
|
|
153
|
-
const notarizeResponse = await this._greeterPlugin.send(responderPeerId,
|
|
154
|
+
const notarizeResponse: NotarizeResponse = await this._greeterPlugin.send(responderPeerId,
|
|
154
155
|
createGreetingNotarizeMessage(secret, credentialMessages as WithTypeUrl<Message>[]));
|
|
155
156
|
|
|
156
157
|
//
|
|
@@ -171,7 +172,7 @@ export class GreetingInitiator {
|
|
|
171
172
|
this._state = GreetingState.SUCCEEDED;
|
|
172
173
|
return {
|
|
173
174
|
partyKey,
|
|
174
|
-
hints: notarizeResponse.
|
|
175
|
+
hints: notarizeResponse.feedHints ?? []
|
|
175
176
|
};
|
|
176
177
|
}
|
|
177
178
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import expect from 'expect';
|
|
6
6
|
import { it as test } from 'mocha';
|
|
7
7
|
|
|
8
|
-
import { createKeyAdmitMessage, createPartyGenesisMessage, defaultSecretProvider,
|
|
8
|
+
import { createKeyAdmitMessage, createPartyGenesisMessage, defaultSecretProvider, Keyring, KeyType, codec as haloCodec } from '@dxos/credentials';
|
|
9
9
|
import { PublicKey } from '@dxos/crypto';
|
|
10
10
|
import { codec } from '@dxos/echo-protocol';
|
|
11
11
|
import { FeedStore } from '@dxos/feed-store';
|
|
@@ -22,7 +22,7 @@ import { SnapshotStore } from '../snapshots';
|
|
|
22
22
|
import { DataParty } from './data-party';
|
|
23
23
|
|
|
24
24
|
describe('DataParty', () => {
|
|
25
|
-
const createParty = async (identity: IdentityCredentials, partyKey: PublicKey,
|
|
25
|
+
const createParty = async (identity: IdentityCredentials, partyKey: PublicKey, feedHints: PublicKey[]) => {
|
|
26
26
|
|
|
27
27
|
const storage = createStorage('', StorageType.RAM);
|
|
28
28
|
const snapshotStore = new SnapshotStore(storage.directory('snapshots'));
|
|
@@ -40,7 +40,7 @@ describe('DataParty', () => {
|
|
|
40
40
|
identity.createCredentialsSigner(),
|
|
41
41
|
identity.preferences,
|
|
42
42
|
networkManager,
|
|
43
|
-
|
|
43
|
+
feedHints
|
|
44
44
|
);
|
|
45
45
|
};
|
|
46
46
|
|
|
@@ -88,6 +88,7 @@ describe('DataParty', () => {
|
|
|
88
88
|
feed.key,
|
|
89
89
|
partyKey
|
|
90
90
|
));
|
|
91
|
+
await party.processor.feedAdded.waitForCount(1);
|
|
91
92
|
|
|
92
93
|
const authenticator = createAuthenticator(party.processor, identity.createCredentialsSigner(), party.credentialsWriter);
|
|
93
94
|
const credentialsProvider = createCredentialsProvider(identity.createCredentialsSigner(), party.key, feed.key);
|
|
@@ -112,6 +113,8 @@ describe('DataParty', () => {
|
|
|
112
113
|
feed.key,
|
|
113
114
|
partyKey
|
|
114
115
|
));
|
|
116
|
+
await party.processor.feedAdded.waitForCount(1);
|
|
117
|
+
|
|
115
118
|
const authenticator = createAuthenticator(party.processor, identityA.createCredentialsSigner(), party.credentialsWriter);
|
|
116
119
|
|
|
117
120
|
const identityB = await deriveTestDeviceCredentials(identityA);
|
|
@@ -145,9 +148,7 @@ describe('DataParty', () => {
|
|
|
145
148
|
));
|
|
146
149
|
|
|
147
150
|
const identityB = await deriveTestDeviceCredentials(identityA);
|
|
148
|
-
const partyB = await createParty(identityB, partyKey.publicKey, [
|
|
149
|
-
{ type: KeyType.FEED, publicKey: feedA.key }
|
|
150
|
-
]);
|
|
151
|
+
const partyB = await createParty(identityB, partyKey.publicKey, [feedA.key]);
|
|
151
152
|
await partyB.open();
|
|
152
153
|
|
|
153
154
|
await partyA.database.createItem({ type: 'test:item-a' });
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import assert from 'assert';
|
|
6
6
|
|
|
7
7
|
import { synchronized, Event } from '@dxos/async';
|
|
8
|
-
import { KeyHint } from '@dxos/credentials';
|
|
9
8
|
import { PublicKey } from '@dxos/crypto';
|
|
10
9
|
import { timed } from '@dxos/debug';
|
|
11
10
|
import { PartyKey, PartySnapshot, Timeframe } from '@dxos/echo-protocol';
|
|
@@ -57,8 +56,8 @@ export class DataParty {
|
|
|
57
56
|
// TODO(dmaretskyi): Pull this out to a higher level. Should preferences be part of client API instead?
|
|
58
57
|
private readonly _profilePreferences: Preferences | undefined,
|
|
59
58
|
private readonly _networkManager: NetworkManager,
|
|
60
|
-
private readonly
|
|
61
|
-
_initialTimeframe?: Timeframe,
|
|
59
|
+
private readonly _feedHints: PublicKey[] = [],
|
|
60
|
+
private readonly _initialTimeframe?: Timeframe,
|
|
62
61
|
_options: PartyOptions = {}
|
|
63
62
|
) {
|
|
64
63
|
this._partyCore = new PartyCore(
|
|
@@ -67,7 +66,6 @@ export class DataParty {
|
|
|
67
66
|
modelFactory,
|
|
68
67
|
snapshotStore,
|
|
69
68
|
this._credentialsSigner.getIdentityKey().publicKey,
|
|
70
|
-
_initialTimeframe,
|
|
71
69
|
_options
|
|
72
70
|
);
|
|
73
71
|
|
|
@@ -152,7 +150,10 @@ export class DataParty {
|
|
|
152
150
|
return this;
|
|
153
151
|
}
|
|
154
152
|
|
|
155
|
-
await this._partyCore.open(
|
|
153
|
+
await this._partyCore.open({
|
|
154
|
+
feedHints: this._feedHints,
|
|
155
|
+
initialTimeframe: this._initialTimeframe
|
|
156
|
+
});
|
|
156
157
|
|
|
157
158
|
this._invitationManager = new InvitationFactory(
|
|
158
159
|
this._partyCore.processor,
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
createEnvelopeMessage,
|
|
10
10
|
createFeedAdmitMessage,
|
|
11
11
|
createPartyGenesisMessage,
|
|
12
|
-
KeyHint,
|
|
13
12
|
KeyType,
|
|
14
13
|
SecretProvider,
|
|
15
14
|
wrapMessage
|
|
@@ -111,7 +110,7 @@ export class PartyFactory {
|
|
|
111
110
|
* @param partyKey
|
|
112
111
|
* @param hints
|
|
113
112
|
*/
|
|
114
|
-
async constructParty (partyKey: PartyKey,
|
|
113
|
+
async constructParty (partyKey: PartyKey, feedHints: PublicKey[] = [], initialTimeframe?: Timeframe) {
|
|
115
114
|
const identity = this._identityProvider() ?? raise(new IdentityNotInitializedError());
|
|
116
115
|
|
|
117
116
|
// TODO(marik-d): Support read-only parties if this feed doesn't exist?
|
|
@@ -128,7 +127,7 @@ export class PartyFactory {
|
|
|
128
127
|
identity.createCredentialsSigner(),
|
|
129
128
|
identity.preferences,
|
|
130
129
|
this._networkManager,
|
|
131
|
-
|
|
130
|
+
feedHints,
|
|
132
131
|
initialTimeframe,
|
|
133
132
|
this._options
|
|
134
133
|
);
|
|
@@ -140,10 +140,7 @@ describe('Party manager', () => {
|
|
|
140
140
|
const feedStream = createWritableFeedStream(feed);
|
|
141
141
|
feedStream.write(createPartyGenesisMessage(keyring, partyKey, feedKey.publicKey, identityKey));
|
|
142
142
|
|
|
143
|
-
await partyManager.addParty(partyKey.publicKey, [
|
|
144
|
-
type: KeyType.FEED,
|
|
145
|
-
publicKey: PublicKey.from(feed.key)
|
|
146
|
-
}]);
|
|
143
|
+
await partyManager.addParty(partyKey.publicKey, [PublicKey.from(feed.key)]);
|
|
147
144
|
|
|
148
145
|
await update;
|
|
149
146
|
});
|
|
@@ -157,11 +157,9 @@ export class PartyManager {
|
|
|
157
157
|
|
|
158
158
|
/**
|
|
159
159
|
* Construct a party object and start replicating with the remote peer that created that party.
|
|
160
|
-
* @param partyKey
|
|
161
|
-
* @param hints
|
|
162
160
|
*/
|
|
163
161
|
@synchronized
|
|
164
|
-
async addParty (partyKey: PartyKey,
|
|
162
|
+
async addParty (partyKey: PartyKey, feedHints: PublicKey[] = []) {
|
|
165
163
|
assert(this._open, 'PartyManager is not open.');
|
|
166
164
|
|
|
167
165
|
/*
|
|
@@ -174,8 +172,8 @@ export class PartyManager {
|
|
|
174
172
|
return this._parties.get(partyKey);
|
|
175
173
|
}
|
|
176
174
|
|
|
177
|
-
log(`Adding party partyKey=${partyKey.toHex()} hints=${
|
|
178
|
-
const party = await this._partyFactory.constructParty(partyKey,
|
|
175
|
+
log(`Adding party partyKey=${partyKey.toHex()} hints=${feedHints.length}`);
|
|
176
|
+
const party = await this._partyFactory.constructParty(partyKey, feedHints);
|
|
179
177
|
await party.open();
|
|
180
178
|
await this._metadataStore.addParty(party.key);
|
|
181
179
|
this._setParty(party);
|
|
@@ -161,7 +161,7 @@ describe('PartyCore', () => {
|
|
|
161
161
|
|
|
162
162
|
const feedOpened = feedStore.feedOpenedEvent.waitForCount(1);
|
|
163
163
|
|
|
164
|
-
await party.open(
|
|
164
|
+
await party.open({ feedHints: [otherFeedKey] });
|
|
165
165
|
afterTest(async () => party.close());
|
|
166
166
|
|
|
167
167
|
await feedOpened;
|
|
@@ -281,10 +281,9 @@ describe('PartyCore', () => {
|
|
|
281
281
|
[peer1.partyKey]
|
|
282
282
|
));
|
|
283
283
|
|
|
284
|
-
await party2.open(
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
}]);
|
|
284
|
+
await party2.open({
|
|
285
|
+
feedHints: [peer1.feedKey]
|
|
286
|
+
});
|
|
288
287
|
afterTest(async () => party2.close());
|
|
289
288
|
|
|
290
289
|
createTestProtocolPair(
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import assert from 'assert';
|
|
6
6
|
|
|
7
7
|
import { synchronized } from '@dxos/async';
|
|
8
|
-
import {
|
|
8
|
+
import { KeyType, Message as HaloMessage } from '@dxos/credentials';
|
|
9
9
|
import { PublicKey } from '@dxos/crypto';
|
|
10
10
|
import { timed } from '@dxos/debug';
|
|
11
11
|
import { createFeedWriter, DatabaseSnapshot, FeedWriter, PartyKey, PartySnapshot, Timeframe } from '@dxos/echo-protocol';
|
|
@@ -28,6 +28,22 @@ export interface PartyOptions {
|
|
|
28
28
|
snapshotInterval?: number;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
export interface OpenOptions {
|
|
32
|
+
/**
|
|
33
|
+
* Keys of initial feeds needed to bootstrap the party.
|
|
34
|
+
*/
|
|
35
|
+
feedHints?: PublicKey[]
|
|
36
|
+
/**
|
|
37
|
+
* Timeframe to start processing feed messages from.
|
|
38
|
+
*/
|
|
39
|
+
initialTimeframe?: Timeframe
|
|
40
|
+
/**
|
|
41
|
+
* Timeframe which must be reached until further processing.
|
|
42
|
+
* PartyCore.open will block until this timeframe is reached.
|
|
43
|
+
*/
|
|
44
|
+
targetTimeframe?: Timeframe
|
|
45
|
+
}
|
|
46
|
+
|
|
31
47
|
/**
|
|
32
48
|
* Encapsulates core components needed by a party:
|
|
33
49
|
* - ECHO database with item-manager & item-demuxer.
|
|
@@ -55,7 +71,6 @@ export class PartyCore {
|
|
|
55
71
|
private readonly _modelFactory: ModelFactory,
|
|
56
72
|
private readonly _snapshotStore: SnapshotStore,
|
|
57
73
|
private readonly _memberKey: PublicKey,
|
|
58
|
-
private readonly _initialTimeframe?: Timeframe,
|
|
59
74
|
private readonly _options: PartyOptions = {}
|
|
60
75
|
) { }
|
|
61
76
|
|
|
@@ -108,12 +123,17 @@ export class PartyCore {
|
|
|
108
123
|
*/
|
|
109
124
|
@synchronized
|
|
110
125
|
@timed(1_000)
|
|
111
|
-
async open (
|
|
126
|
+
async open (options: OpenOptions = {}) {
|
|
127
|
+
const {
|
|
128
|
+
feedHints = [],
|
|
129
|
+
initialTimeframe
|
|
130
|
+
} = options;
|
|
131
|
+
|
|
112
132
|
if (this.isOpen) {
|
|
113
133
|
return this;
|
|
114
134
|
}
|
|
115
135
|
|
|
116
|
-
this._timeframeClock = new TimeframeClock(
|
|
136
|
+
this._timeframeClock = new TimeframeClock(initialTimeframe);
|
|
117
137
|
|
|
118
138
|
// Open all feeds known from metadata and open or create a writable feed to the party.
|
|
119
139
|
await this._feedProvider.openKnownFeeds();
|
|
@@ -128,12 +148,8 @@ export class PartyCore {
|
|
|
128
148
|
void this._feedProvider.createOrOpenReadOnlyFeed(feed);
|
|
129
149
|
}));
|
|
130
150
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
await this._partyProcessor.takeHints([{ type: KeyType.FEED, publicKey: writableFeed.key }]);
|
|
134
|
-
|
|
135
|
-
if (keyHints.length > 0) {
|
|
136
|
-
await this._partyProcessor.takeHints(keyHints);
|
|
151
|
+
if (feedHints.length > 0) {
|
|
152
|
+
await this._partyProcessor.takeHints(feedHints.map(publicKey => ({ publicKey, type: KeyType.FEED })));
|
|
137
153
|
}
|
|
138
154
|
|
|
139
155
|
//
|
|
@@ -142,7 +158,7 @@ export class PartyCore {
|
|
|
142
158
|
|
|
143
159
|
const iterator = await this._feedProvider.createIterator(
|
|
144
160
|
createMessageSelector(this._partyProcessor, this._timeframeClock),
|
|
145
|
-
|
|
161
|
+
initialTimeframe
|
|
146
162
|
);
|
|
147
163
|
|
|
148
164
|
this._pipeline = new Pipeline(
|