@ibgib/core-gib 0.1.22 → 0.1.23
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 +8 -0
- package/dist/common/other/graph-helper.d.mts.map +1 -1
- package/dist/common/other/graph-helper.mjs +31 -1
- package/dist/common/other/graph-helper.mjs.map +1 -1
- package/dist/sync/sync-conflict.respec.mjs +12 -11
- package/dist/sync/sync-conflict.respec.mjs.map +1 -1
- package/dist/sync/sync-constants.d.mts +14 -4
- package/dist/sync/sync-constants.d.mts.map +1 -1
- package/dist/sync/sync-constants.mjs +15 -3
- package/dist/sync/sync-constants.mjs.map +1 -1
- package/dist/sync/sync-helpers.d.mts +22 -15
- package/dist/sync/sync-helpers.d.mts.map +1 -1
- package/dist/sync/sync-helpers.mjs +159 -90
- package/dist/sync/sync-helpers.mjs.map +1 -1
- package/dist/sync/sync-innerspace-constants.respec.mjs +11 -10
- package/dist/sync/sync-innerspace-constants.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs +11 -10
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs +11 -10
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs +12 -10
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-partial-update.respec.mjs +14 -10
- package/dist/sync/sync-innerspace-partial-update.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace.respec.mjs +12 -10
- package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.d.mts +0 -15
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts +15 -14
- 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 +9 -55
- 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 +16 -0
- package/dist/sync/sync-peer/sync-peer-types.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.d.mts +39 -5
- package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.mjs +141 -4
- package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +22 -3
- 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 +104 -31
- 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 +5 -0
- package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.d.mts +74 -70
- package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.mjs +475 -527
- package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
- package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts +105 -22
- package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts.map +1 -1
- package/dist/sync/sync-types.d.mts +56 -88
- package/dist/sync/sync-types.d.mts.map +1 -1
- package/dist/sync/sync-types.mjs +5 -0
- package/dist/sync/sync-types.mjs.map +1 -1
- package/dist/timeline/timeline-api.d.mts.map +1 -1
- package/dist/timeline/timeline-api.mjs +15 -8
- package/dist/timeline/timeline-api.mjs.map +1 -1
- package/package.json +1 -1
- package/src/common/other/graph-helper.mts +26 -1
- package/src/sync/sync-conflict.respec.mts +12 -11
- package/src/sync/sync-constants.mts +15 -4
- package/src/sync/sync-helpers.mts +167 -95
- package/src/sync/sync-innerspace-constants.respec.mts +11 -10
- package/src/sync/sync-innerspace-deep-updates.respec.mts +11 -10
- package/src/sync/sync-innerspace-dest-ahead.respec.mts +11 -10
- package/src/sync/sync-innerspace-multiple-timelines.respec.mts +12 -10
- package/src/sync/sync-innerspace-partial-update.respec.mts +14 -12
- package/src/sync/sync-innerspace.respec.mts +12 -10
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.mts +0 -15
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +16 -65
- package/src/sync/sync-peer/sync-peer-types.mts +17 -0
- package/src/sync/sync-peer/sync-peer-v1.mts +141 -8
- package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +116 -37
- package/src/sync/sync-saga-context/sync-saga-context-types.mts +5 -0
- package/src/sync/sync-saga-coordinator.mts +525 -617
- package/src/sync/sync-saga-message/sync-saga-message-types.mts +106 -22
- package/src/sync/sync-types.mts +59 -101
- package/src/timeline/timeline-api.mts +17 -10
|
@@ -3,26 +3,18 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { extractErrorMsg, unique } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
6
|
-
import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
|
|
7
6
|
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
7
|
+
import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
|
|
8
8
|
|
|
9
9
|
import { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';
|
|
10
|
-
import { SYNC_ATOM, } from '../../sync-constants.mjs';
|
|
11
10
|
import { IbGibSpaceAny } from '../../../witness/space/space-base-v1.mjs';
|
|
12
11
|
import { SyncPeer_V1 } from '../sync-peer-v1.mjs';
|
|
13
12
|
import { getFromSpace, putInSpace } from '../../../witness/space/space-helper.mjs';
|
|
14
13
|
import { SyncSagaContextIbGib_V1, } from '../../sync-saga-context/sync-saga-context-types.mjs';
|
|
15
|
-
import { createSyncSagaContext } from '../../sync-saga-context/sync-saga-context-helpers.mjs';
|
|
16
|
-
import { SubjectWitness } from '../../../common/pubsub/subject/subject-types.mjs';
|
|
17
|
-
import { newupSubject } from '../../../common/pubsub/subject/subject-helper.mjs';
|
|
18
14
|
import { SyncPeerInnerspaceData_V1, SyncPeerInnerspaceIbGib_V1, SyncPeerInnerspaceOptions, SyncPeerInnerspaceRel8ns_V1 } from './sync-peer-innerspace-types.mjs';
|
|
19
|
-
import { SYNC_PEER_INNERSPACE_ATOM } from './sync-peer-innerspace-constants.mjs';
|
|
20
|
-
import { SyncPeerData_V1, SyncPeerRel8ns_V1 } from '../sync-peer-types.mjs';
|
|
21
15
|
import { MetaspaceService } from '../../../witness/space/metaspace/metaspace-types.mjs';
|
|
22
16
|
import { SyncSagaCoordinator } from '../../sync-saga-coordinator.mjs';
|
|
23
|
-
import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
|
|
24
17
|
import { IbGibSpaceResultData } from '../../../witness/space/space-types.mjs';
|
|
25
|
-
import { getSyncSagaDependencyGraph } from '../../sync-helpers.mjs';
|
|
26
18
|
|
|
27
19
|
|
|
28
20
|
const logalot = GLOBAL_LOG_A_LOT || true;
|
|
@@ -39,43 +31,41 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1 implements SyncPeerInners
|
|
|
39
31
|
|
|
40
32
|
protected lc: string = `[${SyncPeerInnerspace_V1.name}]`;
|
|
41
33
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
34
|
+
/**
|
|
35
|
+
* specific to innerspace
|
|
36
|
+
*/
|
|
37
|
+
protected receiverCoordinator: SyncSagaCoordinator;
|
|
38
|
+
/**
|
|
39
|
+
* specific to innerspace
|
|
40
|
+
*/
|
|
41
|
+
protected receiverMetaspace: MetaspaceService;
|
|
42
|
+
public receiverSpace: IbGibSpaceAny;
|
|
43
|
+
public receiverTempSpace: IbGibSpaceAny;
|
|
50
44
|
|
|
51
45
|
override get classname(): string {
|
|
52
46
|
return SyncPeerInnerspace_V1.name;
|
|
53
47
|
}
|
|
54
48
|
|
|
55
49
|
constructor(
|
|
50
|
+
senderSpace: IbGibSpaceAny,
|
|
51
|
+
senderTempSpace: IbGibSpaceAny,
|
|
56
52
|
opts: SyncPeerInnerspaceOptions,
|
|
57
53
|
initialData: SyncPeerInnerspaceData_V1,
|
|
58
54
|
initialRel8ns?: SyncPeerInnerspaceRel8ns_V1,
|
|
59
55
|
) {
|
|
60
|
-
super(initialData, initialRel8ns);
|
|
56
|
+
super(senderSpace, senderTempSpace, initialData, initialRel8ns);
|
|
61
57
|
const {
|
|
62
|
-
|
|
58
|
+
receiverCoordinator,
|
|
63
59
|
receiverMetaspace, receiverSpace, receiverTempSpace
|
|
64
60
|
} = opts;
|
|
65
61
|
|
|
66
|
-
this.senderSpace = senderSpace;
|
|
67
|
-
this.senderTempSpace = senderTempSpace;
|
|
68
62
|
this.receiverCoordinator = receiverCoordinator;
|
|
69
63
|
this.receiverMetaspace = receiverMetaspace;
|
|
70
64
|
this.receiverSpace = receiverSpace;
|
|
71
65
|
this.receiverTempSpace = receiverTempSpace;
|
|
72
66
|
}
|
|
73
67
|
|
|
74
|
-
async
|
|
75
|
-
this.payloadIbGibsDomainReceived$ = await newupSubject<IbGib_V1>();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
private async ensureReceiverTempSpace(): Promise<IbGibSpaceAny> {
|
|
68
|
+
protected override async ensureReceiverTempSpace(): Promise<IbGibSpaceAny> {
|
|
79
69
|
if (!this.receiverTempSpace) {
|
|
80
70
|
const { receiverMetaspace } = this;
|
|
81
71
|
|
|
@@ -96,28 +86,6 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1 implements SyncPeerInners
|
|
|
96
86
|
return this.receiverTempSpace;
|
|
97
87
|
}
|
|
98
88
|
|
|
99
|
-
protected async getLocalIbGib(addr: string): Promise<IbGib_V1 | undefined> {
|
|
100
|
-
const lc = `${this.lc}[${this.getLocalIbGib.name}]`;
|
|
101
|
-
try {
|
|
102
|
-
if (logalot) { console.log(`${lc} starting... (I: 27b248cb9801eeb2386b71485389a826)`); }
|
|
103
|
-
|
|
104
|
-
console.warn(`${lc} possibly a bottleneck here, getLocalIbGib only gets a single ibgib... (W: 2fd448a435480e6b128f6b8bcbef4826)`);
|
|
105
|
-
|
|
106
|
-
const resGet = await getFromSpace({ space: this.senderSpace, addr });
|
|
107
|
-
|
|
108
|
-
if (resGet.success && resGet.ibGibs && resGet.ibGibs.length === 1) {
|
|
109
|
-
const ibGib = resGet.ibGibs[0];
|
|
110
|
-
return ibGib;
|
|
111
|
-
} else {
|
|
112
|
-
throw new Error(`couldn't get addr (${addr}) from local space ${this.senderSpace}. reason: ${resGet.errorMsg ?? 'unknown error (E: 926ef8bf4fcc299ab89dba34ea691a26)'} (E: d8a89807e471d3f8b938ab21df44cb26)`);
|
|
113
|
-
}
|
|
114
|
-
} catch (error) {
|
|
115
|
-
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
116
|
-
throw error;
|
|
117
|
-
} finally {
|
|
118
|
-
if (logalot) { console.log(`${lc} complete.`); }
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
89
|
|
|
122
90
|
protected async push(addrs: IbGibAddr[]): Promise<void> {
|
|
123
91
|
const lc = `${this.lc}[${this.push.name}]`;
|
|
@@ -168,23 +136,6 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1 implements SyncPeerInners
|
|
|
168
136
|
if (!context.rel8ns.sagaFrame) { throw new Error(`(UNEXPECTED) context.rel8ns.sagaFrame falsy? (E: ac06782ad538be406882605f0a83aa26)`); }
|
|
169
137
|
if (!context.sagaFrame) { throw new Error(`(UNEXPECTED) context.sagaFrame falsy? (E: 79cd98a6d9b88a591f4596c8bc58ff26)`); }
|
|
170
138
|
|
|
171
|
-
// validate the context, sagaFrame, and identity(s)
|
|
172
|
-
// persist the context, sagaframe, identity(s) ONLY in the receiver's durable space
|
|
173
|
-
// if sending domain ibgibs...
|
|
174
|
-
// verify the domain ibgibs intrinsically.
|
|
175
|
-
// persist the domain ibgibs in the receiver's temp space (push all addrs?)
|
|
176
|
-
// await until all domain ibgibs are in receiver's temp space
|
|
177
|
-
// process the context with the receiver's coordinator to get a new response context
|
|
178
|
-
// analyze the response context
|
|
179
|
-
// validate context intrinsically
|
|
180
|
-
// validate return identity if present
|
|
181
|
-
// persist the response context's dependency graph (context, saga frame and msg(s), identities)
|
|
182
|
-
// if response has payload domain ibgibs,
|
|
183
|
-
// spin off...
|
|
184
|
-
// pull domain ibgibs to local temp space
|
|
185
|
-
// publish domain ibgibs to observable
|
|
186
|
-
// when all domain ibgibs are pulled, publish complete to the observable
|
|
187
|
-
// return resulting context ibgib (which the caller should get BEFORE the domain ibgibs observable completes)
|
|
188
139
|
|
|
189
140
|
|
|
190
141
|
throw new Error(`not implemented (E: 72840872e252d9f7380f1998b5a0c826)`);
|
|
@@ -7,6 +7,7 @@ import { SubjectWitness } from '../../common/pubsub/subject/subject-types.mjs';
|
|
|
7
7
|
|
|
8
8
|
import { SyncSagaContextData_V1, SyncSagaContextIbGib_V1, SyncSagaContextRel8ns_V1 } from '../sync-saga-context/sync-saga-context-types.mjs';
|
|
9
9
|
import { Witness_V1 } from '../../witness/witness-types.mjs';
|
|
10
|
+
import { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Data for the SyncPeer witness.
|
|
@@ -45,6 +46,22 @@ export interface SyncPeerWitness extends Witness_V1<
|
|
|
45
46
|
> {
|
|
46
47
|
// witness(arg: SyncSagaContextIbGib_V1): Promise<SyncSagaContextIbGib_V1 | undefined>;
|
|
47
48
|
|
|
49
|
+
/**
|
|
50
|
+
* sender's durable space.
|
|
51
|
+
*
|
|
52
|
+
* will store control ibgibs (context, sync saga ibgib, control msg stones)
|
|
53
|
+
* here (and in {@link senderTempSpace}) throughout the process for audit trail.
|
|
54
|
+
*/
|
|
55
|
+
senderSpace: IbGibSpaceAny;
|
|
56
|
+
/**
|
|
57
|
+
* sender's temporary space for the entire sync transaction.
|
|
58
|
+
*
|
|
59
|
+
* In addition to control ibgibs which are stored in both temp and durable
|
|
60
|
+
* spaces, this temp space will be where domain ibgibs are stored that are
|
|
61
|
+
* received/created throughout the transaction until commit.
|
|
62
|
+
*/
|
|
63
|
+
senderTempSpace: IbGibSpaceAny;
|
|
64
|
+
|
|
48
65
|
/**
|
|
49
66
|
* Observable for streaming large domain payloads asynchronously.
|
|
50
67
|
*
|
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
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
|
|
3
15
|
*/
|
|
4
16
|
|
|
5
17
|
import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
6
18
|
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
7
19
|
import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
|
|
8
|
-
import {
|
|
20
|
+
import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
|
|
21
|
+
import { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';
|
|
9
22
|
|
|
10
23
|
import { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';
|
|
11
24
|
import { SYNC_MSG_REL8N_NAME, SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN } from '../sync-constants.mjs';
|
|
25
|
+
import { SubjectWitness } from '../../common/pubsub/subject/subject-types.mjs';
|
|
12
26
|
import { SyncSagaContextIbGib_V1 } from '../sync-saga-context/sync-saga-context-types.mjs';
|
|
13
27
|
import { SyncPeerData_V1, SyncPeerRel8ns_V1, SyncPeerWitness } from './sync-peer-types.mjs';
|
|
14
28
|
import { LightWitnessBase_V1 } from '../../witness/light-witness-base-v1.mjs';
|
|
15
|
-
import {
|
|
29
|
+
import { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';
|
|
30
|
+
import { newupSubject } from '../../common/pubsub/subject/subject-helper.mjs';
|
|
31
|
+
import { validateContext } from '../sync-saga-context/sync-saga-context-helpers.mjs';
|
|
32
|
+
import { getFromSpace } from '../../witness/space/space-helper.mjs';
|
|
16
33
|
|
|
17
34
|
const logalot = GLOBAL_LOG_A_LOT || true;
|
|
18
35
|
const logalotControlDomain = true;
|
|
@@ -33,7 +50,9 @@ export abstract class SyncPeer_V1 extends LightWitnessBase_V1<SyncPeerData_V1, S
|
|
|
33
50
|
|
|
34
51
|
protected lc: string = `[${SyncPeer_V1.name}]`;
|
|
35
52
|
|
|
36
|
-
|
|
53
|
+
public senderSpace: IbGibSpaceAny;
|
|
54
|
+
public senderTempSpace: IbGibSpaceAny;
|
|
55
|
+
public payloadIbGibsDomainReceived$!: SubjectWitness<IbGib_V1>;
|
|
37
56
|
|
|
38
57
|
get classname(): string {
|
|
39
58
|
if (!this.data) { throw new Error(`(UNEXPECTED) this.data falsy? (E: 1ab1841e9338b54f3aa615fa37024826)`); }
|
|
@@ -41,33 +60,84 @@ export abstract class SyncPeer_V1 extends LightWitnessBase_V1<SyncPeerData_V1, S
|
|
|
41
60
|
return this.data.classname;
|
|
42
61
|
}
|
|
43
62
|
|
|
44
|
-
constructor(initialData: SyncPeerData_V1, initialRel8ns?: SyncPeerRel8ns_V1) {
|
|
63
|
+
constructor(senderSpace: IbGibSpaceAny, senderTempSpace: IbGibSpaceAny, initialData: SyncPeerData_V1, initialRel8ns?: SyncPeerRel8ns_V1) {
|
|
45
64
|
super(initialData, initialRel8ns);
|
|
65
|
+
this.senderSpace = senderSpace;
|
|
66
|
+
this.senderTempSpace = senderTempSpace;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async initialize(): Promise<void> {
|
|
70
|
+
this.payloadIbGibsDomainReceived$ = await newupSubject<IbGib_V1>();
|
|
46
71
|
}
|
|
72
|
+
|
|
73
|
+
protected abstract ensureReceiverTempSpace(): Promise<IbGibSpaceAny>;
|
|
74
|
+
|
|
47
75
|
/**
|
|
48
76
|
* Witness the synchronization context (Send/Receive).
|
|
49
77
|
*
|
|
78
|
+
* At this point in code, we are sending the context OUTGOING. The {@link context} should
|
|
79
|
+
* have a fully populated {@link SyncSagaContextIbGib_V1.sagaFrame}
|
|
80
|
+
*
|
|
50
81
|
* @param arg The OUTGOING context (Request).
|
|
51
82
|
* @returns The INCOMING context (Response), or undefined if failed/empty.
|
|
52
83
|
*/
|
|
53
|
-
async witness(
|
|
84
|
+
override async witness(context: SyncSagaContextIbGib_V1): Promise<SyncSagaContextIbGib_V1 | undefined> {
|
|
54
85
|
const lc = `${this.lc}[${this.witness.name}]`;
|
|
55
86
|
try {
|
|
56
87
|
if (logalot) { console.log(`${lc} starting...`); }
|
|
57
88
|
|
|
58
89
|
if (logalot) { console.log(`${lc} starting...`); }
|
|
59
90
|
|
|
91
|
+
// validate, authenticate, and authorize the context, sagaFrame, and identity(s)
|
|
92
|
+
const validationErrors = await validateContext({ context });
|
|
93
|
+
if (validationErrors.length > 0) {
|
|
94
|
+
throw new Error(`invalid context received. validationErrors: ${validationErrors} (E: 8b34c875c968af29bc433138e57a7826)`);
|
|
95
|
+
}
|
|
96
|
+
const authenticationErrors = await this.authenticateContext({ context });
|
|
97
|
+
if (authenticationErrors.length > 0) {
|
|
98
|
+
throw new Error(`invalid context authentication. authenticationErrors: ${authenticationErrors} (E: da89da5ee1269aeb78952d475d607526)`);
|
|
99
|
+
}
|
|
100
|
+
const authorizationErrors = await this.authorizeContext({ context });
|
|
101
|
+
if (authorizationErrors.length > 0) {
|
|
102
|
+
throw new Error(`invalid context authorization. authorizationErrors: ${authorizationErrors} (E: 8ddc284a758cf10ba829334c1babb826)`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// at this point, we have a valid, authenticated, authorized context
|
|
106
|
+
|
|
107
|
+
// persist the context, sagaframe, identity(s) ONLY in the receiver's durable space
|
|
108
|
+
// if sending domain ibgibs...
|
|
109
|
+
// verify the domain ibgibs intrinsically.
|
|
110
|
+
// persist the domain ibgibs in the receiver's temp space (push all addrs?)
|
|
111
|
+
// await until all domain ibgibs are in receiver's temp space
|
|
112
|
+
// process the context with the receiver's coordinator to get a new response context
|
|
113
|
+
// analyze the response context
|
|
114
|
+
// validate context intrinsically
|
|
115
|
+
// validate return identity if present
|
|
116
|
+
// persist the response context's dependency graph (context, saga frame and msg(s), identities)
|
|
117
|
+
// if response has payload domain ibgibs,
|
|
118
|
+
// spin off...
|
|
119
|
+
// pull domain ibgibs to local temp space
|
|
120
|
+
// publish domain ibgibs to observable
|
|
121
|
+
// when all domain ibgibs are pulled, publish complete to the observable
|
|
122
|
+
// return resulting context ibgib (which the caller should get BEFORE the domain ibgibs observable completes)
|
|
123
|
+
|
|
60
124
|
// 1. PUSH: Ensure Request Data is available on Receiver
|
|
61
|
-
await this.pushContextGraph({ context
|
|
125
|
+
await this.pushContextGraph({ context }); // ???
|
|
62
126
|
|
|
63
127
|
// 2. EXECUTE: Trigger Remote Processing
|
|
64
|
-
const response = await this.sendContextRequest(
|
|
128
|
+
const response = await this.sendContextRequest(context);
|
|
65
129
|
|
|
66
130
|
if (!response) {
|
|
67
131
|
if (logalot) { console.log(`${lc} No response from peer.`); }
|
|
68
132
|
return undefined;
|
|
69
133
|
}
|
|
70
134
|
|
|
135
|
+
// at this point, we have received the response context, sync saga
|
|
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
|
|
71
141
|
// 3. PULL: Ensure Response Data is available on Sender (Local)
|
|
72
142
|
await this.pullContextGraph({ context: response });
|
|
73
143
|
|
|
@@ -100,6 +170,46 @@ export abstract class SyncPeer_V1 extends LightWitnessBase_V1<SyncPeerData_V1, S
|
|
|
100
170
|
*/
|
|
101
171
|
protected abstract pull(addrs: IbGibAddr[]): Promise<void>;
|
|
102
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)`);
|
|
184
|
+
|
|
185
|
+
return [];
|
|
186
|
+
} catch (error) {
|
|
187
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
188
|
+
throw error;
|
|
189
|
+
} finally {
|
|
190
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* move to sync-peer-helpers.mts as a pure function?
|
|
196
|
+
*/
|
|
197
|
+
protected async authorizeContext({ context }: { context: SyncSagaContextIbGib_V1 }): Promise<string[]> {
|
|
198
|
+
const lc = `${this.lc}[${this.authorizeContext.name}]`;
|
|
199
|
+
try {
|
|
200
|
+
if (logalot) { console.log(`${lc} starting... (I: 48c918b41ceec0cd489ca3b8819e6826)`); }
|
|
201
|
+
|
|
202
|
+
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)`);
|
|
203
|
+
|
|
204
|
+
return [];
|
|
205
|
+
} catch (error) {
|
|
206
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
207
|
+
throw error;
|
|
208
|
+
} finally {
|
|
209
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
103
213
|
/**
|
|
104
214
|
* Helper to orchestrate the PUSH of a Context's dependency graph.
|
|
105
215
|
*/
|
|
@@ -239,6 +349,29 @@ export abstract class SyncPeer_V1 extends LightWitnessBase_V1<SyncPeerData_V1, S
|
|
|
239
349
|
/**
|
|
240
350
|
* Abstract accessor to get an IbGib from the Local space/store.
|
|
241
351
|
* Needed for inspecting rela8ns during the graph walk.
|
|
352
|
+
*
|
|
353
|
+
* Default implementation simply looks in senderSpace
|
|
242
354
|
*/
|
|
243
|
-
protected
|
|
355
|
+
protected async getLocalIbGib(addr: string): Promise<IbGib_V1 | undefined> {
|
|
356
|
+
const lc = `${this.lc}[${this.getLocalIbGib.name}]`;
|
|
357
|
+
try {
|
|
358
|
+
if (logalot) { console.log(`${lc} starting... (I: 27b248cb9801eeb2386b71485389a826)`); }
|
|
359
|
+
|
|
360
|
+
console.warn(`${lc} possibly a bottleneck here, getLocalIbGib only gets a single ibgib... (W: 2fd448a435480e6b128f6b8bcbef4826)`);
|
|
361
|
+
|
|
362
|
+
const resGet = await getFromSpace({ space: this.senderSpace, addr });
|
|
363
|
+
|
|
364
|
+
if (resGet.success && resGet.ibGibs && resGet.ibGibs.length === 1) {
|
|
365
|
+
const ibGib = resGet.ibGibs[0];
|
|
366
|
+
return ibGib;
|
|
367
|
+
} else {
|
|
368
|
+
throw new Error(`couldn't get addr (${addr}) from local space ${this.senderSpace}. reason: ${resGet.errorMsg ?? 'unknown error (E: 926ef8bf4fcc299ab89dba34ea691a26)'} (E: d8a89807e471d3f8b938ab21df44cb26)`);
|
|
369
|
+
}
|
|
370
|
+
} catch (error) {
|
|
371
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
372
|
+
throw error;
|
|
373
|
+
} finally {
|
|
374
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
375
|
+
}
|
|
376
|
+
}
|
|
244
377
|
}
|
|
@@ -7,14 +7,20 @@ import { Factory_V1 } from '@ibgib/ts-gib/dist/V1/factory.mjs';
|
|
|
7
7
|
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
8
8
|
import { IbGib_V1, } from '@ibgib/ts-gib/dist/V1/types.mjs';
|
|
9
9
|
import { Ib } from '@ibgib/ts-gib/dist/types.mjs';
|
|
10
|
+
import { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';
|
|
10
11
|
|
|
12
|
+
import { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';
|
|
11
13
|
import { SYNC_SAGA_CONTEXT_ATOM } from './sync-saga-context-constants.mjs';
|
|
12
14
|
import { SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN } from '../sync-constants.mjs';
|
|
13
15
|
import {
|
|
14
|
-
SyncSagaContextData_V1, SyncSagaContextIbGib_V1,
|
|
15
|
-
|
|
16
|
+
SyncSagaContextData_V1, SyncSagaContextIbGib_V1, SyncSagaContextIb_V1,
|
|
17
|
+
SyncSagaContextRel8ns_V1,
|
|
16
18
|
} from './sync-saga-context-types.mjs';
|
|
17
|
-
import {
|
|
19
|
+
import { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';
|
|
20
|
+
import { putInSpace, registerNewIbGib } from '../../witness/space/space-helper.mjs';
|
|
21
|
+
import { SyncIbGib_V1 } from '../sync-types.mjs';
|
|
22
|
+
|
|
23
|
+
const logalot = GLOBAL_LOG_A_LOT;
|
|
18
24
|
|
|
19
25
|
/**
|
|
20
26
|
* Options for creating a SyncSagaContext ibgib.
|
|
@@ -23,7 +29,7 @@ export interface CreateSyncSagaContextOptions {
|
|
|
23
29
|
/**
|
|
24
30
|
* The main saga frame (Init, Ack, etc.).
|
|
25
31
|
*/
|
|
26
|
-
sagaFrame:
|
|
32
|
+
sagaFrame: SyncIbGib_V1;
|
|
27
33
|
/**
|
|
28
34
|
* Session identity keystones.
|
|
29
35
|
*/
|
|
@@ -33,6 +39,11 @@ export interface CreateSyncSagaContextOptions {
|
|
|
33
39
|
* payloads to send, e.g., in a Delta frame.
|
|
34
40
|
*/
|
|
35
41
|
payloadIbGibsDomain?: IbGib_V1[];
|
|
42
|
+
/**
|
|
43
|
+
* we persist the context in the local/sender space (relative to our
|
|
44
|
+
* execution POV) right when we create it.
|
|
45
|
+
*/
|
|
46
|
+
localSpace: IbGibSpaceAny;
|
|
36
47
|
}
|
|
37
48
|
|
|
38
49
|
/**
|
|
@@ -98,53 +109,121 @@ export async function parseSyncSagaContextIb({
|
|
|
98
109
|
}
|
|
99
110
|
|
|
100
111
|
/**
|
|
101
|
-
* Creates
|
|
112
|
+
* Creates new SyncSagaContext stone. Puts/registers in {@link localSpace}
|
|
113
|
+
* immediately after creation.
|
|
102
114
|
*
|
|
103
115
|
* @returns The context ibGib.
|
|
116
|
+
*
|
|
117
|
+
* ## notes
|
|
118
|
+
*
|
|
119
|
+
* the other ibgibs that are related to this context stone should already be
|
|
120
|
+
* put/registered in {@link localSpace}.
|
|
104
121
|
*/
|
|
105
122
|
export async function createSyncSagaContext({
|
|
106
123
|
sagaFrame,
|
|
107
124
|
sessionKeystones,
|
|
108
125
|
payloadIbGibsDomain,
|
|
126
|
+
localSpace,
|
|
109
127
|
}: CreateSyncSagaContextOptions): Promise<SyncSagaContextIbGib_V1> {
|
|
128
|
+
const lc = `[${createSyncSagaContext.name}]`;
|
|
129
|
+
try {
|
|
130
|
+
if (logalot) { console.log(`${lc} starting... (I: 6b87bee313e811d1d2fc90e87fbec826)`); }
|
|
131
|
+
|
|
132
|
+
const date = new Date();
|
|
133
|
+
const timestamp = getTimestamp(date);
|
|
134
|
+
const timestampMs = date.getMilliseconds();
|
|
135
|
+
|
|
136
|
+
const data: SyncSagaContextData_V1 = {
|
|
137
|
+
timestamp,
|
|
138
|
+
timestampMs,
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// Domain Payloads
|
|
142
|
+
const payloadAddrsDomain = payloadIbGibsDomain ?
|
|
143
|
+
payloadIbGibsDomain?.map(x => getIbGibAddr({ ibGib: x })) :
|
|
144
|
+
undefined;
|
|
145
|
+
if (payloadAddrsDomain && payloadAddrsDomain.length > 0) {
|
|
146
|
+
data[SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN] = payloadAddrsDomain;
|
|
147
|
+
}
|
|
110
148
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
149
|
+
// rel8ns should always have saga frame, sometimes have keystone
|
|
150
|
+
const rel8ns: SyncSagaContextRel8ns_V1 = {
|
|
151
|
+
sagaFrame: [getIbGibAddr({ ibGib: sagaFrame })],
|
|
152
|
+
};
|
|
153
|
+
if (sessionKeystones && sessionKeystones.length > 0) {
|
|
154
|
+
rel8ns.sessionKeystone = sessionKeystones.map(x => getIbGibAddr({ ibGib: x }));
|
|
155
|
+
}
|
|
114
156
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
157
|
+
// Generate standard ib
|
|
158
|
+
const ib = await getSyncSagaContextIb({ data });
|
|
159
|
+
|
|
160
|
+
const contextIbGib = await Factory_V1.stone<SyncSagaContextData_V1, SyncSagaContextRel8ns_V1>({
|
|
161
|
+
parentPrimitiveIb: SYNC_SAGA_CONTEXT_ATOM,
|
|
162
|
+
ib,
|
|
163
|
+
data,
|
|
164
|
+
rel8ns,
|
|
165
|
+
}) as SyncSagaContextIbGib_V1;
|
|
166
|
+
|
|
167
|
+
// put/register immediately. Note that contextIbGib at this point is
|
|
168
|
+
// pure DTO, i.e., only ib, gib, data, rel8ns props.
|
|
169
|
+
await putInSpace({ ibGib: contextIbGib, space: localSpace, });
|
|
170
|
+
await registerNewIbGib({
|
|
171
|
+
ibGib: contextIbGib,
|
|
172
|
+
space: localSpace,
|
|
173
|
+
fnBroadcast: undefined,
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Attach actual ibgibs for transport (not pure DTO now)
|
|
177
|
+
contextIbGib.sagaFrame = sagaFrame;
|
|
178
|
+
if (payloadIbGibsDomain && payloadIbGibsDomain.length > 0) {
|
|
179
|
+
contextIbGib.payloadIbGibsDomain = payloadIbGibsDomain;
|
|
180
|
+
}
|
|
119
181
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
182
|
+
return contextIbGib;
|
|
183
|
+
} catch (error) {
|
|
184
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
185
|
+
throw error;
|
|
186
|
+
} finally {
|
|
187
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
124
188
|
}
|
|
189
|
+
}
|
|
125
190
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
191
|
+
/**
|
|
192
|
+
* move to sync-peer-helpers.mts as a pure function?
|
|
193
|
+
*/
|
|
194
|
+
export async function validateContext({ context }: { context: SyncSagaContextIbGib_V1 }): Promise<string[]> {
|
|
195
|
+
const lc = `[${validateContext.name}]`;
|
|
196
|
+
try {
|
|
197
|
+
if (logalot) { console.log(`${lc} starting... (I: 7797f8294bd8f7e5089cb722ad468226)`); }
|
|
133
198
|
|
|
134
|
-
|
|
135
|
-
const ib = await getSyncSagaContextIb({ data });
|
|
199
|
+
const errors: string[] = [];
|
|
136
200
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
201
|
+
// validate just the context first. if this fails we return early.
|
|
202
|
+
const intrinsicErrors = await validateIbGibIntrinsically({ ibGib: context });
|
|
203
|
+
if (intrinsicErrors && intrinsicErrors.length > 0) {
|
|
204
|
+
intrinsicErrors.forEach(x => errors.push(x));
|
|
205
|
+
return errors; /* <<<< returns early */
|
|
206
|
+
}
|
|
143
207
|
|
|
144
|
-
|
|
145
|
-
if (payloadIbGibsDomain && payloadIbGibsDomain.length > 0) {
|
|
146
|
-
contextIbGib.payloadIbGibsDomain = payloadIbGibsDomain;
|
|
147
|
-
}
|
|
208
|
+
if (context.sagaFrame) {
|
|
148
209
|
|
|
149
|
-
|
|
150
|
-
|
|
210
|
+
} else {
|
|
211
|
+
errors.push(`context.sagaFrame is falsy. (E: b4edd88f4963f493789f83b29ba2df26)`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// 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)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
// ensure the non-dto properties on the context object (i.e. props
|
|
219
|
+
// that are not ib, gib, data, or rel8ns) match the data in the
|
|
220
|
+
// context object
|
|
221
|
+
|
|
222
|
+
throw new Error(`not implemented (E: cb639658e1183fa6c8a4ebca023ba926)`);
|
|
223
|
+
} catch (error) {
|
|
224
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
225
|
+
throw error;
|
|
226
|
+
} finally {
|
|
227
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
228
|
+
}
|
|
229
|
+
}
|
|
@@ -43,6 +43,11 @@ export interface SyncSagaContextRel8ns_V1 extends IbGibRel8ns_V1 {
|
|
|
43
43
|
/**
|
|
44
44
|
* The Ephemeral Session Keystone Identity used for this saga.
|
|
45
45
|
* Required for validating the saga frame signature.
|
|
46
|
+
*
|
|
47
|
+
* ## notes
|
|
48
|
+
*
|
|
49
|
+
* This will be different for the sender and receiver, yes? hmm...
|
|
50
|
+
* I think I need to put "sender" or "receiver" in the session keystone ib.
|
|
46
51
|
*/
|
|
47
52
|
sessionKeystone?: IbGibAddr[];
|
|
48
53
|
}
|