@kubun/plugin-p2p 0.8.0
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/LICENSE.md +57 -0
- package/lib/context/join.d.ts +4 -0
- package/lib/context/join.js +1 -0
- package/lib/context/space.d.ts +4 -0
- package/lib/context/space.js +1 -0
- package/lib/context/sync.d.ts +3 -0
- package/lib/context/sync.js +1 -0
- package/lib/context/types.d.ts +35 -0
- package/lib/context/types.js +1 -0
- package/lib/index.d.ts +25 -0
- package/lib/index.js +1 -0
- package/lib/migrations.d.ts +8 -0
- package/lib/migrations.js +1 -0
- package/lib/protocol.d.ts +175 -0
- package/lib/protocol.js +1 -0
- package/lib/schema.d.ts +3 -0
- package/lib/schema.js +187 -0
- package/lib/spaces/broadcast-codec.d.ts +3 -0
- package/lib/spaces/broadcast-codec.js +1 -0
- package/lib/spaces/broadcast-service.d.ts +59 -0
- package/lib/spaces/broadcast-service.js +1 -0
- package/lib/spaces/broadcast.d.ts +65 -0
- package/lib/spaces/broadcast.js +1 -0
- package/lib/spaces/events.d.ts +38 -0
- package/lib/spaces/events.js +1 -0
- package/lib/spaces/group-handle.d.ts +3 -0
- package/lib/spaces/group-handle.js +1 -0
- package/lib/spaces/invite-payload.d.ts +24 -0
- package/lib/spaces/invite-payload.js +1 -0
- package/lib/spaces/join-utils.d.ts +22 -0
- package/lib/spaces/join-utils.js +1 -0
- package/lib/spaces/manager.d.ts +147 -0
- package/lib/spaces/manager.js +1 -0
- package/lib/spaces/mls-json.d.ts +2 -0
- package/lib/spaces/mls-json.js +1 -0
- package/lib/spaces/mls-state.d.ts +27 -0
- package/lib/spaces/mls-state.js +1 -0
- package/lib/sync/catalog-scope.d.ts +17 -0
- package/lib/sync/catalog-scope.js +1 -0
- package/lib/sync/handlers.d.ts +19 -0
- package/lib/sync/handlers.js +1 -0
- package/lib/sync/merkle-apply.d.ts +12 -0
- package/lib/sync/merkle-apply.js +1 -0
- package/lib/sync/merkle-tree.d.ts +13 -0
- package/lib/sync/merkle-tree.js +1 -0
- package/lib/sync/peer-registry.d.ts +31 -0
- package/lib/sync/peer-registry.js +1 -0
- package/lib/sync/sync-client.d.ts +68 -0
- package/lib/sync/sync-client.js +1 -0
- package/lib/sync/sync-manager.d.ts +61 -0
- package/lib/sync/sync-manager.js +1 -0
- package/lib/types.d.ts +148 -0
- package/lib/types.js +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Client } from '@enkaku/client';
|
|
2
|
+
import type { ClientTransportOf } from '@enkaku/protocol';
|
|
3
|
+
import type { Runtime } from '@enkaku/runtime';
|
|
4
|
+
import type { SigningIdentity } from '@enkaku/token';
|
|
5
|
+
import type { Logger } from '@kubun/logger';
|
|
6
|
+
import type { SyncProtocol } from '../protocol.js';
|
|
7
|
+
/**
|
|
8
|
+
* Provider for sync-specific transport to a peer's sync server.
|
|
9
|
+
* The p2p plugin exposes this via `createSyncTransport()`.
|
|
10
|
+
*/
|
|
11
|
+
export type SyncTransportProvider = {
|
|
12
|
+
createSyncTransport: (signal?: AbortSignal) => ClientTransportOf<SyncProtocol>;
|
|
13
|
+
};
|
|
14
|
+
export type SyncClientParams = {
|
|
15
|
+
runtime: Runtime;
|
|
16
|
+
identity: SigningIdentity;
|
|
17
|
+
logger: Logger;
|
|
18
|
+
serverResolver?: (serverID: string) => SyncTransportProvider | undefined;
|
|
19
|
+
};
|
|
20
|
+
export type SyncScope = {
|
|
21
|
+
modelID: string;
|
|
22
|
+
ownerDID: string;
|
|
23
|
+
};
|
|
24
|
+
export type MerkleSyncMessage = {
|
|
25
|
+
type: 'mutations';
|
|
26
|
+
mutationJWTs: Array<string>;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'complete';
|
|
29
|
+
divergentBuckets?: number;
|
|
30
|
+
totalMutations?: number;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Client for connecting to peer servers for sync operations.
|
|
34
|
+
* Supports both direct (in-process) and HTTP transports.
|
|
35
|
+
*
|
|
36
|
+
* Uses a raw Enkaku `Client<SyncProtocol>` for sync connections rather than
|
|
37
|
+
* `KubunClient`, since only sync procedures (negotiate, merkle-sync) are needed.
|
|
38
|
+
*/
|
|
39
|
+
export declare class SyncClient {
|
|
40
|
+
#private;
|
|
41
|
+
constructor(params: SyncClientParams);
|
|
42
|
+
/**
|
|
43
|
+
* Connect to a peer server using the specified endpoint.
|
|
44
|
+
* - `direct://server-id` - Use in-process direct transport via sync server
|
|
45
|
+
* - `http://...` or `https://...` - Use HTTP transport
|
|
46
|
+
*/
|
|
47
|
+
connect(endpoint: string, serverID?: string): Promise<Client<SyncProtocol>>;
|
|
48
|
+
/**
|
|
49
|
+
* Negotiate sync scopes with peer.
|
|
50
|
+
*/
|
|
51
|
+
negotiate(client: Client<SyncProtocol>, scopes: Array<SyncScope>, delegationTokens?: Array<string>, knownModelIDs?: Array<string>): Promise<{
|
|
52
|
+
acceptedScopes: Array<SyncScope>;
|
|
53
|
+
excludedDocumentIDs: Array<string>;
|
|
54
|
+
missingClusters?: Record<string, unknown>;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Perform Merkle tree-based sync with peer.
|
|
58
|
+
* Sends local tree, receives divergent mutation JWTs.
|
|
59
|
+
*/
|
|
60
|
+
merkleSync(client: Client<SyncProtocol>, params: {
|
|
61
|
+
scopes: Array<SyncScope>;
|
|
62
|
+
excludedDocumentIDs: Array<string>;
|
|
63
|
+
tree: Record<string, string>;
|
|
64
|
+
}): Promise<{
|
|
65
|
+
mutationJWTs: Array<string>;
|
|
66
|
+
divergentBuckets: number;
|
|
67
|
+
}>;
|
|
68
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Client as e}from"@enkaku/client";import{ClientTransport as t}from"@enkaku/http-client-transport";import{createArraySink as r}from"@enkaku/stream";export class SyncClient{#e;#t;#r;#n;constructor(e){this.#e=e.runtime,this.#t=e.identity,this.#r=e.logger,this.#n=e.serverResolver}async connect(e,t){if(e.startsWith("direct://"))return this.#s(e);if(e.startsWith("http://")||e.startsWith("https://"))return this.#i(e,t);throw Error(`Unsupported endpoint scheme: ${e}`)}#i(r,n){let s=new t({url:r,fetch:this.#e.fetch});return new e({runtime:this.#e,identity:this.#t,logger:this.#r.getChild("sync-client"),serverID:n,transport:s})}#s(t){let r=t.replace("direct://","");if(!this.#n)throw Error("Server resolver not configured for direct transport");let n=this.#n(r);if(!n)throw Error(`Server not found: ${r}`);let s=n.createSyncTransport();return new e({runtime:this.#e,identity:this.#t,logger:this.#r.getChild("sync-client"),serverID:r,transport:s})}async negotiate(e,t,r=[],n){this.#r.debug("Negotiate: sending {scopeCount} scopes",{scopeCount:t.length});let s=await e.request("sync/negotiate",{param:{scopes:t,delegationTokens:r,knownModelIDs:n}});return this.#r.debug("Negotiate: accepted {acceptedCount} scopes, excluded {excludedCount} docs",{acceptedCount:s.acceptedScopes.length,excludedCount:s.excludedDocumentIDs.length}),s}async merkleSync(e,t){this.#r.debug("MerkleSync: creating stream with {buckets} local buckets",{buckets:Object.keys(t.tree).length});let[n,s]=r(),i=e.createStream("sync/merkle-sync",{param:{scopes:t.scopes,excludedDocumentIDs:t.excludedDocumentIDs,tree:t.tree}}),o=i.readable.pipeTo(n);this.#r.debug("MerkleSync: awaiting stream completion"),await Promise.all([i,o]),this.#r.debug("MerkleSync: stream completed, collecting messages");let c=await s,l=[],a=0;for(let e of c)"mutations"===e.type?l.push(...e.mutationJWTs):"complete"===e.type&&(a=e.divergentBuckets??0);return{mutationJWTs:l,divergentBuckets:a}}}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Runtime } from '@enkaku/runtime';
|
|
2
|
+
import { type Identity, type SigningIdentity } from '@enkaku/token';
|
|
3
|
+
import type { KubunDB } from '@kubun/db';
|
|
4
|
+
import type { Logger } from '@kubun/logger';
|
|
5
|
+
import { type PeerConfig, type PeerConfigWithID } from './peer-registry.js';
|
|
6
|
+
import { type SyncScope, type SyncTransportProvider } from './sync-client.js';
|
|
7
|
+
export type SyncSessionInfo = {
|
|
8
|
+
peerID: string;
|
|
9
|
+
startTime: number;
|
|
10
|
+
documentsAttempted: number;
|
|
11
|
+
documentsCompleted: number;
|
|
12
|
+
};
|
|
13
|
+
export type SyncStatus = {
|
|
14
|
+
activeSessions: Array<SyncSessionInfo>;
|
|
15
|
+
lastSyncByPeer: Record<string, number>;
|
|
16
|
+
};
|
|
17
|
+
export type SyncEvent = {
|
|
18
|
+
type: 'started' | 'completed' | 'error' | 'document:complete' | 'document:failed' | 'document:skipped';
|
|
19
|
+
peerID: string;
|
|
20
|
+
documentID?: string;
|
|
21
|
+
timestamp: number;
|
|
22
|
+
error?: string;
|
|
23
|
+
reason?: string;
|
|
24
|
+
};
|
|
25
|
+
export type SyncManagerParams = {
|
|
26
|
+
db: KubunDB;
|
|
27
|
+
deployClusters?: (clusters: Record<string, unknown>) => Promise<void>;
|
|
28
|
+
runtime: Runtime;
|
|
29
|
+
identity: Identity;
|
|
30
|
+
logger: Logger;
|
|
31
|
+
serverResolver?: (serverID: string) => SyncTransportProvider | undefined;
|
|
32
|
+
};
|
|
33
|
+
export type MerkleSyncOptions = {
|
|
34
|
+
knownModelIDs?: Array<string>;
|
|
35
|
+
};
|
|
36
|
+
export declare class SyncManager {
|
|
37
|
+
#private;
|
|
38
|
+
constructor(params: SyncManagerParams);
|
|
39
|
+
/**
|
|
40
|
+
* Configure the signing identity used for sync operations.
|
|
41
|
+
*/
|
|
42
|
+
setIdentity(identity: SigningIdentity): void;
|
|
43
|
+
/**
|
|
44
|
+
* Configure the server resolver for direct transport connections.
|
|
45
|
+
*/
|
|
46
|
+
setServerResolver(resolver: (serverID: string) => SyncTransportProvider | undefined): void;
|
|
47
|
+
addPeer(config: PeerConfig): Promise<void>;
|
|
48
|
+
removePeer(peerDID: string): Promise<void>;
|
|
49
|
+
updatePeerConfig(peerDID: string, updates: Partial<PeerConfig>): Promise<void>;
|
|
50
|
+
listPeers(): Promise<Array<PeerConfigWithID>>;
|
|
51
|
+
getPeer(peerDID: string): Promise<PeerConfigWithID | undefined>;
|
|
52
|
+
merkleSyncWithPeer(peerDID: string, scopes: Array<SyncScope>, delegationTokens?: Array<string>, options?: MerkleSyncOptions): Promise<{
|
|
53
|
+
sessionID: string;
|
|
54
|
+
divergentBuckets: number;
|
|
55
|
+
messagesReceived: number;
|
|
56
|
+
missingClusters?: Record<string, unknown>;
|
|
57
|
+
}>;
|
|
58
|
+
getStatus(peerDID?: string): SyncStatus;
|
|
59
|
+
onSyncEvent(callback: (event: SyncEvent) => void): () => void;
|
|
60
|
+
dispose(): Promise<void>;
|
|
61
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{EventEmitter as e}from"@enkaku/event";import{isSigningIdentity as t}from"@enkaku/token";import{applySyncMutations as s}from"./merkle-apply.js";import{buildMerkleTree as r}from"./merkle-tree.js";import{PeerRegistry as i}from"./peer-registry.js";import{SyncClient as n}from"./sync-client.js";export class SyncManager{#e;#t;#s;#r;#i;#n=new e;#o=new Map;#l=new Map;#a;#c;constructor(e){this.#e=e.db,this.#t=e.deployClusters,this.#s=e.runtime,this.#a=e.identity,this.#r=e.logger,this.#i=new i({db:e.db,runtime:e.runtime}),this.#c=e.serverResolver}setIdentity(e){this.#a=e}setServerResolver(e){this.#c=e}async addPeer(e){await this.#i.addPeer(e),this.#r.info("Peer added",{peerDID:e.peerDID})}async removePeer(e){await this.#i.removePeer(e),this.#r.info("Peer removed",{peerDID:e})}async updatePeerConfig(e,t){await this.#i.updatePeer(e,t),this.#r.info("Peer updated",{peerDID:e})}async listPeers(){return this.#i.listPeers()}async getPeer(e){return this.#i.getPeer(e)}async merkleSyncWithPeer(e,i,o=[],l){let a;this.#r.info("Starting Merkle sync with peer",{peerDID:e,scopes:i});let c=await this.#i.getPeer(e);if(!c)throw Error(`Peer ${e} not found`);let g=`merkle-sync-${e}-${Date.now()}`,m={peerID:e,startTime:Date.now(),documentsAttempted:0,documentsCompleted:0};this.#o.set(g,m),this.#g({type:"started",peerID:e,timestamp:Date.now()});try{let p=this.#a;if(!t(p))throw Error("Signing identity required for Merkle sync");let d=new n({runtime:this.#s,identity:p,logger:this.#r,serverResolver:this.#c});a=await d.connect(c.endpoint,e),this.#r.info("Negotiating sync scopes",{scopes:i});let{acceptedScopes:y,excludedDocumentIDs:h,missingClusters:u}=await d.negotiate(a,i,o,l?.knownModelIDs);if(0===y.length)return this.#r.info("No scopes accepted by peer"),this.#l.set(e,Date.now()),this.#g({type:"completed",peerID:e,timestamp:Date.now()}),this.#o.delete(g),{sessionID:g,divergentBuckets:0,messagesReceived:0,missingClusters:u};null!=u&&Object.keys(u).length>0&&(null!=this.#t?(this.#r.info("Deploying missing clusters from peer",{clusterCount:Object.keys(u).length}),await this.#t(u)):this.#r.warn("Missing clusters received but no deployClusters callback configured",{clusterCount:Object.keys(u).length})),this.#r.info("Building local Merkle tree",{acceptedScopes:y});let v=await this.#e.getDocumentIDsForScope(y,h),f=await this.#e.getMutationLogForDocuments(v),w=r(f);this.#r.info("Requesting Merkle sync from peer",{localTreeBuckets:Object.keys(w.buckets).length});let k=await d.merkleSync(a,{scopes:y,excludedDocumentIDs:h,tree:w.buckets});return k.mutationJWTs.length>0&&(this.#r.info("Applying sync mutations",{mutations:k.mutationJWTs.length}),m.documentsCompleted=(await s({db:this.#e,mutationJWTs:k.mutationJWTs})).applied),this.#l.set(e,Date.now()),this.#g({type:"completed",peerID:e,timestamp:Date.now()}),this.#r.info("Merkle sync completed",{divergentBuckets:k.divergentBuckets,mutationsReceived:k.mutationJWTs.length}),{sessionID:g,divergentBuckets:k.divergentBuckets,messagesReceived:k.mutationJWTs.length,missingClusters:u}}catch(t){throw this.#r.error("Merkle sync failed",{peerDID:e,error:t}),this.#g({type:"error",peerID:e,timestamp:Date.now(),error:t instanceof Error?t.message:String(t)}),t}finally{if(null!=a)try{a.abort("SyncComplete"),await a.dispose()}catch{}this.#o.delete(g)}}getStatus(e){let t=Array.from(this.#o.values()).filter(t=>!e||t.peerID===e).map(e=>({peerID:e.peerID,startTime:e.startTime,documentsAttempted:e.documentsAttempted,documentsCompleted:e.documentsCompleted})),s={};for(let[t,r]of this.#l.entries())e&&t!==e||(s[t]=r);return{activeSessions:t,lastSyncByPeer:s}}onSyncEvent(e){return this.#n.on("sync",e)}#g(e){this.#n.emit("sync",e).catch(e=>{this.#r.error("Error in sync event listener",{error:e})})}async dispose(){this.#o.clear(),this.#l.clear()}}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import type { ClientTransportOf } from '@enkaku/protocol';
|
|
2
|
+
import type { SyncProtocol } from './protocol.js';
|
|
3
|
+
import type { PeerConfig, PeerConfigWithID } from './sync/peer-registry.js';
|
|
4
|
+
import type { SyncScope } from './sync/sync-client.js';
|
|
5
|
+
import type { SyncEvent, SyncStatus } from './sync/sync-manager.js';
|
|
6
|
+
export type SpaceData = {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
createdBy: string;
|
|
11
|
+
createdAt: string;
|
|
12
|
+
};
|
|
13
|
+
export type SpaceMemberData = {
|
|
14
|
+
spaceID: string;
|
|
15
|
+
memberDID: string;
|
|
16
|
+
role: string;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
};
|
|
19
|
+
export type CircleData = {
|
|
20
|
+
id: string;
|
|
21
|
+
spaceID: string;
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
createdAt: string;
|
|
25
|
+
};
|
|
26
|
+
export type CircleMemberData = {
|
|
27
|
+
circleID: string;
|
|
28
|
+
memberDID: string;
|
|
29
|
+
role: string;
|
|
30
|
+
createdAt: string;
|
|
31
|
+
};
|
|
32
|
+
export type CatalogData = {
|
|
33
|
+
id: string;
|
|
34
|
+
ownerDID: string;
|
|
35
|
+
name: string;
|
|
36
|
+
description: string;
|
|
37
|
+
filterCriteria: string;
|
|
38
|
+
createdAt: string;
|
|
39
|
+
};
|
|
40
|
+
export type InviteToSpaceData = {
|
|
41
|
+
invitePayload: string;
|
|
42
|
+
spaceID: string;
|
|
43
|
+
spaceName: string;
|
|
44
|
+
};
|
|
45
|
+
export type JoinSpaceData = {
|
|
46
|
+
space: SpaceData | null;
|
|
47
|
+
};
|
|
48
|
+
export type LeaveSpaceData = {
|
|
49
|
+
spaceID: string;
|
|
50
|
+
};
|
|
51
|
+
export type RemoveSpaceMemberData = {
|
|
52
|
+
spaceID: string;
|
|
53
|
+
};
|
|
54
|
+
export type DeleteCatalogData = {
|
|
55
|
+
deletedID: string;
|
|
56
|
+
};
|
|
57
|
+
export type DeleteCircleData = {
|
|
58
|
+
deletedID: string;
|
|
59
|
+
};
|
|
60
|
+
export type RemoveCircleMemberData = {
|
|
61
|
+
circleID: string;
|
|
62
|
+
memberDID: string;
|
|
63
|
+
};
|
|
64
|
+
export type UpdateSpaceInput = {
|
|
65
|
+
spaceID: string;
|
|
66
|
+
name?: string;
|
|
67
|
+
description?: string;
|
|
68
|
+
};
|
|
69
|
+
export type UpdateCircleInput = {
|
|
70
|
+
circleID: string;
|
|
71
|
+
name?: string;
|
|
72
|
+
description?: string;
|
|
73
|
+
catalogIDs?: Array<string>;
|
|
74
|
+
};
|
|
75
|
+
export type SpaceRequestContext = {
|
|
76
|
+
spaceCreateSpace: (input: {
|
|
77
|
+
name: string;
|
|
78
|
+
description?: string;
|
|
79
|
+
}) => Promise<SpaceData>;
|
|
80
|
+
spaceGetSpaces: () => Promise<Array<SpaceData>>;
|
|
81
|
+
spaceGetSpace: (id: string) => Promise<SpaceData | null>;
|
|
82
|
+
spaceAddSpaceMember: (spaceID: string, memberDID: string, role: string) => Promise<SpaceMemberData>;
|
|
83
|
+
spaceGetSpaceMembers: (spaceID: string) => Promise<Array<SpaceMemberData>>;
|
|
84
|
+
spaceCreateCircle: (params: {
|
|
85
|
+
spaceID: string;
|
|
86
|
+
name: string;
|
|
87
|
+
description?: string;
|
|
88
|
+
}) => Promise<CircleData>;
|
|
89
|
+
spaceGetCircles: (spaceID: string) => Promise<Array<CircleData>>;
|
|
90
|
+
spaceAddCircleMember: (circleID: string, memberDID: string, role: string) => Promise<CircleMemberData>;
|
|
91
|
+
spaceCreateCatalog: (params: {
|
|
92
|
+
name: string;
|
|
93
|
+
description?: string;
|
|
94
|
+
filterCriteria: string;
|
|
95
|
+
}) => Promise<CatalogData>;
|
|
96
|
+
spaceGetCatalogs: (ownerDID?: string) => Promise<Array<CatalogData>>;
|
|
97
|
+
spaceInviteToSpace: (spaceID: string, joinRequest: string) => Promise<InviteToSpaceData>;
|
|
98
|
+
spaceJoinSpace: (invitePayload: string, joinRequestPayload: string) => Promise<JoinSpaceData>;
|
|
99
|
+
spaceLeaveSpace: (spaceID: string) => Promise<LeaveSpaceData>;
|
|
100
|
+
spaceRemoveSpaceMember: (spaceID: string, memberDID: string) => Promise<RemoveSpaceMemberData>;
|
|
101
|
+
spaceUpdateSpace: (input: UpdateSpaceInput) => Promise<SpaceData>;
|
|
102
|
+
spaceUpdateCircle: (input: UpdateCircleInput) => Promise<CircleData>;
|
|
103
|
+
spaceUpdateCatalog: (params: {
|
|
104
|
+
catalogID: string;
|
|
105
|
+
name?: string;
|
|
106
|
+
filterCriteria?: string;
|
|
107
|
+
}) => Promise<CatalogData>;
|
|
108
|
+
spaceDeleteCatalog: (catalogID: string) => Promise<DeleteCatalogData>;
|
|
109
|
+
spaceDeleteCircle: (circleID: string) => Promise<DeleteCircleData>;
|
|
110
|
+
spaceRemoveCircleMember: (circleID: string, memberDID: string) => Promise<RemoveCircleMemberData>;
|
|
111
|
+
};
|
|
112
|
+
export type SyncRequestContext = {
|
|
113
|
+
syncAddPeer: (config: PeerConfig) => Promise<void>;
|
|
114
|
+
syncRemovePeer: (peerDID: string) => Promise<void>;
|
|
115
|
+
syncListPeers: () => Promise<Array<PeerConfigWithID>>;
|
|
116
|
+
syncGetStatus: (peerDID?: string) => SyncStatus;
|
|
117
|
+
};
|
|
118
|
+
export type P2PJoinRequestContext = {
|
|
119
|
+
p2pPrepareJoinRequest: () => Promise<{
|
|
120
|
+
joinRequest: string;
|
|
121
|
+
}>;
|
|
122
|
+
p2pCompleteJoin: (invitePayload: string) => Promise<{
|
|
123
|
+
space: SpaceData | null;
|
|
124
|
+
}>;
|
|
125
|
+
};
|
|
126
|
+
export type SyncSessionResult = {
|
|
127
|
+
sessionID: string;
|
|
128
|
+
divergentBuckets: number;
|
|
129
|
+
messagesReceived: number;
|
|
130
|
+
missingClusters?: Record<string, unknown>;
|
|
131
|
+
};
|
|
132
|
+
export type SyncPluginAPI = {
|
|
133
|
+
/** Resolves when the HTTP sync transport is registered (only present when http option is enabled). */
|
|
134
|
+
syncReady?: Promise<void>;
|
|
135
|
+
addPeer(config: PeerConfig): Promise<void>;
|
|
136
|
+
removePeer(peerDID: string): Promise<void>;
|
|
137
|
+
listPeers(): Promise<Array<PeerConfigWithID>>;
|
|
138
|
+
syncWithPeer(params: {
|
|
139
|
+
peerDID: string;
|
|
140
|
+
scopes: Array<SyncScope>;
|
|
141
|
+
delegationTokens?: Array<string>;
|
|
142
|
+
knownModelIDs?: Array<string>;
|
|
143
|
+
}): Promise<SyncSessionResult>;
|
|
144
|
+
getStatus(peerDID?: string): SyncStatus;
|
|
145
|
+
onSyncEvent(callback: (event: SyncEvent) => void): () => void;
|
|
146
|
+
/** Create a sync-specific transport for direct in-process connections. */
|
|
147
|
+
createSyncTransport(signal?: AbortSignal): ClientTransportOf<SyncProtocol>;
|
|
148
|
+
};
|
package/lib/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{};
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kubun/plugin-p2p",
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"license": "see LICENSE.md",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./lib/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"lib/*",
|
|
13
|
+
"LICENSE.md"
|
|
14
|
+
],
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@enkaku/async": "^0.14.0",
|
|
18
|
+
"@enkaku/capability": "^0.14.0",
|
|
19
|
+
"@enkaku/client": "^0.14.3",
|
|
20
|
+
"@enkaku/codec": "^0.14.0",
|
|
21
|
+
"@enkaku/event": "^0.14.1",
|
|
22
|
+
"@enkaku/generator": "^0.14.0",
|
|
23
|
+
"@enkaku/group": "^0.14.6",
|
|
24
|
+
"@enkaku/http-client-transport": "^0.14.3",
|
|
25
|
+
"@enkaku/http-server-transport": "^0.14.2",
|
|
26
|
+
"@enkaku/protocol": "^0.14.0",
|
|
27
|
+
"@enkaku/runtime": "^0.14.0",
|
|
28
|
+
"@enkaku/schema": "^0.14.0",
|
|
29
|
+
"@enkaku/server": "^0.14.3",
|
|
30
|
+
"@enkaku/stream": "^0.14.1",
|
|
31
|
+
"@enkaku/token": "0.14.1",
|
|
32
|
+
"@enkaku/transport": "0.14.0",
|
|
33
|
+
"@noble/hashes": "^2.2.0",
|
|
34
|
+
"graphql": "^16.13.2",
|
|
35
|
+
"kysely": "^0.28.16",
|
|
36
|
+
"@kubun/client": "^0.8.0",
|
|
37
|
+
"@kubun/graphql": "^0.8.0",
|
|
38
|
+
"@kubun/hlc": "^0.8.0",
|
|
39
|
+
"@kubun/db-adapter": "^0.8.0",
|
|
40
|
+
"@kubun/db": "^0.8.0",
|
|
41
|
+
"@kubun/engine": "^0.8.0",
|
|
42
|
+
"@kubun/logger": "^0.8.0",
|
|
43
|
+
"@kubun/id": "^0.8.0",
|
|
44
|
+
"@kubun/mutation": "^0.8.0",
|
|
45
|
+
"@kubun/protocol": "^0.8.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"get-port": "^7.2.0",
|
|
49
|
+
"@kubun/db-better-sqlite": "^0.8.0",
|
|
50
|
+
"@kubun/plugin-connector": "^0.8.0",
|
|
51
|
+
"@kubun/plugin-http": "^0.8.0",
|
|
52
|
+
"@kubun/plugin-rpc": "^0.8.0",
|
|
53
|
+
"@kubun/test-utils": "^0.8.0"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build:clean": "del lib",
|
|
57
|
+
"build:js": "swc src -d ./lib --config-file ../../swc.json --strip-leading-paths",
|
|
58
|
+
"build:types": "tsc --emitDeclarationOnly --skipLibCheck",
|
|
59
|
+
"build": "pnpm run build:clean && pnpm run build:js && pnpm run build:types",
|
|
60
|
+
"test:types": "tsc --noEmit -p tsconfig.test.json",
|
|
61
|
+
"test:unit": "vitest run",
|
|
62
|
+
"test": "pnpm run test:types && pnpm run test:unit"
|
|
63
|
+
}
|
|
64
|
+
}
|