@ibgib/core-gib 0.1.57 → 0.1.59

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.
Files changed (162) hide show
  1. package/dist/keystone/keystone-config-builder.d.mts +12 -1
  2. package/dist/keystone/keystone-config-builder.d.mts.map +1 -1
  3. package/dist/keystone/keystone-config-builder.mjs +58 -4
  4. package/dist/keystone/keystone-config-builder.mjs.map +1 -1
  5. package/dist/keystone/keystone-constants.d.mts +40 -5
  6. package/dist/keystone/keystone-constants.d.mts.map +1 -1
  7. package/dist/keystone/keystone-constants.mjs +39 -5
  8. package/dist/keystone/keystone-constants.mjs.map +1 -1
  9. package/dist/keystone/keystone-helpers.d.mts +11 -1
  10. package/dist/keystone/keystone-helpers.d.mts.map +1 -1
  11. package/dist/keystone/keystone-helpers.mjs +37 -1
  12. package/dist/keystone/keystone-helpers.mjs.map +1 -1
  13. package/dist/keystone/keystone-policy-types.d.mts +23 -0
  14. package/dist/keystone/keystone-policy-types.d.mts.map +1 -0
  15. package/dist/keystone/keystone-policy-types.mjs +2 -0
  16. package/dist/keystone/keystone-policy-types.mjs.map +1 -0
  17. package/dist/sync/graft-info/graft-info-helpers.respec.mjs +8 -8
  18. package/dist/sync/graft-info/graft-info-helpers.respec.mjs.map +1 -1
  19. package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs +22 -22
  20. package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs.map +1 -1
  21. package/dist/sync/sync-conflict-basic-divergence.respec.mjs +3 -3
  22. package/dist/sync/sync-conflict-basic-divergence.respec.mjs.map +1 -1
  23. package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs +6 -6
  24. package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs.map +1 -1
  25. package/dist/sync/sync-conflict-text-merge.respec.mjs +26 -26
  26. package/dist/sync/sync-conflict-text-merge.respec.mjs.map +1 -1
  27. package/dist/sync/sync-helpers.d.mts +19 -0
  28. package/dist/sync/sync-helpers.d.mts.map +1 -1
  29. package/dist/sync/sync-helpers.mjs +51 -1
  30. package/dist/sync/sync-helpers.mjs.map +1 -1
  31. package/dist/sync/sync-innerspace-constants.respec.mjs +2 -2
  32. package/dist/sync/sync-innerspace-constants.respec.mjs.map +1 -1
  33. package/dist/sync/sync-innerspace-deep-updates.respec.mjs +2 -2
  34. package/dist/sync/sync-innerspace-deep-updates.respec.mjs.map +1 -1
  35. package/dist/sync/sync-innerspace-dest-ahead.respec.mjs +4 -4
  36. package/dist/sync/sync-innerspace-dest-ahead.respec.mjs.map +1 -1
  37. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs +2 -2
  38. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
  39. package/dist/sync/sync-innerspace-partial-update.respec.mjs +3 -3
  40. package/dist/sync/sync-innerspace-partial-update.respec.mjs.map +1 -1
  41. package/dist/sync/sync-innerspace.respec.mjs +4 -4
  42. package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
  43. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.d.mts +5 -0
  44. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.d.mts.map +1 -1
  45. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mjs +24 -2
  46. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mjs.map +1 -1
  47. package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.d.mts +5 -0
  48. package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.d.mts.map +1 -1
  49. package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.mjs +21 -3
  50. package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.mjs.map +1 -1
  51. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.d.mts +1 -1
  52. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts +13 -1
  53. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -1
  54. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +40 -10
  55. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
  56. package/dist/sync/sync-peer/sync-peer-types.d.mts +81 -1
  57. package/dist/sync/sync-peer/sync-peer-types.d.mts.map +1 -1
  58. package/dist/sync/sync-peer/sync-peer-v1.d.mts +37 -3
  59. package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
  60. package/dist/sync/sync-peer/sync-peer-v1.mjs +163 -23
  61. package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
  62. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.d.mts +46 -0
  63. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.d.mts.map +1 -0
  64. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.mjs +45 -0
  65. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.mjs.map +1 -0
  66. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.d.mts +30 -0
  67. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.d.mts.map +1 -0
  68. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.mjs +2 -0
  69. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.mjs.map +1 -0
  70. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts +68 -0
  71. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts.map +1 -0
  72. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs +324 -0
  73. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs.map +1 -0
  74. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts +85 -0
  75. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts.map +1 -0
  76. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs +332 -0
  77. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs.map +1 -0
  78. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-types.d.mts +29 -0
  79. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-types.d.mts.map +1 -0
  80. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-types.mjs +2 -0
  81. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-types.mjs.map +1 -0
  82. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.d.mts +44 -0
  83. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.d.mts.map +1 -0
  84. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs +303 -0
  85. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs.map +1 -0
  86. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +22 -5
  87. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -1
  88. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +223 -27
  89. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
  90. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +9 -0
  91. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
  92. package/dist/sync/sync-saga-coordinator.d.mts +41 -2
  93. package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
  94. package/dist/sync/sync-saga-coordinator.mjs +110 -11
  95. package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
  96. package/dist/sync/sync-types.d.mts +24 -0
  97. package/dist/sync/sync-types.d.mts.map +1 -1
  98. package/dist/sync/sync-types.mjs +0 -1
  99. package/dist/sync/sync-types.mjs.map +1 -1
  100. package/dist/sync/sync-withid.connect.respec.d.mts +12 -0
  101. package/dist/sync/sync-withid.connect.respec.d.mts.map +1 -0
  102. package/dist/sync/sync-withid.connect.respec.mjs +205 -0
  103. package/dist/sync/sync-withid.connect.respec.mjs.map +1 -0
  104. package/dist/sync/sync-withid.establish.respec.d.mts +19 -0
  105. package/dist/sync/sync-withid.establish.respec.d.mts.map +1 -0
  106. package/dist/sync/sync-withid.establish.respec.mjs +322 -0
  107. package/dist/sync/sync-withid.establish.respec.mjs.map +1 -0
  108. package/dist/sync/sync-withid.pingpong.respec.d.mts +11 -0
  109. package/dist/sync/sync-withid.pingpong.respec.d.mts.map +1 -0
  110. package/dist/sync/sync-withid.pingpong.respec.mjs +131 -0
  111. package/dist/sync/sync-withid.pingpong.respec.mjs.map +1 -0
  112. package/dist/witness/space/inner-space/inner-space-v1.d.mts.map +1 -1
  113. package/dist/witness/space/inner-space/inner-space-v1.mjs +1 -1
  114. package/dist/witness/space/inner-space/inner-space-v1.mjs.map +1 -1
  115. package/package.json +4 -4
  116. package/src/keystone/keystone-config-builder.mts +73 -4
  117. package/src/keystone/keystone-constants.mts +42 -6
  118. package/src/keystone/keystone-helpers.mts +44 -2
  119. package/src/keystone/keystone-policy-types.mts +25 -0
  120. package/src/keystone/keystone-policy.schema.json +51 -0
  121. package/src/keystone/keystone-service-v1.mts +3 -3
  122. package/src/sync/docs/architecture.md +20 -0
  123. package/src/sync/docs/ping_pong_plan.md +147 -0
  124. package/src/sync/docs/security.md +207 -3
  125. package/src/sync/graft-info/graft-info-helpers.respec.mts +7 -7
  126. package/src/sync/sync-conflict-adv-multitimelines.respec.mts +21 -21
  127. package/src/sync/sync-conflict-basic-divergence.respec.mts +2 -2
  128. package/src/sync/sync-conflict-basic-multitimelines.respec.mts +5 -5
  129. package/src/sync/sync-conflict-text-merge.respec.mts +25 -25
  130. package/src/sync/sync-helpers.mts +51 -1
  131. package/src/sync/sync-innerspace-constants.respec.mts +1 -1
  132. package/src/sync/sync-innerspace-deep-updates.respec.mts +1 -1
  133. package/src/sync/sync-innerspace-dest-ahead.respec.mts +3 -3
  134. package/src/sync/sync-innerspace-multiple-timelines.respec.mts +1 -1
  135. package/src/sync/sync-innerspace-partial-update.respec.mts +2 -2
  136. package/src/sync/sync-innerspace.respec.mts +3 -3
  137. package/src/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mts +26 -2
  138. package/src/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.mts +23 -3
  139. package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.mts +1 -1
  140. package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +47 -13
  141. package/src/sync/sync-peer/sync-peer-types.mts +87 -1
  142. package/src/sync/sync-peer/sync-peer-v1.mts +171 -32
  143. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.mts +68 -0
  144. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.mts +36 -0
  145. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mts +385 -0
  146. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mts +388 -0
  147. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-types.mts +35 -0
  148. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mts +345 -0
  149. package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +223 -34
  150. package/src/sync/sync-saga-context/sync-saga-context-types.mts +9 -0
  151. package/src/sync/sync-saga-coordinator.mts +162 -6
  152. package/src/sync/sync-types.mts +28 -4
  153. package/src/sync/sync-withid.connect.respec.mts +243 -0
  154. package/src/sync/sync-withid.establish.respec.mts +361 -0
  155. package/src/sync/sync-withid.pingpong.respec.mts +161 -0
  156. package/src/sync/unused-identity-backup.mts.md +1 -1
  157. package/src/witness/space/inner-space/inner-space-v1.mts +4 -5
  158. package/dist/sync/sync-innerspace-dest-ahead-withid.respec.d.mts +0 -2
  159. package/dist/sync/sync-innerspace-dest-ahead-withid.respec.d.mts.map +0 -1
  160. package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs +0 -310
  161. package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs.map +0 -1
  162. package/src/sync/sync-innerspace-dest-ahead-withid.respec.mts +0 -364
