@ibgib/core-gib 0.1.23 → 0.1.26
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/common/other/graph-helper.d.mts +17 -0
- package/dist/common/other/graph-helper.d.mts.map +1 -1
- package/dist/common/other/graph-helper.mjs +44 -0
- package/dist/common/other/graph-helper.mjs.map +1 -1
- package/dist/common/other/ibgib-helper.d.mts +1 -1
- package/dist/common/other/ibgib-helper.d.mts.map +1 -1
- package/dist/common/other/ibgib-helper.mjs.map +1 -1
- package/dist/sync/graft-info/graft-info-helpers.mjs +2 -2
- package/dist/sync/graft-info/graft-info-helpers.mjs.map +1 -1
- package/dist/sync/sync-conflict.respec.mjs +10 -15
- package/dist/sync/sync-conflict.respec.mjs.map +1 -1
- package/dist/sync/sync-constants.d.mts +1 -0
- package/dist/sync/sync-constants.d.mts.map +1 -1
- package/dist/sync/sync-constants.mjs +1 -0
- package/dist/sync/sync-constants.mjs.map +1 -1
- package/dist/sync/sync-helpers.d.mts +5 -0
- package/dist/sync/sync-helpers.d.mts.map +1 -1
- package/dist/sync/sync-helpers.mjs +37 -1
- package/dist/sync/sync-helpers.mjs.map +1 -1
- package/dist/sync/sync-innerspace-constants.respec.mjs +10 -12
- package/dist/sync/sync-innerspace-constants.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs +10 -12
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs +10 -12
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs +9 -12
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-partial-update.respec.mjs +9 -14
- package/dist/sync/sync-innerspace-partial-update.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace.respec.mjs +9 -12
- package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.d.mts +2 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs +4 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts +24 -13
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +176 -76
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-types.d.mts +29 -6
- package/dist/sync/sync-peer/sync-peer-types.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.d.mts +38 -55
- package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.mjs +111 -244
- package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +32 -1
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +96 -7
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
- package/dist/sync/sync-saga-coordinator.d.mts +59 -13
- package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.mjs +446 -304
- package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
- package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts +51 -6
- package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts.map +1 -1
- package/dist/sync/sync-types.d.mts +35 -10
- package/dist/sync/sync-types.d.mts.map +1 -1
- package/dist/sync/sync-types.mjs +1 -2
- package/dist/sync/sync-types.mjs.map +1 -1
- package/package.json +1 -1
- package/src/common/other/graph-helper.mts +53 -0
- package/src/common/other/ibgib-helper.mts +1 -1
- package/src/sync/graft-info/graft-info-helpers.mts +3 -3
- package/src/sync/sync-conflict.respec.mts +10 -17
- package/src/sync/sync-constants.mts +1 -0
- package/src/sync/sync-helpers.mts +47 -7
- package/src/sync/sync-innerspace-constants.respec.mts +10 -12
- package/src/sync/sync-innerspace-deep-updates.respec.mts +10 -12
- package/src/sync/sync-innerspace-dest-ahead.respec.mts +10 -12
- package/src/sync/sync-innerspace-multiple-timelines.respec.mts +9 -12
- package/src/sync/sync-innerspace-partial-update.respec.mts +9 -14
- package/src/sync/sync-innerspace.respec.mts +9 -12
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mts +7 -0
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +200 -75
- package/src/sync/sync-peer/sync-peer-types.mts +35 -11
- package/src/sync/sync-peer/sync-peer-v1.mts +154 -257
- package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +90 -13
- package/src/sync/sync-saga-coordinator.mts +536 -356
- package/src/sync/sync-saga-message/sync-saga-message-types.mts +56 -4
- package/src/sync/sync-types.mts +46 -13
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @module SyncPeer_V1 witness class
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* NOTE: All push/pulls in this were done to get to compile. These should mostly
|
|
6
|
-
* not be single push/pull calls but should be batched with multiple addresses
|
|
7
|
-
* NOTE: All push/pulls in this were done to get to compile. These should mostly
|
|
8
|
-
* not be single push/pull calls but should be batched with multiple addresses
|
|
9
|
-
* NOTE: All push/pulls in this were done to get to compile. These should mostly
|
|
10
|
-
* not be single push/pull calls but should be batched with multiple addresses
|
|
11
|
-
* NOTE: All push/pulls in this were done to get to compile. These should mostly
|
|
12
|
-
* not be single push/pull calls but should be batched with multiple addresses
|
|
13
|
-
* NOTE: All push/pulls in this were done to get to compile. These should mostly
|
|
14
|
-
* not be single push/pull calls but should be batched with multiple addresses
|
|
2
|
+
* @module SyncPeer_V1 witness class for base class plumbing of sync peers.
|
|
3
|
+
*
|
|
4
|
+
* You are expected to implement concrete peer classes for concrete architecture.
|
|
15
5
|
*/
|
|
16
6
|
|
|
17
7
|
import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
@@ -24,11 +14,11 @@ import { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';
|
|
|
24
14
|
import { SYNC_MSG_REL8N_NAME, SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN } from '../sync-constants.mjs';
|
|
25
15
|
import { SubjectWitness } from '../../common/pubsub/subject/subject-types.mjs';
|
|
26
16
|
import { SyncSagaContextIbGib_V1 } from '../sync-saga-context/sync-saga-context-types.mjs';
|
|
27
|
-
import { SyncPeerData_V1, SyncPeerRel8ns_V1, SyncPeerWitness } from './sync-peer-types.mjs';
|
|
17
|
+
import { InitializeSyncPeerOpts, SyncPeerData_V1, SyncPeerRel8ns_V1, SyncPeerWitness } from './sync-peer-types.mjs';
|
|
28
18
|
import { LightWitnessBase_V1 } from '../../witness/light-witness-base-v1.mjs';
|
|
29
19
|
import { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';
|
|
30
20
|
import { newupSubject } from '../../common/pubsub/subject/subject-helper.mjs';
|
|
31
|
-
import {
|
|
21
|
+
import { authenticateContext, authorizeContext, validateContextAndSagaFrame } from '../sync-saga-context/sync-saga-context-helpers.mjs';
|
|
32
22
|
import { getFromSpace } from '../../witness/space/space-helper.mjs';
|
|
33
23
|
|
|
34
24
|
const logalot = GLOBAL_LOG_A_LOT || true;
|
|
@@ -37,21 +27,21 @@ const lcControlDomain = '[ControlDomain]';
|
|
|
37
27
|
|
|
38
28
|
/**
|
|
39
29
|
* Abstract witness for talking to a Sync Peer (e.g. Remote Node or Local Simulator).
|
|
40
|
-
*
|
|
30
|
+
*
|
|
41
31
|
* Takes a SyncSagaContext (Request) and returns a SyncSagaContext (Response).
|
|
42
|
-
*
|
|
32
|
+
*
|
|
43
33
|
* Implements the core "Sync Protocol Transport" logic:
|
|
44
34
|
* 1. Push Context & Dependencies (Sender -> Receiver)
|
|
45
35
|
* 2. Send Request (RPC)
|
|
46
36
|
* 3. Pull Response & Dependencies (Receiver -> Sender)
|
|
47
37
|
*/
|
|
48
|
-
export abstract class SyncPeer_V1 extends
|
|
49
|
-
|
|
38
|
+
export abstract class SyncPeer_V1<TInitializeOpts extends InitializeSyncPeerOpts = InitializeSyncPeerOpts>
|
|
39
|
+
extends LightWitnessBase_V1<SyncPeerData_V1, SyncPeerRel8ns_V1>
|
|
40
|
+
implements SyncPeerWitness<TInitializeOpts> {
|
|
50
41
|
|
|
51
42
|
protected lc: string = `[${SyncPeer_V1.name}]`;
|
|
52
43
|
|
|
53
|
-
public
|
|
54
|
-
public senderTempSpace: IbGibSpaceAny;
|
|
44
|
+
public opts: TInitializeOpts | undefined;
|
|
55
45
|
public payloadIbGibsDomainReceived$!: SubjectWitness<IbGib_V1>;
|
|
56
46
|
|
|
57
47
|
get classname(): string {
|
|
@@ -60,24 +50,79 @@ export abstract class SyncPeer_V1 extends LightWitnessBase_V1<SyncPeerData_V1, S
|
|
|
60
50
|
return this.data.classname;
|
|
61
51
|
}
|
|
62
52
|
|
|
63
|
-
constructor(
|
|
53
|
+
constructor(initialData: SyncPeerData_V1, initialRel8ns?: SyncPeerRel8ns_V1) {
|
|
64
54
|
super(initialData, initialRel8ns);
|
|
65
|
-
this.senderSpace = senderSpace;
|
|
66
|
-
this.senderTempSpace = senderTempSpace;
|
|
67
55
|
}
|
|
68
56
|
|
|
69
|
-
async initialize(): Promise<void> {
|
|
57
|
+
public async initialize(): Promise<void> {
|
|
70
58
|
this.payloadIbGibsDomainReceived$ = await newupSubject<IbGib_V1>();
|
|
71
59
|
}
|
|
72
60
|
|
|
61
|
+
/**
|
|
62
|
+
* base implementation just sets the opts property.
|
|
63
|
+
*
|
|
64
|
+
* override this in concrete classes for further initialization code
|
|
65
|
+
* specific to the sender.
|
|
66
|
+
*
|
|
67
|
+
* @see {@link SyncPeerWitness.opts}
|
|
68
|
+
*/
|
|
69
|
+
public async initializeSender(opts: TInitializeOpts): Promise<void> {
|
|
70
|
+
const lc = `${this.lc}[${this.initializeSender.name}]`;
|
|
71
|
+
try {
|
|
72
|
+
if (logalot) { console.log(`${lc} starting... (I: 31bd5fda37c89fa37fbaf14daf5fe726)`); }
|
|
73
|
+
this.opts = opts;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
76
|
+
throw error;
|
|
77
|
+
} finally {
|
|
78
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public setOptionalOpts(arg: Partial<TInitializeOpts>): void {
|
|
83
|
+
const lc = `${this.lc}[${this.setOptionalOpts.name}]`;
|
|
84
|
+
try {
|
|
85
|
+
if (logalot) { console.log(`${lc} starting... (I: ae5ddbd3577db267f84743175a736626)`); }
|
|
86
|
+
if (!this.opts) { throw new Error(`(UNEXPECTED) this.opts falsy? (E: 0dd4d6080a6e2f31d86cf4d86e11b826)`); }
|
|
87
|
+
|
|
88
|
+
if (logalot) { console.log(`${lc} updating opts. arg keys: ${Object.keys(arg)} (I: 452d78a558f8fc3468c8e2e68c70b226)`); }
|
|
89
|
+
|
|
90
|
+
this.opts = { ...this.opts, ...arg };
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
93
|
+
throw error;
|
|
94
|
+
} finally {
|
|
95
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// public setOptionalOpts({
|
|
100
|
+
// senderTempSpace,
|
|
101
|
+
// }: {
|
|
102
|
+
// senderTempSpace: IbGibSpaceAny,
|
|
103
|
+
// }): void {
|
|
104
|
+
// const lc = `${this.lc}[${this.setOptionalOpts.name}]`;
|
|
105
|
+
// try {
|
|
106
|
+
// if (logalot) { console.log(`${lc} starting... (I: a17188953e38f07b1884e498ac490b26)`); }
|
|
107
|
+
// if (!this.opts) { throw new Error(`(UNEXPECTED) this.opts falsy? (E: bdf00fe4b89b07ea78860d6ebe922e26)`); }
|
|
108
|
+
|
|
109
|
+
// this.opts.senderTempSpace = senderTempSpace;
|
|
110
|
+
// } catch (error) {
|
|
111
|
+
// console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
112
|
+
// throw error;
|
|
113
|
+
// } finally {
|
|
114
|
+
// if (logalot) { console.log(`${lc} complete.`); }
|
|
115
|
+
// }
|
|
116
|
+
// }
|
|
117
|
+
|
|
73
118
|
protected abstract ensureReceiverTempSpace(): Promise<IbGibSpaceAny>;
|
|
74
119
|
|
|
75
120
|
/**
|
|
76
121
|
* Witness the synchronization context (Send/Receive).
|
|
77
|
-
*
|
|
122
|
+
*
|
|
78
123
|
* At this point in code, we are sending the context OUTGOING. The {@link context} should
|
|
79
124
|
* have a fully populated {@link SyncSagaContextIbGib_V1.sagaFrame}
|
|
80
|
-
*
|
|
125
|
+
*
|
|
81
126
|
* @param arg The OUTGOING context (Request).
|
|
82
127
|
* @returns The INCOMING context (Response), or undefined if failed/empty.
|
|
83
128
|
*/
|
|
@@ -86,27 +131,34 @@ export abstract class SyncPeer_V1 extends LightWitnessBase_V1<SyncPeerData_V1, S
|
|
|
86
131
|
try {
|
|
87
132
|
if (logalot) { console.log(`${lc} starting...`); }
|
|
88
133
|
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
//
|
|
134
|
+
if (!this.opts) { throw new Error(`(UNEXPECTED) this.opts falsy? Concrete class should have initialized sender opts by now. (E: 0b9e28287318fdf8bf9f5a6886a24826)`); }
|
|
135
|
+
|
|
136
|
+
// NOTE: There are two basic types of peers:
|
|
137
|
+
// * local-only (peer)
|
|
138
|
+
// * this peer is both sender/receiver peer
|
|
139
|
+
// * for local merges and relatively fast spaces
|
|
140
|
+
// * proxy to remote space
|
|
141
|
+
// * this peer is both sender/receiver peer
|
|
142
|
+
// * works directly with remote/outerspaces
|
|
143
|
+
// * Less efficient over-the-wire xfer due to chatiness
|
|
144
|
+
// * symmetric node sender/receiver peers
|
|
145
|
+
// * separate sender/receiver classes
|
|
146
|
+
// * e.g., SyncPeerClient[Substrate]Sender_V1,
|
|
147
|
+
// SyncPeerClient[Substrate]Receiver_V1
|
|
148
|
+
// * More efficient over-the-wire xfer
|
|
149
|
+
// * Most difficult to mentally model
|
|
150
|
+
// * sender.witness does the pushing out
|
|
151
|
+
// * what the sender/initiator's coordinator has a reference to
|
|
152
|
+
// * receiver.witness does the coming in
|
|
153
|
+
// * lives on a server/remote instance with its own coordinator
|
|
154
|
+
// instance
|
|
155
|
+
// * must do its own validation/authn/authz for possible MITM
|
|
156
|
+
// issues
|
|
157
|
+
// The following is a sketch where some of these may be blurred
|
|
106
158
|
|
|
107
159
|
// persist the context, sagaframe, identity(s) ONLY in the receiver's durable space
|
|
108
160
|
// if sending domain ibgibs...
|
|
109
|
-
// verify the domain ibgibs intrinsically.
|
|
161
|
+
// verify the domain ibgibs intrinsically.
|
|
110
162
|
// persist the domain ibgibs in the receiver's temp space (push all addrs?)
|
|
111
163
|
// await until all domain ibgibs are in receiver's temp space
|
|
112
164
|
// process the context with the receiver's coordinator to get a new response context
|
|
@@ -114,94 +166,48 @@ export abstract class SyncPeer_V1 extends LightWitnessBase_V1<SyncPeerData_V1, S
|
|
|
114
166
|
// validate context intrinsically
|
|
115
167
|
// validate return identity if present
|
|
116
168
|
// persist the response context's dependency graph (context, saga frame and msg(s), identities)
|
|
117
|
-
// if response has payload domain ibgibs,
|
|
169
|
+
// if response has payload domain ibgibs,
|
|
118
170
|
// spin off...
|
|
119
171
|
// pull domain ibgibs to local temp space
|
|
120
172
|
// publish domain ibgibs to observable
|
|
121
173
|
// when all domain ibgibs are pulled, publish complete to the observable
|
|
122
174
|
// return resulting context ibgib (which the caller should get BEFORE the domain ibgibs observable completes)
|
|
123
175
|
|
|
124
|
-
//
|
|
125
|
-
await
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
|
|
132
|
-
|
|
176
|
+
// validate, authenticate, and authorize the context, sagaFrame, and identity(s)
|
|
177
|
+
const validationErrors = await validateContextAndSagaFrame({ context });
|
|
178
|
+
if (validationErrors.length > 0) {
|
|
179
|
+
throw new Error(`invalid context received. validationErrors: ${validationErrors} (E: 8b34c875c968af29bc433138e57a7826)`);
|
|
180
|
+
}
|
|
181
|
+
const authenticationErrors = await authenticateContext({ context });
|
|
182
|
+
if (authenticationErrors.length > 0) {
|
|
183
|
+
throw new Error(`invalid context authentication. authenticationErrors: ${authenticationErrors} (E: da89da5ee1269aeb78952d475d607526)`);
|
|
184
|
+
}
|
|
185
|
+
const authorizationErrors = await authorizeContext({ context });
|
|
186
|
+
if (authorizationErrors.length > 0) {
|
|
187
|
+
throw new Error(`invalid context authorization. authorizationErrors: ${authorizationErrors} (E: 8ddc284a758cf10ba829334c1babb826)`);
|
|
133
188
|
}
|
|
134
189
|
|
|
135
|
-
// at this point, we have
|
|
136
|
-
// frame/msg stones, and any keystones should be evolved. Depending
|
|
137
|
-
// on the concrete implementation, if there are domain ibgibs to
|
|
138
|
-
// receive, they may already be coming.
|
|
139
|
-
|
|
140
|
-
// todo: this pull is a
|
|
141
|
-
// 3. PULL: Ensure Response Data is available on Sender (Local)
|
|
142
|
-
await this.pullContextGraph({ context: response });
|
|
143
|
-
|
|
144
|
-
return response;
|
|
145
|
-
|
|
146
|
-
} catch (error) {
|
|
147
|
-
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
148
|
-
throw error;
|
|
149
|
-
} finally {
|
|
150
|
-
if (logalot) { console.log(`${lc} complete.`); }
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Transmits the Context IbGib itself to the Peer.
|
|
156
|
-
*/
|
|
157
|
-
protected abstract sendContextRequest(context: SyncSagaContextIbGib_V1): Promise<SyncSagaContextIbGib_V1 | undefined>;
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Pushes specific IbGib(s) (by address) from Local to Remote.
|
|
161
|
-
*
|
|
162
|
-
* Should NOT have to handle identifying if the remote already has it
|
|
163
|
-
* (optimization), because the sync coordinator should be doing this in
|
|
164
|
-
* its diffing algorithm.
|
|
165
|
-
*/
|
|
166
|
-
protected abstract push(addrs: IbGibAddr[]): Promise<void>;
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Primitive: Pulls specific IbGib(s) (by address) from Remote to Local.
|
|
170
|
-
*/
|
|
171
|
-
protected abstract pull(addrs: IbGibAddr[]): Promise<void>;
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* move to sync-peer-helpers.mts as a pure function?
|
|
177
|
-
*/
|
|
178
|
-
protected async authenticateContext({ context }: { context: SyncSagaContextIbGib_V1 }): Promise<string[]> {
|
|
179
|
-
const lc = `${this.lc}[${this.authenticateContext.name}]`;
|
|
180
|
-
try {
|
|
181
|
-
if (logalot) { console.log(`${lc} starting... (I: 2677a482dfa873dcd1aa04a3031ff826)`); }
|
|
182
|
-
|
|
183
|
-
console.error(`${lc} NAG ERROR (NOT THROWN): not implemented. // todo: authenticate (v1 must have this after we get merge logic workflow going) (E: bc3a78f2dab18ab64c36d055a4b50526)`);
|
|
190
|
+
// at this point, we have a valid, authenticated, authorized context
|
|
184
191
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
throw error;
|
|
189
|
-
} finally {
|
|
190
|
-
if (logalot) { console.log(`${lc} complete.`); }
|
|
191
|
-
}
|
|
192
|
-
}
|
|
192
|
+
// execute the transfer of control domain ibgibs & outgoing payload
|
|
193
|
+
// ibgibs...
|
|
194
|
+
const response = await this.sendContextRequest(context);
|
|
193
195
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
196
|
+
if (response) {
|
|
197
|
+
// at this point, all outgoing payload domain ibgibs have been sent.
|
|
198
|
+
// we have received the response context, wherein the sync saga
|
|
199
|
+
// frame/msg stone(s) and any keystones should be evolved. Depending
|
|
200
|
+
// on the concrete implementation, if there are domain ibgibs to
|
|
201
|
+
// receive, they may still be transferring. These will be published
|
|
202
|
+
// to this.payloadIbGibsDomainReceived$
|
|
201
203
|
|
|
202
|
-
|
|
204
|
+
return response;
|
|
205
|
+
} else {
|
|
206
|
+
// response falsy. we could be done, or this could be an error.
|
|
207
|
+
if (logalot) { console.log(`${lc} No response from peer. this may be normal if we just sent the very last commit frame. (I: 1855b7728c8898e1f9c001f8170ba826)`); }
|
|
203
208
|
|
|
204
|
-
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
205
211
|
} catch (error) {
|
|
206
212
|
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
207
213
|
throw error;
|
|
@@ -211,145 +217,35 @@ export abstract class SyncPeer_V1 extends LightWitnessBase_V1<SyncPeerData_V1, S
|
|
|
211
217
|
}
|
|
212
218
|
|
|
213
219
|
/**
|
|
214
|
-
*
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PUSH CONTROL: Msg Stone -> ${addr} (I: 5b6c7d8e9f0a1b2c)`); }
|
|
237
|
-
await this.push([addr]);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
// Identity
|
|
241
|
-
const idAddrs = frame.rel8ns?.identity;
|
|
242
|
-
if (idAddrs) {
|
|
243
|
-
for (const addr of idAddrs) {
|
|
244
|
-
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PUSH CONTROL: Identity -> ${addr} (I: 6c7d8e9f0a1b2c3d)`); }
|
|
245
|
-
await this.push([addr]);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// C. Push Session Identity
|
|
252
|
-
const sessionKeystoneAddr = context.rel8ns?.sessionKeystone?.[0];
|
|
253
|
-
if (sessionKeystoneAddr) {
|
|
254
|
-
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PUSH CONTROL: Session Keystone -> ${sessionKeystoneAddr} (I: 7d8e9f0a1b2c3d4e)`); }
|
|
255
|
-
await this.push([sessionKeystoneAddr]);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// D. Push Payloads (Deep/Soft)
|
|
259
|
-
// For payloads, the Peer is just a transport. It doesn't know the structure.
|
|
260
|
-
// It relies on "push" handling the "deep" transfer if needed, or we explicitly iterate if we had a graph.
|
|
261
|
-
// But since we are "Witnessing", we usually assume "push(addr)" acts like "copy(addr, recursive=true)"?
|
|
262
|
-
// Or do we need to be explicit?
|
|
263
|
-
// User said: "payloads should be flat... sync coordinator is the one doing the heavy lifting".
|
|
264
|
-
// So we just push the addrs listed.
|
|
265
|
-
|
|
266
|
-
// 1. Control Payloads
|
|
267
|
-
// const controlAddrs = context.data?.[SYNC_SAGA_PAYLOAD_ADDRS_CONTROL];
|
|
268
|
-
// if (controlAddrs && controlAddrs.length > 0) {
|
|
269
|
-
// if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PUSH CONTROL PAYLOADS (${controlAddrs.length}): ${controlAddrs.join(', ')} (I: 8e9f0a1b2c3d4e5f)`); }
|
|
270
|
-
// for (const addr of controlAddrs) {
|
|
271
|
-
// await this.push(addr);
|
|
272
|
-
// }
|
|
273
|
-
// }
|
|
274
|
-
|
|
275
|
-
// 2. Domain Payloads
|
|
276
|
-
const domainAddrs = context.data?.[SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN];
|
|
277
|
-
if (domainAddrs && domainAddrs.length > 0) {
|
|
278
|
-
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PUSH DOMAIN PAYLOADS (${domainAddrs.length}): ${domainAddrs.join(', ')} (I: 9f0a1b2c3d4e5f6a)`); }
|
|
279
|
-
for (const addr of domainAddrs) {
|
|
280
|
-
await this.push([addr]);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PUSH COMPLETE for context ${contextAddr} (I: a0b1c2d3e4f5a6b7)`); }
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Helper to orchestrate the PULL of a Context's dependency graph.
|
|
220
|
+
* At this point, this is a validated, authenticated and authorized context
|
|
221
|
+
* to send.
|
|
222
|
+
*
|
|
223
|
+
* This is responsible for:
|
|
224
|
+
*
|
|
225
|
+
* * physical sending outgoing {@link context}, the sync saga frame and msg
|
|
226
|
+
* stone(s), and identities...
|
|
227
|
+
* * AND sending OUTGOING domain ibgibs
|
|
228
|
+
* {@link SyncSagaContextIbGib_V1.payloadIbGibsDomain}
|
|
229
|
+
* * getting back the other end's resultant context ibgib, sync saga frame
|
|
230
|
+
* and msg stone(s), and identities in their entirety...
|
|
231
|
+
* * AND stream/receiving the RESPONSE payload domain ibgibs, publishing
|
|
232
|
+
* these to this.payloadIbGibsDomainReceived$.
|
|
233
|
+
* * BUT this should return as soon as the resultant context ibgib comes
|
|
234
|
+
* back.
|
|
235
|
+
*
|
|
236
|
+
* So this returns the RESPONSE context, possibly BEFORE the response DOMAIN
|
|
237
|
+
* ibgibs have been completely received/streamed. The coordinator is
|
|
238
|
+
* responsible for awaiting this stream.
|
|
239
|
+
*
|
|
240
|
+
* @returns next sync saga context if another round, or undefined if we're
|
|
241
|
+
* done. (might throw if there's an error?)
|
|
289
242
|
*/
|
|
290
|
-
protected
|
|
291
|
-
const lc = `[${SyncPeer_V1.name}][pullContextGraph]`;
|
|
292
|
-
|
|
293
|
-
// A. Pull Context Envelope
|
|
294
|
-
const contextAddr = getIbGibAddr({ ibGib: context });
|
|
295
|
-
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PULL Context Envelope <- ${contextAddr} (I: b1c2d3e4f5a6b7c8)`); }
|
|
296
|
-
await this.pull([contextAddr]);
|
|
297
|
-
|
|
298
|
-
// B. Pull Saga Frame & Immediate Deps
|
|
299
|
-
const frameAddr = context.rel8ns?.sagaFrame?.[0];
|
|
300
|
-
if (frameAddr) {
|
|
301
|
-
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PULL CONTROL: Saga Frame <- ${frameAddr} (I: c2d3e4f5a6b7c8d9)`); }
|
|
302
|
-
await this.pull([frameAddr]);
|
|
303
|
-
// Inspect REMOTE frame? We need to have pulled it first.
|
|
304
|
-
const frame = await this.getLocalIbGib(frameAddr); // Should be local now
|
|
305
|
-
if (frame) {
|
|
306
|
-
const msgAddrs = frame.rel8ns?.[SYNC_MSG_REL8N_NAME];
|
|
307
|
-
if (msgAddrs) {
|
|
308
|
-
for (const addr of msgAddrs) {
|
|
309
|
-
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PULL CONTROL: Msg Stone <- ${addr} (I: d3e4f5a6b7c8d9e0)`); }
|
|
310
|
-
await this.pull([addr]);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
const idAddrs = frame.rel8ns?.identity;
|
|
314
|
-
if (idAddrs) {
|
|
315
|
-
for (const addr of idAddrs) {
|
|
316
|
-
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PULL CONTROL: Identity <- ${addr} (I: e4f5a6b7c8d9e0f1)`); }
|
|
317
|
-
await this.pull([addr]);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// C. Pull Session Identity
|
|
324
|
-
const sessionKeystoneAddr = context.rel8ns?.sessionKeystone?.[0];
|
|
325
|
-
if (sessionKeystoneAddr) {
|
|
326
|
-
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PULL CONTROL: Session Keystone <- ${sessionKeystoneAddr} (I: f5a6b7c8d9e0f1a2)`); }
|
|
327
|
-
await this.pull([sessionKeystoneAddr]);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// D. Pull Payloads
|
|
331
|
-
// const controlAddrs = context.data?.[SYNC_SAGA_PAYLOAD_ADDRS_CONTROL];
|
|
332
|
-
// if (controlAddrs && controlAddrs.length > 0) {
|
|
333
|
-
// if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PULL CONTROL PAYLOADS (${controlAddrs.length}): ${controlAddrs.join(', ')} (I: a6b7c8d9e0f1a2b3)`); }
|
|
334
|
-
// for (const addr of controlAddrs) {
|
|
335
|
-
// await this.pull(addr);
|
|
336
|
-
// }
|
|
337
|
-
// }
|
|
338
|
-
const domainAddrs = context.data?.[SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN];
|
|
339
|
-
if (domainAddrs && domainAddrs.length > 0) {
|
|
340
|
-
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PULL DOMAIN PAYLOADS (${domainAddrs.length}): ${domainAddrs.join(', ')} (I: b7c8d9e0f1a2b3c4)`); }
|
|
341
|
-
for (const addr of domainAddrs) {
|
|
342
|
-
await this.pull([addr]);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} PULL COMPLETE for context ${contextAddr} (I: c8d9e0f1a2b3c4d5)`); }
|
|
347
|
-
}
|
|
243
|
+
protected abstract sendContextRequest(context: SyncSagaContextIbGib_V1): Promise<SyncSagaContextIbGib_V1 | undefined>;
|
|
348
244
|
|
|
349
245
|
/**
|
|
350
246
|
* Abstract accessor to get an IbGib from the Local space/store.
|
|
351
247
|
* Needed for inspecting rela8ns during the graph walk.
|
|
352
|
-
*
|
|
248
|
+
*
|
|
353
249
|
* Default implementation simply looks in senderSpace
|
|
354
250
|
*/
|
|
355
251
|
protected async getLocalIbGib(addr: string): Promise<IbGib_V1 | undefined> {
|
|
@@ -358,14 +254,15 @@ export abstract class SyncPeer_V1 extends LightWitnessBase_V1<SyncPeerData_V1, S
|
|
|
358
254
|
if (logalot) { console.log(`${lc} starting... (I: 27b248cb9801eeb2386b71485389a826)`); }
|
|
359
255
|
|
|
360
256
|
console.warn(`${lc} possibly a bottleneck here, getLocalIbGib only gets a single ibgib... (W: 2fd448a435480e6b128f6b8bcbef4826)`);
|
|
257
|
+
if (!this.opts) { throw new Error(`(UNEXPECTED) this.opts falsy? (E: cfb9431f2fb851f24a6c88e80c3b3326)`); }
|
|
361
258
|
|
|
362
|
-
const resGet = await getFromSpace({ space: this.senderSpace, addr });
|
|
259
|
+
const resGet = await getFromSpace({ space: this.opts.senderSpace, addr });
|
|
363
260
|
|
|
364
261
|
if (resGet.success && resGet.ibGibs && resGet.ibGibs.length === 1) {
|
|
365
262
|
const ibGib = resGet.ibGibs[0];
|
|
366
263
|
return ibGib;
|
|
367
264
|
} else {
|
|
368
|
-
throw new Error(`couldn't get addr (${addr}) from local space ${this.senderSpace}. reason: ${resGet.errorMsg ?? 'unknown error (E: 926ef8bf4fcc299ab89dba34ea691a26)'} (E: d8a89807e471d3f8b938ab21df44cb26)`);
|
|
265
|
+
throw new Error(`couldn't get addr (${addr}) from local space ${this.opts.senderSpace}. reason: ${resGet.errorMsg ?? 'unknown error (E: 926ef8bf4fcc299ab89dba34ea691a26)'} (E: d8a89807e471d3f8b938ab21df44cb26)`);
|
|
369
266
|
}
|
|
370
267
|
} catch (error) {
|
|
371
268
|
console.error(`${lc} ${extractErrorMsg(error)}`);
|