@ibgib/core-gib 0.1.25 → 0.1.27
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/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/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 +21 -1
- package/dist/sync/sync-helpers.d.mts.map +1 -1
- package/dist/sync/sync-helpers.mjs +137 -4
- package/dist/sync/sync-helpers.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts +0 -2
- 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 +169 -62
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.d.mts +13 -29
- package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.mjs +18 -57
- package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +15 -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 +77 -7
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +8 -0
- package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.d.mts +76 -17
- package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.mjs +545 -480
- package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
- package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts +1 -1
- package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts.map +1 -1
- package/dist/sync/sync-types.d.mts +31 -4
- package/dist/sync/sync-types.d.mts.map +1 -1
- package/dist/sync/sync-types.mjs +32 -0
- package/dist/sync/sync-types.mjs.map +1 -1
- package/package.json +2 -2
- package/src/common/other/ibgib-helper.mts +1 -1
- package/src/sync/sync-constants.mts +1 -0
- package/src/sync/sync-helpers.mts +132 -4
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +169 -47
- package/src/sync/sync-peer/sync-peer-v1.mts +33 -74
- package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +69 -9
- package/src/sync/sync-saga-context/sync-saga-context-types.mts +13 -5
- package/src/sync/sync-saga-coordinator.mts +628 -530
- package/src/sync/sync-saga-message/sync-saga-message-types.mts +18 -18
- package/src/sync/sync-types.mts +40 -3
|
@@ -2,20 +2,28 @@
|
|
|
2
2
|
* @module SyncPeerInnerspace_V1
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { extractErrorMsg, unique } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
5
|
+
import { delay, extractErrorMsg, pretty, unique } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
6
6
|
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
7
7
|
import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
|
|
8
|
+
import { IbGib_V1, IbGibData_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
|
|
9
|
+
import { isDna } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';
|
|
8
10
|
|
|
9
11
|
import { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';
|
|
10
12
|
import { IbGibSpaceAny } from '../../../witness/space/space-base-v1.mjs';
|
|
11
13
|
import { SyncPeer_V1 } from '../sync-peer-v1.mjs';
|
|
12
|
-
import { getFromSpace, putInSpace } from '../../../witness/space/space-helper.mjs';
|
|
14
|
+
import { getFromSpace, putInSpace, registerNewIbGib } from '../../../witness/space/space-helper.mjs';
|
|
13
15
|
import { SyncSagaContextIbGib_V1, } from '../../sync-saga-context/sync-saga-context-types.mjs';
|
|
14
16
|
import { SyncPeerInnerspaceData_V1, SyncPeerInnerspaceIbGib_V1, SyncPeerInnerspaceOptions, SyncPeerInnerspaceRel8ns_V1 } from './sync-peer-innerspace-types.mjs';
|
|
15
17
|
import { MetaspaceService } from '../../../witness/space/metaspace/metaspace-types.mjs';
|
|
16
18
|
import { SyncSagaCoordinator } from '../../sync-saga-coordinator.mjs';
|
|
17
19
|
import { IbGibSpaceResultData } from '../../../witness/space/space-types.mjs';
|
|
18
20
|
import { InitializeSyncPeerOpts } from '../sync-peer-types.mjs';
|
|
21
|
+
import { getSyncSagaMessageFromFrame } from '../../sync-saga-message/sync-saga-message-helpers.mjs';
|
|
22
|
+
import { SYNC_STAGE_VALID_VALUES, SyncStage } from '../../sync-constants.mjs';
|
|
23
|
+
import { SyncSagaMessageAckData_V1, SyncSagaMessageCommitData_V1, SyncSagaMessageData_V1, SyncSagaMessageDeltaData_V1, SyncSagaMessageInitData_V1 } from '../../sync-saga-message/sync-saga-message-types.mjs';
|
|
24
|
+
import { getExecutionContext, getSyncSagaFrameDependencyGraph, putInSpace_dnasThenNonDnas } from '../../sync-helpers.mjs';
|
|
25
|
+
import { splitPerTjpAndOrDna, toDto } from '../../../common/other/ibgib-helper.mjs';
|
|
26
|
+
import { SyncExecutionContext } from '../../sync-types.mjs';
|
|
19
27
|
|
|
20
28
|
|
|
21
29
|
const logalot = GLOBAL_LOG_A_LOT || true;
|
|
@@ -101,69 +109,183 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1<InitializeSyncPeerInnersp
|
|
|
101
109
|
}
|
|
102
110
|
}
|
|
103
111
|
|
|
104
|
-
|
|
105
|
-
protected async push(addrs: IbGibAddr[]): Promise<void> {
|
|
106
|
-
const lc = `${this.lc}[${this.push.name}]`;
|
|
107
|
-
try {
|
|
108
|
-
if (logalot) { console.log(`${lc} starting... (I: 07bce80be18f3259b8a311ed9c4da926)`); }
|
|
109
|
-
if (!this.opts) { throw new Error(`(UNEXPECTED) this.opts falsy? (E: e1efd1b364cc8a8d985b243878f71e26)`); }
|
|
110
|
-
|
|
111
|
-
// silly defensive checks because this has been a ridiculous development cycle
|
|
112
|
-
if (!this.opts.senderSpace) { throw new Error(`(UNEXPECTED) this.opts.senderSpace falsy? (E: 503e288168f5d297f4d4e028bc538826)`); }
|
|
113
|
-
if (!this.opts.receiverTempSpace) { throw new Error(`(UNEXPECTED) this.opts.receiverTempSpace falsy? (E: 0bd7c1a0ba4868ac7a260e15b504e826)`); }
|
|
114
|
-
|
|
115
|
-
await this.transfer({ addrs, from: this.opts.senderSpace, to: this.opts.receiverTempSpace });
|
|
116
|
-
} catch (error) {
|
|
117
|
-
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
118
|
-
throw error;
|
|
119
|
-
} finally {
|
|
120
|
-
if (logalot) { console.log(`${lc} complete.`); }
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
protected async pull(addrs: IbGibAddr[]): Promise<void> {
|
|
125
|
-
const lc = `${this.lc}[${this.pull.name}]`;
|
|
126
|
-
try {
|
|
127
|
-
if (logalot) { console.log(`${lc} starting... (I: b16a28ed0dc8f52f1838ee257d9b1126)`); }
|
|
128
|
-
|
|
129
|
-
if (!this.opts) { throw new Error(`(UNEXPECTED) this.opts falsy? (E: 5a72b83fc1a83bf0f81d19330f575626)`); }
|
|
130
|
-
|
|
131
|
-
// silly defensive checks because this has been a ridiculous development cycle
|
|
132
|
-
if (!this.opts.receiverSpace) { throw new Error(`(UNEXPECTED) this.opts.receiverSpace falsy? (E: bd2fdfa89ba4c89a185b68e9bb1f1c26)`); }
|
|
133
|
-
if (!this.opts.senderTempSpace) { throw new Error(`(UNEXPECTED) this.opts.senderTempSpace falsy? (E: b23fa55713f881493dac4a9835ac7326)`); }
|
|
134
|
-
|
|
135
|
-
await this.transfer({ addrs, from: this.opts.receiverSpace, to: this.opts.senderTempSpace });
|
|
136
|
-
} catch (error) {
|
|
137
|
-
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
138
|
-
throw error;
|
|
139
|
-
} finally {
|
|
140
|
-
if (logalot) { console.log(`${lc} complete.`); }
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
112
|
protected async sendContextRequest(context: SyncSagaContextIbGib_V1): Promise<SyncSagaContextIbGib_V1 | undefined> {
|
|
145
113
|
const lc = `${this.lc}[${this.sendContextRequest.name}]`;
|
|
146
114
|
try {
|
|
147
115
|
if (!this.opts) { throw new Error(`(UNEXPECTED) this.opts falsy? (E: d8b1348e3233810128999596b1fa5826)`); }
|
|
148
116
|
|
|
149
|
-
const {
|
|
117
|
+
const {
|
|
118
|
+
senderSpace, senderTempSpace,
|
|
119
|
+
receiverSpace, receiverCoordinator, receiverMetaspace,
|
|
120
|
+
receiverTempSpace
|
|
121
|
+
} = this.opts;
|
|
150
122
|
|
|
151
123
|
if (logalot) { console.log(`${lc} starting...Context: ${getIbGibAddr({ ibGib: context })}`); }
|
|
152
124
|
|
|
153
|
-
|
|
125
|
+
const { sagaFrame } = context;
|
|
126
|
+
|
|
127
|
+
// The context has already been validated, authenticated and authorized at this point.
|
|
128
|
+
|
|
129
|
+
// #region sanity validation assertions
|
|
154
130
|
if (!context.data) { throw new Error(`(UNEXPECTED) context.data falsy? (E: 1d2ac8a9b991d451e8900588057fe626)`); }
|
|
155
131
|
if (!context.rel8ns) { throw new Error(`(UNEXPECTED) context.rel8ns falsy? (E: 3508786f0d8880bcadd346282a807826)`); }
|
|
156
132
|
if (!context.rel8ns.sagaFrame) { throw new Error(`(UNEXPECTED) context.rel8ns.sagaFrame falsy? (E: ac06782ad538be406882605f0a83aa26)`); }
|
|
157
133
|
if (!context.sagaFrame) { throw new Error(`(UNEXPECTED) context.sagaFrame falsy? (E: 79cd98a6d9b88a591f4596c8bc58ff26)`); }
|
|
134
|
+
if (!sagaFrame.data) { throw new Error(`(UNEXPECTED) sagaFrame.data falsy? (E: f30e290a8b770e1b387377420ea73a26)`); }
|
|
135
|
+
if (!sagaFrame.rel8ns) { throw new Error(`(UNEXPECTED) sagaFrame.rel8ns falsy? (E: f888caa698b8cf6b4893b7fd6df09726)`); }
|
|
136
|
+
if (!receiverTempSpace) { throw new Error(`(UNEXPECTED) receiverTempSpace falsy? (E: 3b46d838f6fc645c58b29215bfddb826)`); }
|
|
137
|
+
if (!senderTempSpace) { throw new Error(`(UNEXPECTED) senderTempSpace falsy? (E: b187a8f913c2295ae90d7ae2b47b6a26)`); }
|
|
138
|
+
// #endregion sanity validation assertions
|
|
139
|
+
|
|
140
|
+
// let localSpace: IbGibSpaceAny;
|
|
141
|
+
// let localTempSpace: IbGibSpaceAny;
|
|
142
|
+
// let remoteSpace: IbGibSpaceAny;
|
|
143
|
+
// let remoteTempSpace: IbGibSpaceAny;
|
|
144
|
+
// if (getExecutionContext({ sagaFrame: context.sagaFrame }) === SyncExecutionContext.sender) {
|
|
145
|
+
// localSpace = senderSpace;
|
|
146
|
+
// localTempSpace = senderTempSpace;
|
|
147
|
+
// remoteSpace = receiverSpace;
|
|
148
|
+
// remoteTempSpace = receiverTempSpace;
|
|
149
|
+
// } else {
|
|
150
|
+
// localSpace = receiverSpace;
|
|
151
|
+
// localTempSpace = receiverTempSpace;
|
|
152
|
+
// remoteSpace = senderSpace;
|
|
153
|
+
// remoteTempSpace = senderSpace;
|
|
154
|
+
// }
|
|
155
|
+
|
|
156
|
+
const { sagaIbGib: _alreadyHave, msgStones, identities } = await getSyncSagaFrameDependencyGraph({
|
|
157
|
+
sagaIbGib: sagaFrame,
|
|
158
|
+
localSpace: senderSpace,
|
|
159
|
+
});
|
|
160
|
+
if (msgStones.length !== 1) { throw new Error(`(UNEXPECTED) msgStones.length !== 1? we're only geared for a single msg stone that is always present (not 0, not greater than 1) (E: 2d3138ed130f1aca116551889483e826)`); }
|
|
161
|
+
const msg = msgStones[0];
|
|
162
|
+
if (!msg.data) { throw new Error(`(UNEXPECTED) sync saga message ibgib.data falsy? (E: 61ec18743988ad3cbab2072d1dd69826)`); }
|
|
158
163
|
|
|
164
|
+
// send the context itself, then send the payload ibgibs separately.
|
|
165
|
+
// in this innerspace, this just means putting the control ibgibs
|
|
166
|
+
// first into the receiver durable space, then we will spin off a
|
|
167
|
+
// promise to put any payload ibgibs in the receiver temp space.
|
|
168
|
+
// We'll test a little latency also, to mimic a fuller, two-part
|
|
169
|
+
// sync peer to ensure that other code is acting as expected.
|
|
170
|
+
|
|
171
|
+
// we store inside out, meaning we do the dependencies first and
|
|
172
|
+
// then the higher-level dependents.
|
|
173
|
+
const payloadIbGibsControl = [
|
|
174
|
+
...identities, msg, sagaFrame, context
|
|
175
|
+
].map(x => toDto({ ibGib: x }));
|
|
176
|
+
await putInSpace({
|
|
177
|
+
ibGibs: payloadIbGibsControl,
|
|
178
|
+
space: receiverSpace,
|
|
179
|
+
});
|
|
180
|
+
// register yet??
|
|
181
|
+
for (const control of payloadIbGibsControl) {
|
|
182
|
+
await registerNewIbGib({
|
|
183
|
+
ibGib: control,
|
|
184
|
+
space: receiverSpace,
|
|
185
|
+
fnBroadcast: undefined
|
|
186
|
+
});
|
|
187
|
+
}
|
|
159
188
|
|
|
160
|
-
|
|
189
|
+
if (context.payloadIbGibsDomain && context.payloadIbGibsDomain.length > 0) {
|
|
190
|
+
await putInSpace_dnasThenNonDnas({
|
|
191
|
+
ibGibs: context.payloadIbGibsDomain,
|
|
192
|
+
space: receiverTempSpace,
|
|
193
|
+
});
|
|
161
194
|
|
|
162
|
-
|
|
195
|
+
// no need to register right now, because we're putting into the
|
|
196
|
+
// temp receiver space and we don't register until we commit
|
|
197
|
+
// const { mapWithTjp_NoDna, mapWithTjp_YesDna, mapWithoutTjps } =
|
|
198
|
+
// splitPerTjpAndOrDna({ ibGibs: payload_NonDnas });
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// at this time, the receiver has received the control ibgibs AND
|
|
202
|
+
// the payload ibgibs. so the receiver coordinator should be ready
|
|
203
|
+
// to do its thing.
|
|
163
204
|
|
|
205
|
+
const responseCtx = await receiverCoordinator.continueSync({
|
|
206
|
+
sagaContext: context,
|
|
207
|
+
metaspace: receiverMetaspace,
|
|
208
|
+
mySpace: receiverSpace,
|
|
209
|
+
myTempSpace: receiverTempSpace,
|
|
210
|
+
});
|
|
164
211
|
|
|
212
|
+
if (logalot) { console.log(`${lc} receiverCoordinator.continueSync responseCtx: ${responseCtx ? pretty(responseCtx) : 'undefined'} (I: fb2831decde1f2b3589021f85ab19126)`); }
|
|
213
|
+
|
|
214
|
+
if (!responseCtx) {
|
|
215
|
+
if (logalot) { console.log(`${lc} receiver produced undefined response context. (I: 2e1888ffc9e836689d5b171887c36d26)`); }
|
|
216
|
+
return undefined; /* <<<< returns early */
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// at this point, we have received the full response from the
|
|
220
|
+
// receiver coordinator. That coordinator has put the control ibgibs
|
|
221
|
+
// in its durable space. Now we need to put the response's control
|
|
222
|
+
// ibgibs in the sender's durable space (register them??), spin off
|
|
223
|
+
// the process of any response payloads, and return the context.
|
|
224
|
+
|
|
225
|
+
// get control ibgibs from the receiver space...
|
|
226
|
+
const { msgStones: msgStonesResponse, identities: identitiesResponse } =
|
|
227
|
+
await getSyncSagaFrameDependencyGraph({
|
|
228
|
+
sagaIbGib: responseCtx.sagaFrame,
|
|
229
|
+
localSpace: receiverSpace,
|
|
230
|
+
});
|
|
231
|
+
if (msgStonesResponse.length !== 1) { throw new Error(`(UNEXPECTED) msgStonesResponse.length !== 1? we're only geared for a single msg stone that is always present (not 0, not greater than 1) (E: 2d3138ed130f1aca116551889483e826)`); }
|
|
232
|
+
const msgResponse = msgStonesResponse[0];
|
|
233
|
+
if (!msgResponse.data) { throw new Error(`(UNEXPECTED) sync saga message ibgib.data falsy? (E: 61ec18743988ad3cbab2072d1dd69826)`); }
|
|
234
|
+
const responsePayloadIbGibsControl = [
|
|
235
|
+
...identities, msgResponse, responseCtx.sagaFrame, context
|
|
236
|
+
].map(x => toDto({ ibGib: x }));
|
|
237
|
+
// ...put into sender's durable space
|
|
238
|
+
await putInSpace({
|
|
239
|
+
ibGibs: responsePayloadIbGibsControl,
|
|
240
|
+
space: senderSpace,
|
|
241
|
+
});
|
|
242
|
+
// register yet??
|
|
243
|
+
for (const control of responsePayloadIbGibsControl) {
|
|
244
|
+
await registerNewIbGib({
|
|
245
|
+
ibGib: control,
|
|
246
|
+
space: senderSpace,
|
|
247
|
+
fnBroadcast: undefined
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// spin off the payloads, as that may take a long time
|
|
252
|
+
const payloadIbGibsDomain_response = responseCtx.payloadIbGibsDomain;
|
|
253
|
+
if (payloadIbGibsDomain_response) {
|
|
254
|
+
new Promise<void>(async (resolve, reject) => {
|
|
255
|
+
const lcPut = `${lc}[putPayloadsPromise]`;
|
|
256
|
+
try {
|
|
257
|
+
if (logalot) { console.log(`${lcPut} starting... (I: 4133e736b4c80d2cf94448b87b206826)`); }
|
|
258
|
+
|
|
259
|
+
// 2 seconds...i want to see huge blocks of logs entries for this to see this happening
|
|
260
|
+
const delayMs = 200;
|
|
261
|
+
for (let i = 0; i < 10; i++) {
|
|
262
|
+
console.warn(`${lc} ARTIFICIALLY DELAYING PAYLOADS TO MIMIC TRANSFER LATENCY. REMOVE THIS DELAY!! (W: 5e7b28f1daa82d955897e9d8cdb16f26)`)
|
|
263
|
+
await delay(delayMs);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
await putInSpace_dnasThenNonDnas({
|
|
268
|
+
ibGibs: payloadIbGibsDomain_response,
|
|
269
|
+
space: senderTempSpace,
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
if (logalot) { console.log(`${lcPut} complete.`); }
|
|
273
|
+
resolve();
|
|
274
|
+
} catch (error) {
|
|
275
|
+
const errorMsg = `${lcPut} ${extractErrorMsg(error)}`;
|
|
276
|
+
console.error(errorMsg);
|
|
277
|
+
if (logalot) { console.log(`${lcPut} complete. (errored)`); }
|
|
278
|
+
reject(errorMsg);
|
|
279
|
+
}
|
|
280
|
+
}); // spin off
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* the caller should be getting these from the observable.
|
|
284
|
+
*/
|
|
285
|
+
delete responseCtx.payloadIbGibsDomain;
|
|
286
|
+
}
|
|
165
287
|
|
|
166
|
-
|
|
288
|
+
return responseCtx;
|
|
167
289
|
} catch (error) {
|
|
168
290
|
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
169
291
|
throw error;
|
|
@@ -18,7 +18,7 @@ import { InitializeSyncPeerOpts, SyncPeerData_V1, SyncPeerRel8ns_V1, SyncPeerWit
|
|
|
18
18
|
import { LightWitnessBase_V1 } from '../../witness/light-witness-base-v1.mjs';
|
|
19
19
|
import { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';
|
|
20
20
|
import { newupSubject } from '../../common/pubsub/subject/subject-helper.mjs';
|
|
21
|
-
import { validateContextAndSagaFrame } from '../sync-saga-context/sync-saga-context-helpers.mjs';
|
|
21
|
+
import { authenticateContext, authorizeContext, validateContextAndSagaFrame } from '../sync-saga-context/sync-saga-context-helpers.mjs';
|
|
22
22
|
import { getFromSpace } from '../../witness/space/space-helper.mjs';
|
|
23
23
|
|
|
24
24
|
const logalot = GLOBAL_LOG_A_LOT || true;
|
|
@@ -178,34 +178,38 @@ export abstract class SyncPeer_V1<TInitializeOpts extends InitializeSyncPeerOpts
|
|
|
178
178
|
if (validationErrors.length > 0) {
|
|
179
179
|
throw new Error(`invalid context received. validationErrors: ${validationErrors} (E: 8b34c875c968af29bc433138e57a7826)`);
|
|
180
180
|
}
|
|
181
|
-
const authenticationErrors = await
|
|
181
|
+
const authenticationErrors = await authenticateContext({ context });
|
|
182
182
|
if (authenticationErrors.length > 0) {
|
|
183
183
|
throw new Error(`invalid context authentication. authenticationErrors: ${authenticationErrors} (E: da89da5ee1269aeb78952d475d607526)`);
|
|
184
184
|
}
|
|
185
|
-
const authorizationErrors = await
|
|
185
|
+
const authorizationErrors = await authorizeContext({ context });
|
|
186
186
|
if (authorizationErrors.length > 0) {
|
|
187
187
|
throw new Error(`invalid context authorization. authorizationErrors: ${authorizationErrors} (E: 8ddc284a758cf10ba829334c1babb826)`);
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
// at this point, we have a valid, authenticated, authorized context
|
|
191
191
|
|
|
192
|
-
|
|
193
|
-
const response = await this.sendContextRequest(context);
|
|
192
|
+
await this.ensureReceiverTempSpace();
|
|
194
193
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
194
|
+
// execute the transfer of control domain ibgibs & outgoing payload
|
|
195
|
+
// ibgibs...
|
|
196
|
+
const response = await this.sendContextRequest(context);
|
|
199
197
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
198
|
+
if (response) {
|
|
199
|
+
// at this point, all outgoing payload domain ibgibs have been sent.
|
|
200
|
+
// we have received the response context, wherein the sync saga
|
|
201
|
+
// frame/msg stone(s) and any keystones should be evolved. Depending
|
|
202
|
+
// on the concrete implementation, if there are domain ibgibs to
|
|
203
|
+
// receive, they may still be transferring. These will be published
|
|
204
|
+
// to this.payloadIbGibsDomainReceived$
|
|
206
205
|
|
|
207
|
-
|
|
206
|
+
return response;
|
|
207
|
+
} else {
|
|
208
|
+
// response falsy. we could be done, or this could be an error.
|
|
209
|
+
if (logalot) { console.log(`${lc} No response from peer. this may be normal if we just sent the very last commit frame. (I: 1855b7728c8898e1f9c001f8170ba826)`); }
|
|
208
210
|
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
209
213
|
} catch (error) {
|
|
210
214
|
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
211
215
|
throw error;
|
|
@@ -215,75 +219,30 @@ export abstract class SyncPeer_V1<TInitializeOpts extends InitializeSyncPeerOpts
|
|
|
215
219
|
}
|
|
216
220
|
|
|
217
221
|
/**
|
|
222
|
+
* At this point, this is a validated, authenticated and authorized context
|
|
223
|
+
* to send.
|
|
224
|
+
*
|
|
218
225
|
* This is responsible for:
|
|
219
226
|
*
|
|
220
|
-
* * sending outgoing {@link context}, the sync saga frame and msg
|
|
221
|
-
* and identities...
|
|
227
|
+
* * physical sending outgoing {@link context}, the sync saga frame and msg
|
|
228
|
+
* stone(s), and identities...
|
|
222
229
|
* * AND sending OUTGOING domain ibgibs
|
|
223
230
|
* {@link SyncSagaContextIbGib_V1.payloadIbGibsDomain}
|
|
224
231
|
* * getting back the other end's resultant context ibgib, sync saga frame
|
|
225
232
|
* and msg stone(s), and identities in their entirety...
|
|
226
233
|
* * AND stream/receiving the RESPONSE payload domain ibgibs, publishing
|
|
227
234
|
* these to this.payloadIbGibsDomainReceived$.
|
|
235
|
+
* * BUT this should return as soon as the resultant context ibgib comes
|
|
236
|
+
* back.
|
|
228
237
|
*
|
|
229
|
-
* So this returns the RESPONSE context, possibly BEFORE the
|
|
230
|
-
* ibgibs have been completely received/streamed. The coordinator is
|
|
231
|
-
|
|
232
|
-
protected abstract sendContextRequest(context: SyncSagaContextIbGib_V1): Promise<SyncSagaContextIbGib_V1 | undefined>;
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Pushes specific IbGib(s) (by address) from Local to Remote.
|
|
238
|
+
* So this returns the RESPONSE context, possibly BEFORE the response DOMAIN
|
|
239
|
+
* ibgibs have been completely received/streamed. The coordinator is
|
|
240
|
+
* responsible for awaiting this stream.
|
|
236
241
|
*
|
|
237
|
-
*
|
|
238
|
-
* (
|
|
239
|
-
* its diffing algorithm.
|
|
240
|
-
*/
|
|
241
|
-
protected abstract push(addrs: IbGibAddr[]): Promise<void>;
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Primitive: Pulls specific IbGib(s) (by address) from Remote to Local.
|
|
245
|
-
*/
|
|
246
|
-
protected abstract pull(addrs: IbGibAddr[]): Promise<void>;
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* move to sync-peer-helpers.mts as a pure function?
|
|
252
|
-
*/
|
|
253
|
-
protected async authenticateContext({ context }: { context: SyncSagaContextIbGib_V1 }): Promise<string[]> {
|
|
254
|
-
const lc = `${this.lc}[${this.authenticateContext.name}]`;
|
|
255
|
-
try {
|
|
256
|
-
if (logalot) { console.log(`${lc} starting... (I: 2677a482dfa873dcd1aa04a3031ff826)`); }
|
|
257
|
-
|
|
258
|
-
console.error(`${lc} NAG ERROR (NOT THROWN): not implemented. // todo: authenticate (v1 must have this after we get merge logic workflow going) (E: bc3a78f2dab18ab64c36d055a4b50526)`);
|
|
259
|
-
|
|
260
|
-
return [];
|
|
261
|
-
} catch (error) {
|
|
262
|
-
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
263
|
-
throw error;
|
|
264
|
-
} finally {
|
|
265
|
-
if (logalot) { console.log(`${lc} complete.`); }
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* move to sync-peer-helpers.mts as a pure function?
|
|
242
|
+
* @returns next sync saga context if another round, or undefined if we're
|
|
243
|
+
* done. (might throw if there's an error?)
|
|
271
244
|
*/
|
|
272
|
-
protected
|
|
273
|
-
const lc = `${this.lc}[${this.authorizeContext.name}]`;
|
|
274
|
-
try {
|
|
275
|
-
if (logalot) { console.log(`${lc} starting... (I: 48c918b41ceec0cd489ca3b8819e6826)`); }
|
|
276
|
-
|
|
277
|
-
console.error(`${lc} NAG ERROR (NOT THROWN): not implemented. authorize business logic (v1 must have this, but later when we are working on admin vs. student)(E: bc3a78f2dab18ab64c36d055a4b50526)`);
|
|
278
|
-
|
|
279
|
-
return [];
|
|
280
|
-
} catch (error) {
|
|
281
|
-
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
282
|
-
throw error;
|
|
283
|
-
} finally {
|
|
284
|
-
if (logalot) { console.log(`${lc} complete.`); }
|
|
285
|
-
}
|
|
286
|
-
}
|
|
245
|
+
protected abstract sendContextRequest(context: SyncSagaContextIbGib_V1): Promise<SyncSagaContextIbGib_V1 | undefined>;
|
|
287
246
|
|
|
288
247
|
/**
|
|
289
248
|
* Abstract accessor to get an IbGib from the Local space/store.
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
import { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';
|
|
20
20
|
import { putInSpace, registerNewIbGib } from '../../witness/space/space-helper.mjs';
|
|
21
21
|
import { SyncIbGib_V1 } from '../sync-types.mjs';
|
|
22
|
+
import { validateSyncSagaFrame } from '../sync-helpers.mjs';
|
|
22
23
|
|
|
23
24
|
const logalot = GLOBAL_LOG_A_LOT;
|
|
24
25
|
|
|
@@ -59,9 +60,10 @@ export async function getSyncSagaContextIb({
|
|
|
59
60
|
if (!data) { throw new Error(`data required (E: 839d82138c234b3e89582855594191fe)`); }
|
|
60
61
|
|
|
61
62
|
const payloadCount = data['@payloadAddrsDomain'] ? data['@payloadAddrsDomain'].length : 0;
|
|
62
|
-
|
|
63
|
+
|
|
63
64
|
const ib = [
|
|
64
65
|
SYNC_SAGA_CONTEXT_ATOM,
|
|
66
|
+
data.sagaN,
|
|
65
67
|
payloadCount,
|
|
66
68
|
].join(' ');
|
|
67
69
|
|
|
@@ -88,6 +90,7 @@ export async function parseSyncSagaContextIb({
|
|
|
88
90
|
}
|
|
89
91
|
const [
|
|
90
92
|
atom,
|
|
93
|
+
sagaNStr,
|
|
91
94
|
payloadCountStr,
|
|
92
95
|
] = parts;
|
|
93
96
|
|
|
@@ -95,13 +98,19 @@ export async function parseSyncSagaContextIb({
|
|
|
95
98
|
throw new Error(`Atom mismatch. Expected ${SYNC_SAGA_CONTEXT_ATOM}. Got ${atom}. (E: 67d71fc0f8d04840b178652309f471f5)`);
|
|
96
99
|
}
|
|
97
100
|
|
|
101
|
+
if (!sagaNStr) { throw new Error(`invalid ib. second piece should be sagaN but is falsy (E: 081ed475aeb8fe25a66f60466b2e5826)`); }
|
|
102
|
+
const sagaN = parseInt(sagaNStr);
|
|
103
|
+
if (isNaN(sagaN)) {
|
|
104
|
+
throw new Error(`sagaNStr is not a number. (E: 3d6b580d5a48c5e03ecec288896e2826)`);
|
|
105
|
+
}
|
|
106
|
+
|
|
98
107
|
if (!payloadCountStr) { throw new Error(`invalid ib. second piece should be payloadCount but is falsy (E: 0bb7580793d800ca02227828a7294826)`); }
|
|
99
108
|
const payloadCount = parseInt(payloadCountStr);
|
|
100
109
|
if (isNaN(payloadCount)) {
|
|
101
110
|
throw new Error(`payloadCountStr is not a number. (E: 49457814282a44069871630987588722)`);
|
|
102
111
|
}
|
|
103
112
|
|
|
104
|
-
return { atom, payloadCount };
|
|
113
|
+
return { atom, sagaN, payloadCount };
|
|
105
114
|
} catch (error) {
|
|
106
115
|
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
107
116
|
throw error;
|
|
@@ -129,6 +138,9 @@ export async function createSyncSagaContext({
|
|
|
129
138
|
try {
|
|
130
139
|
if (logalot) { console.log(`${lc} starting... (I: 6b87bee313e811d1d2fc90e87fbec826)`); }
|
|
131
140
|
|
|
141
|
+
if (!sagaFrame.data) { throw new Error(`(UNEXPECTED) sagaFrame.data falsy? (E: 04c49b4cccba6842a8b52e4c6f570726)`); }
|
|
142
|
+
if (!sagaFrame.data.n && sagaFrame.data.n !== 0) { throw new Error(`(UNEXPECTED) sagaFrame.data.n falsy and not 0? (E: 45b508da64a8b28428b11765d684b826)`); }
|
|
143
|
+
|
|
132
144
|
const date = new Date();
|
|
133
145
|
const timestamp = getTimestamp(date);
|
|
134
146
|
const timestampMs = date.getMilliseconds();
|
|
@@ -136,6 +148,7 @@ export async function createSyncSagaContext({
|
|
|
136
148
|
const data: SyncSagaContextData_V1 = {
|
|
137
149
|
timestamp,
|
|
138
150
|
timestampMs,
|
|
151
|
+
sagaN: sagaFrame.data.n,
|
|
139
152
|
};
|
|
140
153
|
|
|
141
154
|
// Domain Payloads
|
|
@@ -215,20 +228,27 @@ export async function validateContextAndSagaFrame({ context }: { context: SyncSa
|
|
|
215
228
|
}
|
|
216
229
|
|
|
217
230
|
if (context.sagaFrame) {
|
|
218
|
-
|
|
231
|
+
const sagaFrameErrors =
|
|
232
|
+
await validateSyncSagaFrame({ sagaIbGib: context.sagaFrame });
|
|
233
|
+
sagaFrameErrors.forEach(x => errors.push(x));
|
|
219
234
|
} else {
|
|
220
235
|
errors.push(`context.sagaFrame is falsy. (E: b4edd88f4963f493789f83b29ba2df26)`);
|
|
221
236
|
}
|
|
222
237
|
|
|
223
|
-
//
|
|
224
|
-
|
|
238
|
+
// if this is already invalid, we could have intrinsic validation errors, which are a non-starter.
|
|
239
|
+
if (errors.length > 0) { return errors; /* <<<< returns early */ }
|
|
225
240
|
|
|
241
|
+
// validate the entire context graph intrinsically, including saga frame, stones, identity(s) (if applicable but not authentication, that will be done in a separate step)
|
|
226
242
|
|
|
227
|
-
// ensure the non-dto properties on the context object (i.e. props
|
|
243
|
+
// ~~ensure the non-dto properties on the context object (i.e. props
|
|
228
244
|
// that are not ib, gib, data, or rel8ns) match the data in the
|
|
229
|
-
// context object
|
|
245
|
+
// context object~~ NO. THIS WILL BE IN A SEPARATE FUNCTION.
|
|
246
|
+
// See `validateContextDomainPayloadIbGibs`
|
|
230
247
|
|
|
231
|
-
throw new Error(`not implemented (E: cb639658e1183fa6c8a4ebca023ba926)`);
|
|
248
|
+
// throw new Error(`not implemented (E: cb639658e1183fa6c8a4ebca023ba926)`);
|
|
249
|
+
|
|
250
|
+
console.error(`${lc} NAG ERROR MSG (NOT THROWN): not fully implemented yet (E: d574d85cb578637648ed403857f7a826)`);
|
|
251
|
+
return [];
|
|
232
252
|
} catch (error) {
|
|
233
253
|
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
234
254
|
throw error;
|
|
@@ -239,7 +259,9 @@ export async function validateContextAndSagaFrame({ context }: { context: SyncSa
|
|
|
239
259
|
|
|
240
260
|
|
|
241
261
|
/**
|
|
242
|
-
* validates
|
|
262
|
+
* validates {@link SyncSagaContextIbGib_V1.payloadIbGibsDomain} intrinsically,
|
|
263
|
+
* and ensures that these payloadIbGibs also match the expected addrs in
|
|
264
|
+
* {@link SyncSagaContextData_V1}[{@link SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN}].
|
|
243
265
|
*
|
|
244
266
|
* @returns empty array if valid, else validation errors
|
|
245
267
|
*/
|
|
@@ -248,6 +270,44 @@ export async function validateContextDomainPayloadIbGibs({ context }: { context:
|
|
|
248
270
|
try {
|
|
249
271
|
if (logalot) { console.log(`${lc} starting... (I: 9f9fe835bcc80c75aa7fd6d887fc0826)`); }
|
|
250
272
|
console.error(`${lc} NAG MESSAGE (NOT THROWN). not implemented (E: bfe02ab36a227291a8f17ffc08f2ef26)`)
|
|
273
|
+
return [];
|
|
274
|
+
} catch (error) {
|
|
275
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
276
|
+
throw error;
|
|
277
|
+
} finally {
|
|
278
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* move to sync-peer-helpers.mts as a pure function?
|
|
284
|
+
*/
|
|
285
|
+
export async function authenticateContext({ context }: { context: SyncSagaContextIbGib_V1 }): Promise<string[]> {
|
|
286
|
+
const lc = `[${authenticateContext.name}]`;
|
|
287
|
+
try {
|
|
288
|
+
if (logalot) { console.log(`${lc} starting... (I: 2677a482dfa873dcd1aa04a3031ff826)`); }
|
|
289
|
+
|
|
290
|
+
console.error(`${lc} NAG ERROR (NOT THROWN): not implemented. // todo: authenticate (v1 must have this after we get merge logic workflow going) (E: bc3a78f2dab18ab64c36d055a4b50526)`);
|
|
291
|
+
|
|
292
|
+
return [];
|
|
293
|
+
} catch (error) {
|
|
294
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
295
|
+
throw error;
|
|
296
|
+
} finally {
|
|
297
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* move to sync-peer-helpers.mts as a pure function?
|
|
303
|
+
*/
|
|
304
|
+
export async function authorizeContext({ context }: { context: SyncSagaContextIbGib_V1 }): Promise<string[]> {
|
|
305
|
+
const lc = `[${authorizeContext.name}]`;
|
|
306
|
+
try {
|
|
307
|
+
if (logalot) { console.log(`${lc} starting... (I: 48c918b41ceec0cd489ca3b8819e6826)`); }
|
|
308
|
+
|
|
309
|
+
console.error(`${lc} NAG ERROR (NOT THROWN): not implemented. authorize business logic (v1 must have this, but later when we are working on admin vs. student)(E: bc3a78f2dab18ab64c36d055a4b50526)`);
|
|
310
|
+
|
|
251
311
|
return [];
|
|
252
312
|
} catch (error) {
|
|
253
313
|
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
@@ -11,6 +11,10 @@ import { SYNC_SAGA_CONTEXT_ATOM } from './sync-saga-context-constants.mjs';
|
|
|
11
11
|
|
|
12
12
|
export interface SyncSagaContextIb_V1 {
|
|
13
13
|
atom: typeof SYNC_SAGA_CONTEXT_ATOM;
|
|
14
|
+
/**
|
|
15
|
+
* sagaFrame.data.n value
|
|
16
|
+
*/
|
|
17
|
+
sagaN: number;
|
|
14
18
|
/**
|
|
15
19
|
* simple metadata count of data["@payloadAddrsDomain"]
|
|
16
20
|
*/
|
|
@@ -21,6 +25,10 @@ export interface SyncSagaContextIb_V1 {
|
|
|
21
25
|
* Data payload for the Sync Saga Context.
|
|
22
26
|
*/
|
|
23
27
|
export interface SyncSagaContextData_V1 extends IbGibData_V1 {
|
|
28
|
+
/**
|
|
29
|
+
* context's sagaFrame.data.n value
|
|
30
|
+
*/
|
|
31
|
+
sagaN: number;
|
|
24
32
|
/**
|
|
25
33
|
* Payload data addresses for DOMAIN ibGibs (Timeline frames, user content).
|
|
26
34
|
* Soft-linked via data property to avoid hard-linking graph dependencies.
|
|
@@ -35,7 +43,7 @@ export interface SyncSagaContextData_V1 extends IbGibData_V1 {
|
|
|
35
43
|
export interface SyncSagaContextRel8ns_V1 extends IbGibRel8ns_V1 {
|
|
36
44
|
/**
|
|
37
45
|
* The primary Saga Frame being transported (Init, Ack, Delta, etc.).
|
|
38
|
-
*
|
|
46
|
+
*
|
|
39
47
|
* Should be a single addr.
|
|
40
48
|
*/
|
|
41
49
|
sagaFrame: IbGibAddr[];
|
|
@@ -43,9 +51,9 @@ export interface SyncSagaContextRel8ns_V1 extends IbGibRel8ns_V1 {
|
|
|
43
51
|
/**
|
|
44
52
|
* The Ephemeral Session Keystone Identity used for this saga.
|
|
45
53
|
* Required for validating the saga frame signature.
|
|
46
|
-
*
|
|
54
|
+
*
|
|
47
55
|
* ## notes
|
|
48
|
-
*
|
|
56
|
+
*
|
|
49
57
|
* This will be different for the sender and receiver, yes? hmm...
|
|
50
58
|
* I think I need to put "sender" or "receiver" in the session keystone ib.
|
|
51
59
|
*/
|
|
@@ -59,7 +67,7 @@ export interface SyncSagaContextRel8ns_V1 extends IbGibRel8ns_V1 {
|
|
|
59
67
|
export interface SyncSagaContextIbGib_V1 extends IbGib_V1<SyncSagaContextData_V1, SyncSagaContextRel8ns_V1> {
|
|
60
68
|
/**
|
|
61
69
|
* Domain ibgibs - OUTBOUND only.
|
|
62
|
-
*
|
|
70
|
+
*
|
|
63
71
|
* For inbound, the domain payload ibgibs are streamed via observable in the
|
|
64
72
|
* peer.
|
|
65
73
|
*/
|
|
@@ -67,7 +75,7 @@ export interface SyncSagaContextIbGib_V1 extends IbGib_V1<SyncSagaContextData_V1
|
|
|
67
75
|
|
|
68
76
|
/**
|
|
69
77
|
* Reference to the actual sync saga frame that this context conveys.
|
|
70
|
-
*
|
|
78
|
+
*
|
|
71
79
|
* This frame's addr should be {@link SyncSagaContextRel8ns_V1.sagaFrame}.
|
|
72
80
|
*/
|
|
73
81
|
sagaFrame: SyncIbGib_V1;
|