@@ -0,0 +1,361 @@
1
+ /**
2
+ * @module sync-withid.establish.respec
3
+ *
4
+ * Phase 1 — `establishSessionIdentity` (Pre-Connect)
5
+ *
6
+ * Goal: Get `I^Itjp` onto the domain provider, generate `S^Stjp` locally,
7
+ * evolve `I → I1` with a `sync` claim targeting `S^Stjp`, and post both
8
+ * `I1` and `S` to the provider. Verify both keystones are in the appropriate
9
+ * durable spaces at the right times.
10
+ *
11
+ * `senderCoordinator.sync(...)` IS called — we are not mocking. We expect it
12
+ * may throw at first. We examine side-effects (keystone presence in durable
13
+ * spaces) rather than end-to-end correctness. As phases succeed and sync no
14
+ * longer throws, assertions will be adjusted accordingly.
15
+ *
16
+ * @see libs/core-gib/src/sync/docs/security.md — Implementation Plan, Phase 1A
17
+ */
18
+
19
+ import {
20
+ respecfully, ifWeMight, iReckon, ifWe
21
+ } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
22
+ const maam = `[${import.meta.url}]`, sir = maam;
23
+ import { clone, delay, extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
24
+ import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
25
+
26
+ import { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';
27
+ import { SyncSagaCoordinator } from './sync-saga-coordinator.mjs';
28
+ import { getFromSpace } from '../witness/space/space-helper.mjs';
29
+ import { Metaspace_Innerspace } from '../witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.mjs';
30
+ import { InnerSpace_V1 } from '../witness/space/inner-space/inner-space-v1.mjs';
31
+ import { SyncPeerInnerspace_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs';
32
+ import { DEFAULT_INNER_SPACE_DATA_V1 } from '../witness/space/inner-space/inner-space-types.mjs';
33
+ import { SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs';
34
+ import { KeystoneService_V1 } from '../keystone/keystone-service-v1.mjs';
35
+ import { KeystoneIbGib_V1 } from '../keystone/keystone-types.mjs';
36
+ import {
37
+ KEYSTONE_VERB_SYNC, POOL_ID_SYNC, POOL_ID_CONNECT, KEYSTONE_VERB_CONNECT,
38
+ } from '../keystone/keystone-constants.mjs';
39
+ import { createStandardPoolConfig } from '../keystone/keystone-config-builder.mjs';
40
+ import { KeystoneReplenishStrategy } from '../keystone/keystone-types.mjs';
41
+ import { SyncConflictStrategy } from './sync-constants.mjs';
42
+ import { IbGibAddr, TransformResult } from '@ibgib/ts-gib/dist/types.mjs';
43
+ import { IbGibSpaceAny } from '../witness/space/space-base-v1.mjs';
44
+ import { MetaspaceService } from '../witness/space/metaspace/metaspace-types.mjs';
45
+ import { getIdentity_throwIfUndefined } from '../keystone/keystone-helpers.mjs';
46
+ import { Factory_V1 } from '@ibgib/ts-gib/dist/V1/factory.mjs';
47
+ import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
48
+ import { ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';
49
+ import { fork } from '@ibgib/ts-gib/dist/V1/transforms/fork.mjs';
50
+
51
+ const logalot = GLOBAL_LOG_A_LOT;
52
+ const lc = sir;
53
+
54
+ // ---------------------------------------------------------------------------
55
+ // Test-only identity constants
56
+ // ---------------------------------------------------------------------------
57
+
58
+ /**
59
+ * Plaintext secret for the senderIdentity keystone (I).
60
+ * Test-only — never use plaintext secrets in production.
61
+ */
62
+ const SENDER_SECRET = 'test-sender-secret-phase1';
63
+
64
+ // ---------------------------------------------------------------------------
65
+ // Session keystone pool configs
66
+ // ---------------------------------------------------------------------------
67
+
68
+ /**
69
+ * `connect` pool — used once during `peer.connect()` transport handshake.
70
+ * Small pool; fully consumed in one handshake.
71
+ */
72
+ const SESSION_CONNECT_POOL_CONFIG = createStandardPoolConfig({
73
+ id: POOL_ID_CONNECT,
74
+ salt: 'session-connect-salt-phase1',
75
+ verbs: [KEYSTONE_VERB_CONNECT],
76
+ // Small size: fully consumed in a single connect handshake
77
+ size: 10,
78
+ sequential: 1,
79
+ random: 1,
80
+ targetBinding: 2,
81
+ replenishStrategy: KeystoneReplenishStrategy.deleteAll,
82
+ });
83
+
84
+ /**
85
+ * `sync` pool — used per outgoing context frame (Init, Delta, Commit).
86
+ * Replenishes via topUp to stay active throughout the saga.
87
+ */
88
+ const SESSION_SYNC_POOL_CONFIG = createStandardPoolConfig({
89
+ id: POOL_ID_SYNC,
90
+ salt: 'session-sync-salt-phase1',
91
+ verbs: [KEYSTONE_VERB_SYNC],
92
+ size: 200,
93
+ sequential: 1,
94
+ random: 1,
95
+ targetBinding: 2,
96
+ replenishStrategy: KeystoneReplenishStrategy.topUp,
97
+ });
98
+
99
+ // ---------------------------------------------------------------------------
100
+ // Top-level senderIdentity (I) pool config
101
+ // ---------------------------------------------------------------------------
102
+
103
+ /**
104
+ * The senderIdentity needs a `sync` pool so it can evolve itself (I → I1)
105
+ * with a claim targeting the session keystone genesis (S^Stjp).
106
+ */
107
+ const SENDER_IDENTITY_SYNC_POOL_CONFIG = createStandardPoolConfig({
108
+ id: POOL_ID_SYNC,
109
+ salt: 'senderidentitysyncsaltphase1', // dashes not allowed in regex
110
+ verbs: [KEYSTONE_VERB_SYNC],
111
+ size: 200,
112
+ sequential: 1,
113
+ random: 1,
114
+ targetBinding: 2,
115
+ replenishStrategy: KeystoneReplenishStrategy.topUp,
116
+ });
117
+
118
+ // ---------------------------------------------------------------------------
119
+ // Main test suite
120
+ // ---------------------------------------------------------------------------
121
+
122
+ await respecfully(sir, `Test Phase 1: establishSessionIdentity`, async () => {
123
+
124
+ // #region Init/Setup
125
+
126
+ const metaspace = new Metaspace_Innerspace(undefined);
127
+ await metaspace.initialize({
128
+ getFnAlert: () => async ({ title, msg }) => { console.log(`[Alert] ${title}: ${msg}`); },
129
+ getFnPrompt: () => async ({ title, msg }) => { console.log(`[Prompt] ${title}: ${msg}`); return ''; },
130
+ getFnPromptPassword: () => async (title, msg) => { console.log(`[PromptPwd] ${title}: ${msg}`); return null; },
131
+ });
132
+ while (!metaspace.initialized) { await delay(10); }
133
+
134
+ const defaultLocalUserSpace = await metaspace.getLocalUserSpace({ lock: false });
135
+ await defaultLocalUserSpace!.initialized;
136
+
137
+ /** Sender's durable space — where the sender originates ibgibs. */
138
+ const sourceSpace = new InnerSpace_V1({
139
+ ...DEFAULT_INNER_SPACE_DATA_V1,
140
+ name: 'source',
141
+ uuid: 'source_uuid',
142
+ description: 'sender durable space',
143
+ });
144
+ await sourceSpace.initialized;
145
+
146
+ /** Receiver's durable space — the domain provider in the innerspace simulation. */
147
+ const destSpace = new InnerSpace_V1({
148
+ ...DEFAULT_INNER_SPACE_DATA_V1,
149
+ name: 'dest',
150
+ uuid: 'dest_uuid',
151
+ description: 'receiver (domain provider) durable space',
152
+ });
153
+ await destSpace.initialized;
154
+
155
+ const senderCoordinator = new SyncSagaCoordinator();
156
+ const receiverCoordinator = new SyncSagaCoordinator();
157
+
158
+ async function newTestIbGib_stone({ ib = 'test', data }: { ib: string, data?: any }): Promise<IbGib_V1> {
159
+ const stone = await Factory_V1.stone({
160
+ parentPrimitiveIb: ib.split(' ').at(0) ?? 'test',
161
+ ib,
162
+ data,
163
+ uuid: true,
164
+ });
165
+ return stone;
166
+ }
167
+ async function newTestIbGib({ ib = 'test' }: { ib: string }): Promise<TransformResult<IbGib_V1>> {
168
+ let resFork = await fork({
169
+ src: ROOT,
170
+ destIb: ib,
171
+ tjp: { timestamp: true, uuid: true },
172
+ dna: true,
173
+ nCounter: true,
174
+ });
175
+ return resFork;
176
+ }
177
+
178
+ async function newTestPeer(): Promise<SyncPeerInnerspace_V1> {
179
+ const peer = new SyncPeerInnerspace_V1(clone(SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1));
180
+ await peer.initialized;
181
+ await peer.initializeOpts({
182
+ sagaId: '', // coordinator will override this via setOptionalOpts before establishSessionIdentity
183
+ localMetaspace: metaspace,
184
+ localSpace: sourceSpace,
185
+ receiverSpace: destSpace,
186
+ receiverCoordinator,
187
+ receiverMetaspace: metaspace,
188
+ });
189
+ return peer;
190
+ }
191
+
192
+ // KeystoneService_V1 is stateless — new it inline wherever needed.
193
+ const keystoneSvc = new KeystoneService_V1();
194
+
195
+ // #endregion Init/Setup
196
+
197
+
198
+ /**
199
+ * senderIdentity (I): Alice's long-lived Domain Keystone.
200
+ * Created fresh for this test with a `sync` pool so it can evolve (I → I1).
201
+ */
202
+ let senderIdentity: KeystoneIbGib_V1 | undefined;
203
+
204
+ // #region Step 1: Prepare identity
205
+
206
+ // Create senderIdentity genesis (I^Itjp) in sourceSpace
207
+ senderIdentity = await keystoneSvc.genesis({
208
+ masterSecret: SENDER_SECRET,
209
+ configs: [SENDER_IDENTITY_SYNC_POOL_CONFIG],
210
+ metaspace,
211
+ space: sourceSpace,
212
+ });
213
+ if (logalot) { console.log(`${lc} senderIdentity genesis addr: ${getIbGibAddr({ ibGib: senderIdentity })}`); }
214
+
215
+ // post the senderIdentity to receiver (like "create account")
216
+ await metaspace.put({ ibGib: senderIdentity, space: destSpace });
217
+ await metaspace.registerNewIbGib({ ibGib: senderIdentity, space: destSpace });
218
+
219
+ // #endregion Step 1: Prepare identity
220
+
221
+ // at this point, we have mimicked a user who already has an identity via a
222
+ // create account button.
223
+
224
+ // #region Step 2: Execute
225
+
226
+ let xStone: IbGib_V1;
227
+ let xStoneAddr: IbGibAddr;
228
+ try {
229
+ if (logalot) { console.log(`${lc}[Step 2] starting... (I: 1aa5643dd8d46fcdd87d48b8be550826)`); }
230
+
231
+ // setup/call sync
232
+
233
+ // Sync call — sync itself is responsible for establishSessionIdentity
234
+ // internally.
235
+
236
+ /**
237
+ * doesn't really matter intrinsically for this test, but we need a
238
+ * domain ibgib to sync
239
+ */
240
+ xStone = await newTestIbGib_stone({ ib: 'test' });
241
+ xStoneAddr = getIbGibAddr({ ibGib: xStone });
242
+ await metaspace.put({ ibGib: xStone, space: sourceSpace });
243
+ await metaspace.registerNewIbGib({ ibGib: xStone, space: sourceSpace });
244
+
245
+ const syncSaga = await senderCoordinator.sync({
246
+ domainIbGibs: [xStone],
247
+ senderIdentity,
248
+ fnSenderSecret: async () => { return SENDER_SECRET },
249
+ peer: await newTestPeer(),
250
+ localSpace: sourceSpace,
251
+ metaspace,
252
+ conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
253
+ });
254
+ await syncSaga.done;
255
+
256
+ } catch (error) {
257
+ // error is fine/expected right now. later perhaps we will throw, or
258
+ // perhaps we always just swallow any exceptions since this is close to
259
+ // a unit test
260
+ console.error(`${lc} ${extractErrorMsg(error)}`);
261
+ } finally {
262
+ if (logalot) { console.log(`${lc}[Step 2] complete.`); }
263
+ }
264
+
265
+ // #endregion Step 2: Execute
266
+
267
+ // #region Step 3: Check states
268
+
269
+ // check state of sender/receiver spaces WRT sender identity, new sender
270
+ // identity, and session identity.
271
+
272
+ // get newSenderIdentity address via metaspace.getLatestAddr
273
+ // Resolve the latest senderIdentity frame (I1) from the sender's space.
274
+ // After sync, the coordinator should have evolved I → I1 and stored it.
275
+ let newSenderIdentityAddr: IbGibAddr | undefined;
276
+ /**
277
+ * The session keystone addr should be embedded in I1's proof claim target.
278
+ */
279
+ let newSenderIdentity: KeystoneIbGib_V1 | undefined;
280
+ await ifWe(sir, 'newSenderIdentity created and stored in source space', async () => {
281
+ newSenderIdentityAddr = await metaspace.getLatestAddr({
282
+ ibGib: senderIdentity,
283
+ space: sourceSpace,
284
+ });
285
+ if (!newSenderIdentityAddr) { throw new Error(`newSenderIdentity not found in space (${sourceSpace.ib}). this should have been evolved and stored during sync (E: a5a798bf8ba467cbc87595dcc2b36726)`); }
286
+
287
+ newSenderIdentity = await getIdentity_throwIfUndefined({
288
+ addr: newSenderIdentityAddr,
289
+ metaspace,
290
+ space: sourceSpace,
291
+ });
292
+
293
+ // todo: add iReckon statements for expectations like claim verb, claim target, etc., of newSenderIdentity
294
+ iReckon(sir, newSenderIdentity).asTo('newSenderIdentity is truthy').isGonnaBeTruthy();
295
+ const syncProof = newSenderIdentity?.data?.proofs?.find(p => p.claim?.verb === KEYSTONE_VERB_SYNC);
296
+ iReckon(sir, syncProof).asTo('I1 has a sync-verb proof/claim').isGonnaBeTruthy();
297
+ iReckon(sir, syncProof?.claim?.target).asTo('sync claim has a target (S^Stjp)').isGonnaBeTruthy();
298
+ });
299
+ if (!newSenderIdentity) { throw new Error(`(UNEXPECTED) newSenderIdentity falsy? should have thrown before this if falsy. (E: 7a3d92e6160409de149eaf6802365126)`); }
300
+
301
+ const sessionIdentityTjpAddr = newSenderIdentity.data.proofs
302
+ .find(p => p.claim.verb === KEYSTONE_VERB_SYNC)?.claim.target;
303
+
304
+ if (!sessionIdentityTjpAddr) { throw new Error(`(UNEXPECTED) sessionIdentityTjpAddr falsy? (E: c53583b07a78837de84a59388b6ff826)`); }
305
+
306
+ let sessionIdentity: KeystoneIbGib_V1 | undefined;
307
+ await ifWe(sir, 'creates sessionIdentity genesis (S) locally — exists in sourceSpace', async () => {
308
+ sessionIdentity = await getIdentity_throwIfUndefined({
309
+ addr: sessionIdentityTjpAddr,
310
+ metaspace,
311
+ space: sourceSpace,
312
+ });
313
+ iReckon(sir, sessionIdentity).asTo('sessionIdentity is truthy').isGonnaBeTruthy();
314
+ });
315
+ if (!sessionIdentity) { throw new Error(`(UNEXPECTED) sessionIdentity falsy? (E: e1fa06009df535f3c848e6ca8b0bd326)`); }
316
+
317
+ await ifWe(sir, 'Session identity S has expected state', async () => {
318
+ // #region sanity/compile
319
+ if (!sessionIdentity) { throw new Error(`(UNEXPECTED) sessionIdentity falsy? (E: dd229f4e44489a54488768157a393926)`); }
320
+ if (!sessionIdentity.data) { throw new Error(`(UNEXPECTED) sessionIdentity.data falsy? (E: 56f10c9f9c18c6147ea19281dcbaf826)`); }
321
+ // #endregion sanity/compile
322
+
323
+ // Verify S has both pool ids: connect and sync
324
+ const sPools = sessionIdentity.data.challengePools;
325
+ iReckon(sir, sPools).asTo('S has challengePools').isGonnaBeTruthy();
326
+ const hasConnectPool = sPools?.some(p => p.id === POOL_ID_CONNECT);
327
+ const hasSyncPool = sPools?.some(p => p.id === POOL_ID_SYNC);
328
+ iReckon(sir, hasConnectPool).asTo('S has connect pool').isGonnaBeTrue();
329
+ iReckon(sir, hasSyncPool).asTo('S has sync pool').isGonnaBeTrue();
330
+ const sProofs = sessionIdentity.data.proofs;
331
+ iReckon(sir, sProofs).asTo('S has proofs array').isGonnaBeTruthy();
332
+ iReckon(sir, sProofs.length === 0).asTo('S has 0 proofs on genesis').isGonnaBeTrue();
333
+
334
+ // Verify S is bound to target domain (xStone) via frameDetails
335
+ const targetAddrs = sessionIdentity.data.frameDetails?.targetAddrs;
336
+ iReckon(sir, targetAddrs).asTo('S has targetAddrs array in frameDetails').isGonnaBeTruthy();
337
+ iReckon(sir, targetAddrs?.includes(xStoneAddr)).asTo('S targetAddrs contains the domain being synced (xStoneAddr)').isGonnaBeTrue();
338
+ });
339
+
340
+ await ifWe(sir, 'I, I1 and S all exist in destSpace (receiver)', async () => {
341
+ // todo: use getIdentity_throwIfUndefined for all three identities but in destSpace
342
+ const senderIdentityAddr = getIbGibAddr({ ibGib: senderIdentity! });
343
+ await getIdentity_throwIfUndefined({
344
+ addr: senderIdentityAddr,
345
+ metaspace,
346
+ space: destSpace
347
+ });
348
+ iReckon(sir, true).asTo('I (original) exists in destSpace').isGonnaBeTrue();
349
+
350
+ if (!newSenderIdentityAddr) { throw new Error(`newSenderIdentity not found in space (${sourceSpace.ib}). this should have been evolved and stored during sync (E: b626885071885b38d87853189f25c826)`); }
351
+ await getIdentity_throwIfUndefined({ addr: newSenderIdentityAddr, metaspace, space: destSpace });
352
+ iReckon(sir, true).asTo('I1 (evolved) exists in destSpace').isGonnaBeTrue();
353
+
354
+ await getIdentity_throwIfUndefined({ addr: sessionIdentityTjpAddr, metaspace, space: destSpace });
355
+ iReckon(sir, true).asTo('S (sessionIdentity) exists in destSpace').isGonnaBeTrue();
356
+
357
+ });
358
+
359
+ // #endregion Step 3: Check states
360
+
361
+ });
@@ -0,0 +1,161 @@
1
+ /**
2
+ * @module sync-withid.pingpong.respec
3
+ *
4
+ * Phase 3A — Basic Single-Timeline Sync with Identity
5
+ *
6
+ * Goal: Verify that the ping pong sync process completes successfully with identity.
7
+ *
8
+ * @see libs/core-gib/src/sync/docs/ping_pong_plan.md
9
+ */
10
+
11
+ import {
12
+ respecfully, ifWeMight, iReckon,
13
+ } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
14
+ const maam = `[${import.meta.url}]`, sir = maam;
15
+ import { clone, delay, extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
16
+ import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
17
+
18
+ import { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';
19
+ import { SyncSagaCoordinator } from './sync-saga-coordinator.mjs';
20
+ import { Metaspace_Innerspace } from '../witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.mjs';
21
+ import { InnerSpace_V1 } from '../witness/space/inner-space/inner-space-v1.mjs';
22
+ import { SyncPeerInnerspace_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs';
23
+ import { DEFAULT_INNER_SPACE_DATA_V1 } from '../witness/space/inner-space/inner-space-types.mjs';
24
+ import { SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs';
25
+ import { KeystoneService_V1 } from '../keystone/keystone-service-v1.mjs';
26
+ import { KeystoneIbGib_V1 } from '../keystone/keystone-types.mjs';
27
+ import {
28
+ KEYSTONE_VERB_SYNC, POOL_ID_SYNC, POOL_ID_CONNECT, KEYSTONE_VERB_CONNECT,
29
+ } from '../keystone/keystone-constants.mjs';
30
+ import { createStandardPoolConfig } from '../keystone/keystone-config-builder.mjs';
31
+ import { KeystoneReplenishStrategy } from '../keystone/keystone-types.mjs';
32
+ import { SyncConflictStrategy } from './sync-constants.mjs';
33
+ import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
34
+ import { getIdentity_throwIfUndefined } from '../keystone/keystone-helpers.mjs';
35
+ import { Factory_V1 } from '@ibgib/ts-gib/dist/V1/factory.mjs';
36
+ import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
37
+ import { getDependencyGraph } from '../common/other/graph-helper.mjs';
38
+
39
+ const logalot = GLOBAL_LOG_A_LOT;
40
+ const lc = sir;
41
+
42
+ const SENDER_SECRET = 'test-sender-secret-phase1';
43
+
44
+ const SENDER_IDENTITY_SYNC_POOL_CONFIG = createStandardPoolConfig({
45
+ id: POOL_ID_SYNC,
46
+ salt: 'senderidentitysyncsaltphase1',
47
+ verbs: [KEYSTONE_VERB_SYNC],
48
+ size: 200,
49
+ sequential: 1,
50
+ random: 1,
51
+ targetBinding: 2,
52
+ replenishStrategy: KeystoneReplenishStrategy.topUp,
53
+ });
54
+
55
+ await respecfully(sir, `Test Phase 3A: Ping Pong Sync with Identity`, async () => {
56
+
57
+ // #region Init/Setup
58
+
59
+ const metaspace = new Metaspace_Innerspace(undefined);
60
+ await metaspace.initialize({
61
+ getFnAlert: () => async ({ title, msg }) => { console.log(`[Alert] ${title}: ${msg}`); },
62
+ getFnPrompt: () => async ({ title, msg }) => { console.log(`[Prompt] ${title}: ${msg}`); return ''; },
63
+ getFnPromptPassword: () => async (title, msg) => { console.log(`[PromptPwd] ${title}: ${msg}`); return null; },
64
+ });
65
+ while (!metaspace.initialized) { await delay(10); }
66
+
67
+ const defaultLocalUserSpace = await metaspace.getLocalUserSpace({ lock: false });
68
+ await defaultLocalUserSpace!.initialized;
69
+
70
+ const sourceSpace = new InnerSpace_V1({
71
+ ...DEFAULT_INNER_SPACE_DATA_V1,
72
+ name: 'source',
73
+ uuid: 'source_uuid',
74
+ description: 'sender durable space',
75
+ });
76
+ await sourceSpace.initialized;
77
+
78
+ const destSpace = new InnerSpace_V1({
79
+ ...DEFAULT_INNER_SPACE_DATA_V1,
80
+ name: 'dest',
81
+ uuid: 'dest_uuid',
82
+ description: 'receiver (domain provider) durable space',
83
+ });
84
+ await destSpace.initialized;
85
+
86
+ const senderCoordinator = new SyncSagaCoordinator();
87
+ const receiverCoordinator = new SyncSagaCoordinator();
88
+
89
+ async function newTestIbGib_stone({ ib = 'test', data }: { ib: string, data?: any }): Promise<IbGib_V1> {
90
+ const stone = await Factory_V1.stone({
91
+ parentPrimitiveIb: ib.split(' ').at(0) ?? 'test',
92
+ ib,
93
+ data,
94
+ uuid: true,
95
+ });
96
+ return stone;
97
+ }
98
+
99
+ async function newTestPeer(): Promise<SyncPeerInnerspace_V1> {
100
+ const peer = new SyncPeerInnerspace_V1(clone(SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1));
101
+ await peer.initialized;
102
+ await peer.initializeOpts({
103
+ sagaId: '',
104
+ localMetaspace: metaspace,
105
+ localSpace: sourceSpace,
106
+ receiverSpace: destSpace,
107
+ receiverCoordinator,
108
+ receiverMetaspace: metaspace,
109
+ });
110
+ return peer;
111
+ }
112
+
113
+ const keystoneSvc = new KeystoneService_V1();
114
+
115
+ // #endregion Init/Setup
116
+
117
+ let senderIdentity = await keystoneSvc.genesis({
118
+ masterSecret: SENDER_SECRET,
119
+ configs: [SENDER_IDENTITY_SYNC_POOL_CONFIG],
120
+ metaspace,
121
+ space: sourceSpace,
122
+ });
123
+
124
+ // post the senderIdentity to receiver
125
+ await metaspace.put({ ibGib: senderIdentity, space: destSpace });
126
+ await metaspace.registerNewIbGib({ ibGib: senderIdentity, space: destSpace });
127
+
128
+ let syncError: any = null;
129
+ let xStone: IbGib_V1;
130
+ let xStoneAddr: IbGibAddr;
131
+ let peer: SyncPeerInnerspace_V1;
132
+
133
+ try {
134
+ xStone = await newTestIbGib_stone({ ib: 'test-pingpong' });
135
+ xStoneAddr = getIbGibAddr({ ibGib: xStone });
136
+ await metaspace.put({ ibGib: xStone, space: sourceSpace });
137
+ await metaspace.registerNewIbGib({ ibGib: xStone, space: sourceSpace });
138
+
139
+ peer = await newTestPeer();
140
+
141
+ const syncSaga = await senderCoordinator.sync({
142
+ domainIbGibs: [xStone],
143
+ senderIdentity,
144
+ fnSenderSecret: async () => SENDER_SECRET,
145
+ peer,
146
+ localSpace: sourceSpace,
147
+ metaspace,
148
+ conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
149
+ });
150
+ await syncSaga.done;
151
+
152
+ } catch (error) {
153
+ syncError = error;
154
+ }
155
+
156
+ await ifWeMight(sir, 'completes the entire sync saga successfully', async () => {
157
+ const errorMsg = syncError ? extractErrorMsg(syncError) : '';
158
+ iReckon(sir, syncError).asTo(`syncError: ${errorMsg}`).isGonnaBeFalsy();
159
+ });
160
+
161
+ });
@@ -270,7 +270,7 @@ export async function authenticateContext({
270
270
  const { signedSessionKeystone } = context;
271
271
  if (signedSessionKeystone) {
272
272
  if (msg.data.stage === SyncStage.init) {
273
- // transmit full keystone graph on the first handshake
273
+ // transmit full keystone graph on the first connect handshake
274
274
  const keystoneGraph = await getDependencyGraph({
275
275
  ibGib: signedSessionKeystone,
276
276
  space: localSpace,
@@ -5,19 +5,18 @@ import { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helpe
5
5
 
6
6
  import { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';
7
7
  import {
8
- IbGibSpaceData, IbGibSpaceOptionsData, IbGibSpaceOptionsRel8ns,
8
+ IbGibSpaceOptionsData, IbGibSpaceOptionsRel8ns,
9
9
  IbGibSpaceOptionsIbGib, IbGibSpaceResultData, IbGibSpaceResultRel8ns,
10
- IbGibSpaceResultIbGib, IbGibSpaceRel8ns,
10
+ IbGibSpaceResultIbGib,
11
11
  } from '../space-types.mjs';
12
12
  import { getSpaceIb, } from '../space-helper.mjs';
13
13
  import { getTjpAddr } from '../../../common/other/ibgib-helper.mjs';
14
- import { ReconciliationSpaceBase, ReconciliationSpaceData, ReconciliationSpaceRel8ns } from '../reconciliation-space/reconciliation-space-base.mjs';
14
+ import { ReconciliationSpaceBase, } from '../reconciliation-space/reconciliation-space-base.mjs';
15
15
  import { DEFAULT_INNER_SPACE_DATA_V1, InnerSpaceData_V1, InnerSpaceRel8ns_V1 } from './inner-space-types.mjs';
16
16
  import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
17
17
  import { getGib } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';
18
- import { isMetaStone, newUpMetaStone, parseMetaStoneIb } from '../../../common/meta-stone/meta-stone-helper.mjs';
18
+ import { isMetaStone, parseMetaStoneIb } from '../../../common/meta-stone/meta-stone-helper.mjs';
19
19
  import { MetaStoneIbGib_V1, MetaStoneIbInfo } from '../../../common/meta-stone/meta-stone-types.mjs';
20
- import { GIB } from '@ibgib/ts-gib/dist/V1/constants.mjs';
21
20
  import { META_STONE_TARGET_REL8N_NAME } from '../../../common/meta-stone/meta-stone-constants.mjs';
22
21
 
23
22
  const logalot = GLOBAL_LOG_A_LOT;
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=sync-innerspace-dest-ahead-withid.respec.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sync-innerspace-dest-ahead-withid.respec.d.mts","sourceRoot":"","sources":["../../src/sync/sync-innerspace-dest-ahead-withid.respec.mts"],"names":[],"mappings":""}