@dxos/client-services 0.1.30-next.a4f4fa5 → 0.1.30
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/lib/browser/{chunk-ZIQUYEJS.mjs → chunk-DFO3FW2W.mjs} +53 -20
- package/dist/lib/browser/{chunk-ZIQUYEJS.mjs.map → chunk-DFO3FW2W.mjs.map} +3 -3
- package/dist/lib/browser/index.mjs +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/testing/index.mjs +64 -6
- package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
- package/dist/lib/node/index.cjs +52 -19
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/packlets/testing/index.cjs +114 -22
- package/dist/lib/node/packlets/testing/index.cjs.map +3 -3
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +8 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +4 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +2 -0
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/tests/text.test.d.ts +2 -0
- package/dist/types/src/packlets/tests/text.test.d.ts.map +1 -0
- package/package.json +31 -30
- package/src/packlets/spaces/data-space-manager.test.ts +60 -0
- package/src/packlets/spaces/data-space-manager.ts +11 -7
- package/src/packlets/spaces/data-space.ts +13 -1
- package/src/packlets/spaces/notarization-plugin.ts +9 -2
- package/src/packlets/spaces/spaces-service.ts +25 -0
- package/src/packlets/testing/test-builder.ts +45 -5
- package/src/packlets/tests/spaces-invitations.test.ts +46 -6
- package/src/packlets/tests/spaces.test.ts +70 -2
- package/src/packlets/tests/text.test.ts +206 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-space-manager.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/spaces/data-space-manager.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAA4B,MAAM,aAAa,CAAC;AAG9D,OAAO,EACL,aAAa,EACb,cAAc,EAGd,YAAY,EACZ,wBAAwB,EAExB,aAAa,EACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAGnE,OAAO,EAAE,UAAU,EAAiB,MAAM,YAAY,CAAC;AAGvD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAIzC,oBAAY,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,SAAS,CAAC;IACpB,cAAc,EAAE,SAAS,CAAC;CAC3B,CAAC;AAEF,qBACa,gBAAgB;IAQzB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAdjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IAEtC,SAAgB,OAAO,cAAe;IAEtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwD;gBAG7D,aAAa,EAAE,YAAY,EAC3B,cAAc,EAAE,aAAa,EAC7B,yBAAyB,EAAE,wBAAwB,EACnD,QAAQ,EAAE,OAAO,EACjB,eAAe,EAAE,cAAc,EAC/B,aAAa,EAAE,YAAY,EAC3B,UAAU,EAAE,SAAS,CAAC,WAAW,CAAC,EAClC,cAAc,EAAE,aAAa;IAIhD,IAAI,MAAM,qCAET;IAGK,IAAI;IAuBJ,KAAK;IAOX;;OAEG;IAEG,WAAW;IAiCX,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,SAAS,CAAC;YAoBjD,eAAe;
|
|
1
|
+
{"version":3,"file":"data-space-manager.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/spaces/data-space-manager.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAA4B,MAAM,aAAa,CAAC;AAG9D,OAAO,EACL,aAAa,EACb,cAAc,EAGd,YAAY,EACZ,wBAAwB,EAExB,aAAa,EACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAGnE,OAAO,EAAE,UAAU,EAAiB,MAAM,YAAY,CAAC;AAGvD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAIzC,oBAAY,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,SAAS,CAAC;IACpB,cAAc,EAAE,SAAS,CAAC;CAC3B,CAAC;AAEF,qBACa,gBAAgB;IAQzB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAdjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IAEtC,SAAgB,OAAO,cAAe;IAEtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwD;gBAG7D,aAAa,EAAE,YAAY,EAC3B,cAAc,EAAE,aAAa,EAC7B,yBAAyB,EAAE,wBAAwB,EACnD,QAAQ,EAAE,OAAO,EACjB,eAAe,EAAE,cAAc,EAC/B,aAAa,EAAE,YAAY,EAC3B,UAAU,EAAE,SAAS,CAAC,WAAW,CAAC,EAClC,cAAc,EAAE,aAAa;IAIhD,IAAI,MAAM,qCAET;IAGK,IAAI;IAuBJ,KAAK;IAOX;;OAEG;IAEG,WAAW;IAiCX,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,SAAS,CAAC;YAoBjD,eAAe;CAqD9B"}
|
|
@@ -4,7 +4,8 @@ import { Keyring } from '@dxos/keyring';
|
|
|
4
4
|
import { PublicKey } from '@dxos/keys';
|
|
5
5
|
import { ModelFactory } from '@dxos/model-factory';
|
|
6
6
|
import { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
7
|
-
import {
|
|
7
|
+
import { GossipMessage } from '@dxos/protocols/proto/dxos/mesh/teleport/gossip';
|
|
8
|
+
import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
|
|
8
9
|
import { TrustedKeySetAuthVerifier } from '../identity';
|
|
9
10
|
import { NotarizationPlugin } from './notarization-plugin';
|
|
10
11
|
export declare type DataSpaceParams = {
|
|
@@ -12,6 +13,7 @@ export declare type DataSpaceParams = {
|
|
|
12
13
|
modelFactory: ModelFactory;
|
|
13
14
|
metadataStore: MetadataStore;
|
|
14
15
|
snapshotManager: SnapshotManager;
|
|
16
|
+
gossip: Gossip;
|
|
15
17
|
presence: Presence;
|
|
16
18
|
keyring: Keyring;
|
|
17
19
|
feedStore: FeedStore<FeedMessage>;
|
|
@@ -23,6 +25,7 @@ export declare class DataSpace {
|
|
|
23
25
|
private readonly _ctx;
|
|
24
26
|
private readonly _dataPipelineController;
|
|
25
27
|
private readonly _inner;
|
|
28
|
+
private readonly _gossip;
|
|
26
29
|
private readonly _presence;
|
|
27
30
|
private readonly _keyring;
|
|
28
31
|
private readonly _feedStore;
|
|
@@ -40,6 +43,10 @@ export declare class DataSpace {
|
|
|
40
43
|
get notarizationPlugin(): NotarizationPlugin;
|
|
41
44
|
open(): Promise<void>;
|
|
42
45
|
close(): Promise<void>;
|
|
46
|
+
postMessage(channel: string, message: any): Promise<void[]>;
|
|
47
|
+
listen(channel: string, callback: (message: GossipMessage) => void): {
|
|
48
|
+
unsubscribe: () => void;
|
|
49
|
+
};
|
|
43
50
|
initializeDataPipeline(): Promise<void>;
|
|
44
51
|
private _createWritableFeeds;
|
|
45
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-space.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/spaces/data-space.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,0BAA0B,EAC1B,aAAa,EACb,KAAK,EACL,cAAc,EAEd,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"data-space.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/spaces/data-space.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,0BAA0B,EAC1B,aAAa,EACb,KAAK,EACL,cAAc,EAEd,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,iDAAiD,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAGnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAI3D,oBAAY,eAAe,GAAG;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,eAAe,EAAE,eAAe,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;IAClC,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC,CAAC;AAGF,qBACa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA6B;IACrE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IACpD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAyC;IAErF,SAAgB,YAAY,EAAE,yBAAyB,CAAC;gBAE5C,MAAM,EAAE,eAAe;IA2BnC,IAAI,GAAG,cAEN;IAED,IAAI,MAAM,YAET;IAGD,IAAI,KAAK,UAER;IAED,IAAI,sBAAsB,IAAI,0BAA0B,CAEvD;IAED,IAAI,WAAW,sCAEd;IAED,IAAI,QAAQ,aAEX;IAED,IAAI,kBAAkB,uBAErB;IAEK,IAAI;IAMJ,KAAK;IAYL,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAI/C,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI;;;IAI5D,sBAAsB;YAmBd,oBAAoB;CA4CnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notarization-plugin.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/spaces/notarization-plugin.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAI9C,OAAO,EAAE,UAAU,EAAE,MAAM,6CAA6C,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,uDAAuD,CAAC;AAC7G,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"notarization-plugin.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/spaces/notarization-plugin.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAI9C,OAAO,EAAE,UAAU,EAAE,MAAM,6CAA6C,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,uDAAuD,CAAC;AAC7G,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAYhE;;GAEG;AACH,qBAAa,kBAAmB,YAAW,mBAAmB;IAC5D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAe;IAEhD,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4C;IACxE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA6C;IACnF,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAsD;IAE5F,IAAI;IAEJ,KAAK;IAIX;;OAEG;IACG,QAAQ,CAAC,WAAW,EAAE,UAAU,EAAE;IAuExC;;OAEG;IACG,OAAO,CAAC,UAAU,EAAE,UAAU;IASpC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC;YAK1B,mBAAmB;IAOjC;;OAEG;YACW,WAAW;IAazB,eAAe;CAehB;AAED,oBAAY,mCAAmC,GAAG;IAChD,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,UAAU,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD,CAAC;AAEF,qBAAa,6BAA8B,SAAQ,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC;IACrE,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,mCAAmC;cAWzD,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC;IAUjC,MAAM,CAAC,GAAG,EAAE,gBAAgB;IAK5B,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS;CAI/C;AAED,aAAK,QAAQ,GAAG;IACd,mBAAmB,EAAE,mBAAmB,CAAC;CAC1C,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Stream } from '@dxos/codec-protobuf';
|
|
2
2
|
import { DataServiceSubscriptions, SpaceManager } from '@dxos/echo-pipeline';
|
|
3
|
-
import { QueryCredentialsRequest, QuerySpacesResponse, Space, SpacesService, UpdateSpaceRequest, WriteCredentialsRequest } from '@dxos/protocols/proto/dxos/client/services';
|
|
3
|
+
import { PostMessageRequest, QueryCredentialsRequest, QuerySpacesResponse, Space, SpacesService, SubscribeMessagesRequest, UpdateSpaceRequest, WriteCredentialsRequest } from '@dxos/protocols/proto/dxos/client/services';
|
|
4
4
|
import { Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
5
|
+
import { GossipMessage } from '@dxos/protocols/proto/dxos/mesh/teleport/gossip';
|
|
5
6
|
import { Provider } from '@dxos/util';
|
|
6
7
|
import { IdentityManager } from '../identity';
|
|
7
8
|
import { DataSpaceManager } from './data-space-manager';
|
|
@@ -17,6 +18,8 @@ export declare class SpacesServiceImpl implements SpacesService {
|
|
|
17
18
|
createSpace(): Promise<Space>;
|
|
18
19
|
updateSpace(request: UpdateSpaceRequest): Promise<void>;
|
|
19
20
|
querySpaces(): Stream<QuerySpacesResponse>;
|
|
21
|
+
postMessage({ spaceKey, channel, message }: PostMessageRequest): Promise<void>;
|
|
22
|
+
subscribeMessages({ spaceKey, channel }: SubscribeMessagesRequest): Stream<GossipMessage>;
|
|
20
23
|
queryCredentials({ spaceKey }: QueryCredentialsRequest): Stream<Credential>;
|
|
21
24
|
writeCredentials({ spaceKey, credentials }: WriteCredentialsRequest): Promise<void>;
|
|
22
25
|
private _transformSpace;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spaces-service.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/spaces/spaces-service.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAsB,MAAM,qBAAqB,CAAC;AAEjG,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,KAAK,EAEL,aAAa,EAEb,kBAAkB,EAClB,uBAAuB,EACxB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,6CAA6C,CAAC;AACzE,OAAO,EAAY,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD;;GAEG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IAEnD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAC1C,OAAO,CAAC,QAAQ,CAAC,oBAAoB;gBAHpB,gBAAgB,EAAE,eAAe,EACjC,aAAa,EAAE,YAAY,EAC3B,yBAAyB,EAAE,wBAAwB,EACnD,oBAAoB,EAAE,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAGtE,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC;IAS7B,WAAW,CAAC,OAAO,EAAE,kBAAkB;IAI7C,WAAW,IAAI,MAAM,CAAC,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"spaces-service.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/spaces/spaces-service.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAsB,MAAM,qBAAqB,CAAC;AAEjG,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,KAAK,EAEL,aAAa,EAEb,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,EACxB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,6CAA6C,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,iDAAiD,CAAC;AAChF,OAAO,EAAY,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD;;GAEG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IAEnD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAC1C,OAAO,CAAC,QAAQ,CAAC,oBAAoB;gBAHpB,gBAAgB,EAAE,eAAe,EACjC,aAAa,EAAE,YAAY,EAC3B,yBAAyB,EAAE,wBAAwB,EACnD,oBAAoB,EAAE,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAGtE,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC;IAS7B,WAAW,CAAC,OAAO,EAAE,kBAAkB;IAI7C,WAAW,IAAI,MAAM,CAAC,mBAAmB,CAAC;IAgDpC,WAAW,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,kBAAkB;IAMpE,iBAAiB,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,wBAAwB;IAajE,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE,uBAAuB,GAAG,MAAM,CAAC,UAAU,CAAC;IAcrE,gBAAgB,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,uBAAuB;IAOzE,OAAO,CAAC,eAAe;CAmBxB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Client } from '@dxos/client';
|
|
2
2
|
import { Config } from '@dxos/config';
|
|
3
3
|
import { DatabaseBackendProxy } from '@dxos/echo-db';
|
|
4
|
+
import { PublicKey } from '@dxos/keys';
|
|
4
5
|
import { MemorySignalManagerContext } from '@dxos/messaging';
|
|
5
6
|
import { NetworkManager } from '@dxos/network-manager';
|
|
6
7
|
import { Storage } from '@dxos/random-access-storage';
|
|
@@ -36,4 +37,5 @@ export declare class TestBuilder {
|
|
|
36
37
|
}
|
|
37
38
|
export declare const testSpace: (create: DatabaseBackendProxy, check?: DatabaseBackendProxy) => Promise<import("@dxos/echo-db").MutateResult>;
|
|
38
39
|
export declare const syncItems: (db1: DatabaseBackendProxy, db2: DatabaseBackendProxy) => Promise<void>;
|
|
40
|
+
export declare const joinCommonSpace: ([initialPeer, ...peers]: Client[], spaceKey?: PublicKey) => Promise<PublicKey>;
|
|
39
41
|
//# sourceMappingURL=test-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-builder.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/testing/test-builder.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"test-builder.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/testing/test-builder.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAA8E,MAAM,cAAc,CAAC;AAClH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGtC,OAAO,EAAE,oBAAoB,EAAmB,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAuB,0BAA0B,EAA0B,MAAM,iBAAiB,CAAC;AAC1G,OAAO,EAAwD,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC7G,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAyC,YAAY,EAAE,MAAM,WAAW,CAAC;AAEhF,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEtE,eAAO,MAAM,yBAAyB,QAUpC,CAAC;AAEH;;GAEG;AACH,qBAAa,WAAW;IAQpB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IARxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAE1B,OAAO,CAAC,EAAE,OAAO,CAAC;gBAIvB,MAAM,CAAC,EAAE,MAAM,EACE,aAAa,6CAA8B,EAC3C,qBAAqB,6BAAmC;IAK3E,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACH,IAAI,cAAc,mBAkBjB;IAED;;OAEG;IACH,wBAAwB;IASxB;;OAEG;IACH,WAAW;IASX;;OAEG;IACH,kBAAkB,CAAC,IAAI,GAAE,kBAAoD,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;CAY3G;AAED,eAAO,MAAM,SAAS,WAAkB,oBAAoB,UAAS,oBAAoB,kDAexF,CAAC;AAEF,eAAO,MAAM,SAAS,QAAe,oBAAoB,OAAO,oBAAoB,kBAMnF,CAAC;AAEF,eAAO,MAAM,eAAe,4BAAmC,MAAM,EAAE,aAAa,SAAS,KAAG,QAAQ,SAAS,CAoChH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.test.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/tests/text.test.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/client-services",
|
|
3
|
-
"version": "0.1.30
|
|
3
|
+
"version": "0.1.30",
|
|
4
4
|
"description": "DXOS client services implementation",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -20,38 +20,39 @@
|
|
|
20
20
|
"src"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@dxos/async": "0.1.30
|
|
24
|
-
"@dxos/client": "0.1.30
|
|
25
|
-
"@dxos/codec-protobuf": "0.1.30
|
|
26
|
-
"@dxos/config": "0.1.30
|
|
27
|
-
"@dxos/context": "0.1.30
|
|
28
|
-
"@dxos/credentials": "0.1.30
|
|
29
|
-
"@dxos/crypto": "0.1.30
|
|
30
|
-
"@dxos/debug": "0.1.30
|
|
31
|
-
"@dxos/document-model": "0.1.30
|
|
32
|
-
"@dxos/echo-db": "0.1.30
|
|
33
|
-
"@dxos/echo-pipeline": "0.1.30
|
|
34
|
-
"@dxos/errors": "0.1.30
|
|
35
|
-
"@dxos/feed-store": "0.1.30
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/
|
|
38
|
-
"@dxos/
|
|
39
|
-
"@dxos/messaging": "0.1.30
|
|
40
|
-
"@dxos/model-factory": "0.1.30
|
|
41
|
-
"@dxos/network-manager": "0.1.30
|
|
42
|
-
"@dxos/node-std": "0.1.30
|
|
43
|
-
"@dxos/protocols": "0.1.30
|
|
44
|
-
"@dxos/random-access-storage": "0.1.30
|
|
45
|
-
"@dxos/rpc": "0.1.30
|
|
46
|
-
"@dxos/teleport": "0.1.30
|
|
47
|
-
"@dxos/teleport-extension-
|
|
48
|
-
"@dxos/text-model": "0.1.30
|
|
49
|
-
"@dxos/timeframe": "0.1.30
|
|
50
|
-
"@dxos/util": "0.1.30
|
|
23
|
+
"@dxos/async": "0.1.30",
|
|
24
|
+
"@dxos/client": "0.1.30",
|
|
25
|
+
"@dxos/codec-protobuf": "0.1.30",
|
|
26
|
+
"@dxos/config": "0.1.30",
|
|
27
|
+
"@dxos/context": "0.1.30",
|
|
28
|
+
"@dxos/credentials": "0.1.30",
|
|
29
|
+
"@dxos/crypto": "0.1.30",
|
|
30
|
+
"@dxos/debug": "0.1.30",
|
|
31
|
+
"@dxos/document-model": "0.1.30",
|
|
32
|
+
"@dxos/echo-db": "0.1.30",
|
|
33
|
+
"@dxos/echo-pipeline": "0.1.30",
|
|
34
|
+
"@dxos/errors": "0.1.30",
|
|
35
|
+
"@dxos/feed-store": "0.1.30",
|
|
36
|
+
"@dxos/keys": "0.1.30",
|
|
37
|
+
"@dxos/log": "0.1.30",
|
|
38
|
+
"@dxos/keyring": "0.1.30",
|
|
39
|
+
"@dxos/messaging": "0.1.30",
|
|
40
|
+
"@dxos/model-factory": "0.1.30",
|
|
41
|
+
"@dxos/network-manager": "0.1.30",
|
|
42
|
+
"@dxos/node-std": "0.1.30",
|
|
43
|
+
"@dxos/protocols": "0.1.30",
|
|
44
|
+
"@dxos/random-access-storage": "0.1.30",
|
|
45
|
+
"@dxos/rpc": "0.1.30",
|
|
46
|
+
"@dxos/teleport": "0.1.30",
|
|
47
|
+
"@dxos/teleport-extension-gossip": "0.1.30",
|
|
48
|
+
"@dxos/text-model": "0.1.30",
|
|
49
|
+
"@dxos/timeframe": "0.1.30",
|
|
50
|
+
"@dxos/util": "0.1.30"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/readable-stream": "^2.3.9",
|
|
54
|
-
"
|
|
54
|
+
"fast-check": "~3.3.0",
|
|
55
|
+
"@dxos/signal": "0.1.30"
|
|
55
56
|
},
|
|
56
57
|
"publishConfig": {
|
|
57
58
|
"access": "public"
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { expect } from 'chai';
|
|
6
6
|
|
|
7
|
+
import { latch } from '@dxos/async';
|
|
7
8
|
import { createAdmissionCredentials } from '@dxos/credentials';
|
|
8
9
|
import { DocumentModel } from '@dxos/document-model';
|
|
9
10
|
import { AuthStatus, DataServiceSubscriptions } from '@dxos/echo-pipeline';
|
|
@@ -128,4 +129,63 @@ describe('DataSpaceManager', () => {
|
|
|
128
129
|
expect(space2.inner.protocol.sessions.get(identity1.deviceKey)).to.exist;
|
|
129
130
|
expect(space2.inner.protocol.sessions.get(identity1.deviceKey)?.authStatus).to.equal(AuthStatus.SUCCESS);
|
|
130
131
|
});
|
|
132
|
+
|
|
133
|
+
test('pub/sub API', async () => {
|
|
134
|
+
const builder = new HostTestBuilder();
|
|
135
|
+
|
|
136
|
+
const peer1 = builder.createPeer();
|
|
137
|
+
const identity1 = await createSigningContext(peer1.keyring);
|
|
138
|
+
const dataSpaceManager1 = new DataSpaceManager(
|
|
139
|
+
peer1.spaceManager,
|
|
140
|
+
peer1.metadataStore,
|
|
141
|
+
new DataServiceSubscriptions(),
|
|
142
|
+
peer1.keyring,
|
|
143
|
+
identity1,
|
|
144
|
+
new ModelFactory().registerModel(DocumentModel),
|
|
145
|
+
peer1.feedStore,
|
|
146
|
+
peer1.snapshotStore
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const peer2 = builder.createPeer();
|
|
150
|
+
const identity2 = await createSigningContext(peer2.keyring);
|
|
151
|
+
const dataSpaceManager2 = new DataSpaceManager(
|
|
152
|
+
peer2.spaceManager,
|
|
153
|
+
peer2.metadataStore,
|
|
154
|
+
new DataServiceSubscriptions(),
|
|
155
|
+
peer2.keyring,
|
|
156
|
+
identity2,
|
|
157
|
+
new ModelFactory().registerModel(DocumentModel),
|
|
158
|
+
peer2.feedStore,
|
|
159
|
+
peer1.snapshotStore
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
const space1 = await dataSpaceManager1.createSpace();
|
|
163
|
+
await space1.inner.controlPipeline.state.waitUntilTimeframe(space1.inner.controlPipeline.state.endTimeframe);
|
|
164
|
+
|
|
165
|
+
// Admit peer2 to space1.
|
|
166
|
+
await writeMessages(
|
|
167
|
+
space1.inner.controlPipeline.writer,
|
|
168
|
+
await createAdmissionCredentials(
|
|
169
|
+
identity1.credentialSigner,
|
|
170
|
+
identity2.identityKey,
|
|
171
|
+
space1.key,
|
|
172
|
+
space1.inner.genesisFeedKey
|
|
173
|
+
)
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
// Accept must be called after admission so that the peer can authenticate for notarization.
|
|
177
|
+
const space2 = await dataSpaceManager2.acceptSpace({
|
|
178
|
+
spaceKey: space1.key,
|
|
179
|
+
genesisFeedKey: space1.inner.genesisFeedKey
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const [receivedMessage, inc] = latch({ count: 1 });
|
|
183
|
+
space2.listen('test', (message) => {
|
|
184
|
+
expect(message.channelId).to.equal('test');
|
|
185
|
+
inc();
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
await space1.postMessage('test', { '@type': 'google.protobuf.Any', test: true });
|
|
189
|
+
await receivedMessage();
|
|
190
|
+
});
|
|
131
191
|
});
|
|
@@ -24,7 +24,7 @@ import { log } from '@dxos/log';
|
|
|
24
24
|
import { ModelFactory } from '@dxos/model-factory';
|
|
25
25
|
import { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
26
26
|
import { SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
27
|
-
import { Presence } from '@dxos/teleport-extension-
|
|
27
|
+
import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
|
|
28
28
|
import { ComplexMap, deferFunction } from '@dxos/util';
|
|
29
29
|
|
|
30
30
|
import { createAuthProvider } from '../identity';
|
|
@@ -150,11 +150,14 @@ export class DataSpaceManager {
|
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
private async _constructSpace(metadata: SpaceMetadata) {
|
|
153
|
+
const gossip = new Gossip({
|
|
154
|
+
localPeerId: this._signingContext.deviceKey
|
|
155
|
+
});
|
|
153
156
|
const presence = new Presence({
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
157
|
+
announceInterval: 500,
|
|
158
|
+
offlineTimeout: 5_000, // TODO(burdon): Config.
|
|
159
|
+
identityKey: this._signingContext.identityKey,
|
|
160
|
+
gossip
|
|
158
161
|
});
|
|
159
162
|
const snapshotManager = new SnapshotManager(this._snapshotStore);
|
|
160
163
|
|
|
@@ -171,8 +174,8 @@ export class DataSpaceManager {
|
|
|
171
174
|
},
|
|
172
175
|
onNetworkConnection: (session) => {
|
|
173
176
|
session.addExtension(
|
|
174
|
-
'dxos.mesh.teleport.
|
|
175
|
-
|
|
177
|
+
'dxos.mesh.teleport.gossip',
|
|
178
|
+
gossip.createExtension({ remotePeerId: session.remotePeerId })
|
|
176
179
|
);
|
|
177
180
|
session.addExtension('dxos.mesh.teleport.objectsync', snapshotManager.objectSync.createExtension());
|
|
178
181
|
session.addExtension('dxos.mesh.teleport.notarization', dataSpace.notarizationPlugin.createExtension());
|
|
@@ -186,6 +189,7 @@ export class DataSpaceManager {
|
|
|
186
189
|
modelFactory: this._modelFactory,
|
|
187
190
|
metadataStore: this._metadataStore,
|
|
188
191
|
snapshotManager,
|
|
192
|
+
gossip,
|
|
189
193
|
presence,
|
|
190
194
|
memberKey: this._signingContext.identityKey,
|
|
191
195
|
keyring: this._keyring,
|
|
@@ -20,7 +20,8 @@ import { PublicKey } from '@dxos/keys';
|
|
|
20
20
|
import { ModelFactory } from '@dxos/model-factory';
|
|
21
21
|
import { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
22
22
|
import { AdmittedFeed, Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
23
|
-
import {
|
|
23
|
+
import { GossipMessage } from '@dxos/protocols/proto/dxos/mesh/teleport/gossip';
|
|
24
|
+
import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
|
|
24
25
|
import { ComplexSet } from '@dxos/util';
|
|
25
26
|
|
|
26
27
|
import { TrustedKeySetAuthVerifier } from '../identity';
|
|
@@ -33,6 +34,7 @@ export type DataSpaceParams = {
|
|
|
33
34
|
modelFactory: ModelFactory;
|
|
34
35
|
metadataStore: MetadataStore;
|
|
35
36
|
snapshotManager: SnapshotManager;
|
|
37
|
+
gossip: Gossip;
|
|
36
38
|
presence: Presence;
|
|
37
39
|
keyring: Keyring;
|
|
38
40
|
feedStore: FeedStore<FeedMessage>;
|
|
@@ -47,6 +49,7 @@ export class DataSpace {
|
|
|
47
49
|
private readonly _ctx = new Context();
|
|
48
50
|
private readonly _dataPipelineController: DataPipelineControllerImpl;
|
|
49
51
|
private readonly _inner: Space;
|
|
52
|
+
private readonly _gossip: Gossip;
|
|
50
53
|
private readonly _presence: Presence;
|
|
51
54
|
private readonly _keyring: Keyring;
|
|
52
55
|
private readonly _feedStore: FeedStore<FeedMessage>;
|
|
@@ -58,6 +61,7 @@ export class DataSpace {
|
|
|
58
61
|
|
|
59
62
|
constructor(params: DataSpaceParams) {
|
|
60
63
|
this._inner = params.inner;
|
|
64
|
+
this._gossip = params.gossip;
|
|
61
65
|
this._presence = params.presence;
|
|
62
66
|
this._keyring = params.keyring;
|
|
63
67
|
this._feedStore = params.feedStore;
|
|
@@ -129,6 +133,14 @@ export class DataSpace {
|
|
|
129
133
|
await this._presence.destroy();
|
|
130
134
|
}
|
|
131
135
|
|
|
136
|
+
async postMessage(channel: string, message: any) {
|
|
137
|
+
return this._gossip.postMessage(channel, message);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
listen(channel: string, callback: (message: GossipMessage) => void) {
|
|
141
|
+
return this._gossip.listen(channel, callback);
|
|
142
|
+
}
|
|
143
|
+
|
|
132
144
|
async initializeDataPipeline() {
|
|
133
145
|
await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({
|
|
134
146
|
timeout: CONTROL_PIPELINE_READY_TIMEFRAME
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import assert from 'node:assert';
|
|
6
6
|
|
|
7
|
-
import { DeferredTask, Event, scheduleTask, TimeoutError, Trigger } from '@dxos/async';
|
|
7
|
+
import { DeferredTask, Event, scheduleTask, sleep, TimeoutError, Trigger } from '@dxos/async';
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
9
|
import { CredentialProcessor } from '@dxos/credentials';
|
|
10
10
|
import { FeedWriter } from '@dxos/feed-store';
|
|
@@ -16,7 +16,13 @@ import { NotarizationService, NotarizeRequest } from '@dxos/protocols/proto/dxos
|
|
|
16
16
|
import { ExtensionContext, RpcExtension } from '@dxos/teleport';
|
|
17
17
|
import { ComplexMap, ComplexSet, entry } from '@dxos/util';
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
// Timeout for retrying notarization.
|
|
20
|
+
const RETRY_TIMEOUT = 1_000;
|
|
21
|
+
|
|
22
|
+
// Minimum wait time after a peer confirms successful notarization before attempting with a new peer.
|
|
23
|
+
const SUCCESS_DELAY = 1_000;
|
|
24
|
+
|
|
25
|
+
// Timeout for the whole notarization process.
|
|
20
26
|
const NOTARIZE_TIMEOUT = 10_000;
|
|
21
27
|
|
|
22
28
|
/**
|
|
@@ -92,6 +98,7 @@ export class NotarizationPlugin implements CredentialProcessor {
|
|
|
92
98
|
credentials: credentials.filter((credential) => !this._processedCredentials.has(credential.id!))
|
|
93
99
|
});
|
|
94
100
|
log('success');
|
|
101
|
+
await sleep(SUCCESS_DELAY); // wait before trying with a new peer
|
|
95
102
|
} catch (err) {
|
|
96
103
|
log.warn('error notarizing (recoverable)', err);
|
|
97
104
|
notarizeTask.schedule(); // retry immediately with next peer
|
|
@@ -8,16 +8,19 @@ import { raise, todo } from '@dxos/debug';
|
|
|
8
8
|
import { DataServiceSubscriptions, SpaceManager, SpaceNotFoundError } from '@dxos/echo-pipeline';
|
|
9
9
|
import { log } from '@dxos/log';
|
|
10
10
|
import {
|
|
11
|
+
PostMessageRequest,
|
|
11
12
|
QueryCredentialsRequest,
|
|
12
13
|
QuerySpacesResponse,
|
|
13
14
|
Space,
|
|
14
15
|
SpaceMember,
|
|
15
16
|
SpacesService,
|
|
16
17
|
SpaceStatus,
|
|
18
|
+
SubscribeMessagesRequest,
|
|
17
19
|
UpdateSpaceRequest,
|
|
18
20
|
WriteCredentialsRequest
|
|
19
21
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
20
22
|
import { Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
23
|
+
import { GossipMessage } from '@dxos/protocols/proto/dxos/mesh/teleport/gossip';
|
|
21
24
|
import { humanize, Provider } from '@dxos/util';
|
|
22
25
|
|
|
23
26
|
import { IdentityManager } from '../identity';
|
|
@@ -96,6 +99,25 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
96
99
|
});
|
|
97
100
|
}
|
|
98
101
|
|
|
102
|
+
async postMessage({ spaceKey, channel, message }: PostMessageRequest) {
|
|
103
|
+
const dataSpaceManager = await this._getDataSpaceManager();
|
|
104
|
+
const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));
|
|
105
|
+
await space.postMessage(getChannelId(channel), message);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
subscribeMessages({ spaceKey, channel }: SubscribeMessagesRequest) {
|
|
109
|
+
return new Stream<GossipMessage>(({ ctx, next }) => {
|
|
110
|
+
scheduleTask(ctx, async () => {
|
|
111
|
+
const dataSpaceManager = await this._getDataSpaceManager();
|
|
112
|
+
const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));
|
|
113
|
+
const handle = space.listen(getChannelId(channel), (message) => {
|
|
114
|
+
next(message);
|
|
115
|
+
});
|
|
116
|
+
ctx.onDispose(() => handle.unsubscribe());
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
99
121
|
queryCredentials({ spaceKey }: QueryCredentialsRequest): Stream<Credential> {
|
|
100
122
|
return new Stream(({ ctx, next }) => {
|
|
101
123
|
const space = this._spaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));
|
|
@@ -137,3 +159,6 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
137
159
|
};
|
|
138
160
|
}
|
|
139
161
|
}
|
|
162
|
+
|
|
163
|
+
// Add `user-channel` prefix to the channel name, so that it doesn't collide with the internal channels.
|
|
164
|
+
const getChannelId = (channel: string): string => `user-channel/${channel}`;
|
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
import assert from 'node:assert';
|
|
6
6
|
|
|
7
|
-
import { asyncTimeout } from '@dxos/async';
|
|
8
|
-
import { Client, ClientServices, ClientServicesProxy, createDefaultModelFactory } from '@dxos/client';
|
|
7
|
+
import { asyncTimeout, Trigger } from '@dxos/async';
|
|
8
|
+
import { Client, ClientServices, ClientServicesProxy, createDefaultModelFactory, Invitation } from '@dxos/client';
|
|
9
9
|
import { Config } from '@dxos/config';
|
|
10
|
+
import { raise } from '@dxos/debug';
|
|
10
11
|
import { DocumentModel } from '@dxos/document-model';
|
|
11
12
|
import { DatabaseBackendProxy, genesisMutation } from '@dxos/echo-db';
|
|
12
13
|
import { PublicKey } from '@dxos/keys';
|
|
14
|
+
import { log } from '@dxos/log';
|
|
13
15
|
import { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';
|
|
14
16
|
import { createWebRTCTransportFactory, MemoryTransportFactory, NetworkManager } from '@dxos/network-manager';
|
|
15
17
|
import { Storage } from '@dxos/random-access-storage';
|
|
@@ -119,12 +121,12 @@ export const testSpace = async (create: DatabaseBackendProxy, check: DatabaseBac
|
|
|
119
121
|
|
|
120
122
|
const result = create.mutate(genesisMutation(objectId, DocumentModel.meta.type));
|
|
121
123
|
|
|
122
|
-
await result.getReceipt();
|
|
124
|
+
await result.batch.getReceipt();
|
|
123
125
|
// TODO(dmaretskiy): await result.waitToBeProcessed()
|
|
124
|
-
assert(create._itemManager.entities.has(result.
|
|
126
|
+
assert(create._itemManager.entities.has(result.objectsUpdated[0].id));
|
|
125
127
|
|
|
126
128
|
await asyncTimeout(
|
|
127
|
-
check.
|
|
129
|
+
check.itemUpdate.waitForCondition(() => check._itemManager.entities.has(objectId)),
|
|
128
130
|
1000
|
|
129
131
|
);
|
|
130
132
|
|
|
@@ -138,3 +140,41 @@ export const syncItems = async (db1: DatabaseBackendProxy, db2: DatabaseBackendP
|
|
|
138
140
|
// Check item replicated from 2 => 1.
|
|
139
141
|
await testSpace(db2, db1);
|
|
140
142
|
};
|
|
143
|
+
|
|
144
|
+
export const joinCommonSpace = async ([initialPeer, ...peers]: Client[], spaceKey?: PublicKey): Promise<PublicKey> => {
|
|
145
|
+
const rootSpace = spaceKey ? initialPeer.echo.getSpace(spaceKey) : await initialPeer.echo.createSpace();
|
|
146
|
+
assert(rootSpace, 'Space not found.');
|
|
147
|
+
|
|
148
|
+
await Promise.all(
|
|
149
|
+
peers.map(async (peer) => {
|
|
150
|
+
const hostDone = new Trigger<Invitation>();
|
|
151
|
+
const guestDone = new Trigger<Invitation>();
|
|
152
|
+
|
|
153
|
+
const hostObservabli = rootSpace.createInvitation({ type: Invitation.Type.INTERACTIVE_TESTING });
|
|
154
|
+
log('invitation created');
|
|
155
|
+
hostObservabli.subscribe({
|
|
156
|
+
onConnecting: (invitation) => {
|
|
157
|
+
const guestObservable = peer.echo.acceptInvitation(invitation);
|
|
158
|
+
log('invitation accepted');
|
|
159
|
+
|
|
160
|
+
guestObservable.subscribe({
|
|
161
|
+
onSuccess: (invitation: Invitation) => {
|
|
162
|
+
guestDone.wake(invitation);
|
|
163
|
+
log('invitation guestDone');
|
|
164
|
+
},
|
|
165
|
+
onError: (err: Error) => raise(err)
|
|
166
|
+
});
|
|
167
|
+
},
|
|
168
|
+
onSuccess: (invitation) => {
|
|
169
|
+
hostDone.wake(invitation);
|
|
170
|
+
log('invitation hostDone');
|
|
171
|
+
},
|
|
172
|
+
onError: (err) => raise(err)
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
await Promise.all([hostDone.wait(), guestDone.wait()]);
|
|
176
|
+
})
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
return rootSpace.key;
|
|
180
|
+
};
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
// Copyright 2021 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { expect } from 'chai';
|
|
6
|
+
|
|
7
|
+
import { Trigger } from '@dxos/async';
|
|
8
|
+
import { Client, Invitation } from '@dxos/client';
|
|
9
|
+
import { raise } from '@dxos/debug';
|
|
10
|
+
import { log } from '@dxos/log';
|
|
6
11
|
import { describe, test, afterTest } from '@dxos/test';
|
|
7
12
|
|
|
8
13
|
import { TestBuilder, testSpace } from '../testing';
|
|
@@ -11,13 +16,48 @@ describe('Spaces/invitations', () => {
|
|
|
11
16
|
test('creates a space and invites a peer', async () => {
|
|
12
17
|
const testBuilder = new TestBuilder();
|
|
13
18
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
await
|
|
17
|
-
await
|
|
19
|
+
const client1 = new Client({ services: testBuilder.createLocal() });
|
|
20
|
+
const client2 = new Client({ services: testBuilder.createLocal() });
|
|
21
|
+
await client1.initialize();
|
|
22
|
+
await client2.initialize();
|
|
23
|
+
await client1.halo.createIdentity({ displayName: 'Peer 1' });
|
|
24
|
+
await client2.halo.createIdentity({ displayName: 'Peer 2' });
|
|
25
|
+
|
|
26
|
+
log('initialized');
|
|
27
|
+
|
|
28
|
+
afterTest(() => Promise.all([client1.destroy()]));
|
|
29
|
+
afterTest(() => Promise.all([client2.destroy()]));
|
|
30
|
+
|
|
31
|
+
const success1 = new Trigger<Invitation>();
|
|
32
|
+
const success2 = new Trigger<Invitation>();
|
|
33
|
+
|
|
34
|
+
const space1 = await client1.echo.createSpace();
|
|
35
|
+
log('createSpace', { key: space1.key });
|
|
36
|
+
const observable1 = space1.createInvitation({ type: Invitation.Type.INTERACTIVE_TESTING });
|
|
37
|
+
|
|
38
|
+
observable1.subscribe({
|
|
39
|
+
onConnecting: (invitation) => {
|
|
40
|
+
const observable2 = client2.echo.acceptInvitation(invitation);
|
|
41
|
+
observable2.subscribe({
|
|
42
|
+
onSuccess: (invitation: Invitation) => {
|
|
43
|
+
success2.wake(invitation);
|
|
44
|
+
},
|
|
45
|
+
onError: (err: Error) => raise(err)
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
onSuccess: (invitation) => {
|
|
49
|
+
log('onSuccess');
|
|
50
|
+
success1.wake(invitation);
|
|
51
|
+
},
|
|
52
|
+
onError: (err) => raise(err)
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const [invitation1, invitation2] = await Promise.all([success1.wait(), success2.wait()]);
|
|
56
|
+
expect(invitation1.spaceKey).to.deep.eq(invitation2.spaceKey);
|
|
57
|
+
expect(invitation1.state).to.eq(Invitation.State.SUCCESS);
|
|
18
58
|
|
|
19
59
|
{
|
|
20
|
-
const space =
|
|
60
|
+
const space = client2.echo.getSpace(invitation2.spaceKey!)!;
|
|
21
61
|
await testSpace(space.internal.db);
|
|
22
62
|
}
|
|
23
63
|
});
|