@ibgib/core-gib 0.0.4

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 (330) hide show
  1. package/.vscode/core-gib-snippets.code-snippets +189 -0
  2. package/.vscode/launch.json +24 -0
  3. package/.vscode/settings.json +56 -0
  4. package/.vscode/tasks.json +37 -0
  5. package/CHANGELOG.md +11 -0
  6. package/README.md +215 -0
  7. package/dist/common/aws-constants.d.mts +7 -0
  8. package/dist/common/aws-constants.d.mts.map +1 -0
  9. package/dist/common/aws-constants.mjs +7 -0
  10. package/dist/common/aws-constants.mjs.map +1 -0
  11. package/dist/common/bin/bin-types.d.mts +17 -0
  12. package/dist/common/bin/bin-types.d.mts.map +1 -0
  13. package/dist/common/bin/bin-types.mjs +3 -0
  14. package/dist/common/bin/bin-types.mjs.map +1 -0
  15. package/dist/common/cache/cache-types.d.mts +57 -0
  16. package/dist/common/cache/cache-types.d.mts.map +1 -0
  17. package/dist/common/cache/cache-types.mjs +2 -0
  18. package/dist/common/cache/cache-types.mjs.map +1 -0
  19. package/dist/common/comment/comment-constants.d.mts +11 -0
  20. package/dist/common/comment/comment-constants.d.mts.map +1 -0
  21. package/dist/common/comment/comment-constants.mjs +11 -0
  22. package/dist/common/comment/comment-constants.mjs.map +1 -0
  23. package/dist/common/comment/comment-helper.d.mts +59 -0
  24. package/dist/common/comment/comment-helper.d.mts.map +1 -0
  25. package/dist/common/comment/comment-helper.mjs +173 -0
  26. package/dist/common/comment/comment-helper.mjs.map +1 -0
  27. package/dist/common/comment/comment-types.d.mts +16 -0
  28. package/dist/common/comment/comment-types.d.mts.map +1 -0
  29. package/dist/common/comment/comment-types.mjs +2 -0
  30. package/dist/common/comment/comment-types.mjs.map +1 -0
  31. package/dist/common/display/display-helper.d.mts +19 -0
  32. package/dist/common/display/display-helper.d.mts.map +1 -0
  33. package/dist/common/display/display-helper.mjs +68 -0
  34. package/dist/common/display/display-helper.mjs.map +1 -0
  35. package/dist/common/display/display-types.d.mts +97 -0
  36. package/dist/common/display/display-types.d.mts.map +1 -0
  37. package/dist/common/display/display-types.mjs +37 -0
  38. package/dist/common/display/display-types.mjs.map +1 -0
  39. package/dist/common/encrypt/encrypt-constants.d.mts +27 -0
  40. package/dist/common/encrypt/encrypt-constants.d.mts.map +1 -0
  41. package/dist/common/encrypt/encrypt-constants.mjs +27 -0
  42. package/dist/common/encrypt/encrypt-constants.mjs.map +1 -0
  43. package/dist/common/encrypt/encrypt-types.d.mts +116 -0
  44. package/dist/common/encrypt/encrypt-types.d.mts.map +1 -0
  45. package/dist/common/encrypt/encrypt-types.mjs +9 -0
  46. package/dist/common/encrypt/encrypt-types.mjs.map +1 -0
  47. package/dist/common/error/error-constants.d.mts +9 -0
  48. package/dist/common/error/error-constants.d.mts.map +1 -0
  49. package/dist/common/error/error-constants.mjs +9 -0
  50. package/dist/common/error/error-constants.mjs.map +1 -0
  51. package/dist/common/error/error-helper.d.mts +43 -0
  52. package/dist/common/error/error-helper.d.mts.map +1 -0
  53. package/dist/common/error/error-helper.mjs +167 -0
  54. package/dist/common/error/error-helper.mjs.map +1 -0
  55. package/dist/common/error/error-types.d.mts +58 -0
  56. package/dist/common/error/error-types.d.mts.map +1 -0
  57. package/dist/common/error/error-types.mjs +2 -0
  58. package/dist/common/error/error-types.mjs.map +1 -0
  59. package/dist/common/form/form-helper.d.mts +97 -0
  60. package/dist/common/form/form-helper.d.mts.map +1 -0
  61. package/dist/common/form/form-helper.mjs +185 -0
  62. package/dist/common/form/form-helper.mjs.map +1 -0
  63. package/dist/common/form/form-items.d.mts +229 -0
  64. package/dist/common/form/form-items.d.mts.map +1 -0
  65. package/dist/common/form/form-items.mjs +63 -0
  66. package/dist/common/form/form-items.mjs.map +1 -0
  67. package/dist/common/import-export/import-export-types.d.mts +18 -0
  68. package/dist/common/import-export/import-export-types.d.mts.map +1 -0
  69. package/dist/common/import-export/import-export-types.mjs +2 -0
  70. package/dist/common/import-export/import-export-types.mjs.map +1 -0
  71. package/dist/common/legacy/legacy-types.d.mts +2 -0
  72. package/dist/common/legacy/legacy-types.d.mts.map +1 -0
  73. package/dist/common/legacy/legacy-types.mjs +2 -0
  74. package/dist/common/legacy/legacy-types.mjs.map +1 -0
  75. package/dist/common/link/link-constants.d.mts +2 -0
  76. package/dist/common/link/link-constants.d.mts.map +1 -0
  77. package/dist/common/link/link-constants.mjs +2 -0
  78. package/dist/common/link/link-constants.mjs.map +1 -0
  79. package/dist/common/link/link-helper.d.mts +37 -0
  80. package/dist/common/link/link-helper.d.mts.map +1 -0
  81. package/dist/common/link/link-helper.mjs +143 -0
  82. package/dist/common/link/link-helper.mjs.map +1 -0
  83. package/dist/common/link/link-types.d.mts +14 -0
  84. package/dist/common/link/link-types.d.mts.map +1 -0
  85. package/dist/common/link/link-types.mjs +2 -0
  86. package/dist/common/link/link-types.mjs.map +1 -0
  87. package/dist/common/other/graph-helper.d.mts +166 -0
  88. package/dist/common/other/graph-helper.d.mts.map +1 -0
  89. package/dist/common/other/graph-helper.mjs +710 -0
  90. package/dist/common/other/graph-helper.mjs.map +1 -0
  91. package/dist/common/other/ibgib-helper.d.mts +245 -0
  92. package/dist/common/other/ibgib-helper.d.mts.map +1 -0
  93. package/dist/common/other/ibgib-helper.mjs +641 -0
  94. package/dist/common/other/ibgib-helper.mjs.map +1 -0
  95. package/dist/common/other/other-constants.d.mts +53 -0
  96. package/dist/common/other/other-constants.d.mts.map +1 -0
  97. package/dist/common/other/other-constants.mjs +67 -0
  98. package/dist/common/other/other-constants.mjs.map +1 -0
  99. package/dist/common/other/other-types.d.mts +166 -0
  100. package/dist/common/other/other-types.d.mts.map +1 -0
  101. package/dist/common/other/other-types.mjs +30 -0
  102. package/dist/common/other/other-types.mjs.map +1 -0
  103. package/dist/common/other/svg-constants.d.mts +2 -0
  104. package/dist/common/other/svg-constants.d.mts.map +1 -0
  105. package/dist/common/other/svg-constants.mjs +2 -0
  106. package/dist/common/other/svg-constants.mjs.map +1 -0
  107. package/dist/common/other/svg-helper.d.mts +54 -0
  108. package/dist/common/other/svg-helper.d.mts.map +1 -0
  109. package/dist/common/other/svg-helper.mjs +170 -0
  110. package/dist/common/other/svg-helper.mjs.map +1 -0
  111. package/dist/common/pic/pic-constants.d.mts +13 -0
  112. package/dist/common/pic/pic-constants.d.mts.map +1 -0
  113. package/dist/common/pic/pic-constants.mjs +13 -0
  114. package/dist/common/pic/pic-constants.mjs.map +1 -0
  115. package/dist/common/pic/pic-helper.d.mts +70 -0
  116. package/dist/common/pic/pic-helper.d.mts.map +1 -0
  117. package/dist/common/pic/pic-helper.mjs +235 -0
  118. package/dist/common/pic/pic-helper.mjs.map +1 -0
  119. package/dist/common/pic/pic-types.d.mts +23 -0
  120. package/dist/common/pic/pic-types.d.mts.map +1 -0
  121. package/dist/common/pic/pic-types.mjs +2 -0
  122. package/dist/common/pic/pic-types.mjs.map +1 -0
  123. package/dist/common/root/root-constants.d.mts +40 -0
  124. package/dist/common/root/root-constants.d.mts.map +1 -0
  125. package/dist/common/root/root-constants.mjs +40 -0
  126. package/dist/common/root/root-constants.mjs.map +1 -0
  127. package/dist/common/root/root-types.d.mts +9 -0
  128. package/dist/common/root/root-types.d.mts.map +1 -0
  129. package/dist/common/root/root-types.mjs +2 -0
  130. package/dist/common/root/root-types.mjs.map +1 -0
  131. package/dist/common/tag/tag-constants.d.mts +21 -0
  132. package/dist/common/tag/tag-constants.d.mts.map +1 -0
  133. package/dist/common/tag/tag-constants.mjs +28 -0
  134. package/dist/common/tag/tag-constants.mjs.map +1 -0
  135. package/dist/common/tag/tag-types.d.mts +14 -0
  136. package/dist/common/tag/tag-types.d.mts.map +1 -0
  137. package/dist/common/tag/tag-types.mjs +2 -0
  138. package/dist/common/tag/tag-types.mjs.map +1 -0
  139. package/dist/core-constants.d.mts +89 -0
  140. package/dist/core-constants.d.mts.map +1 -0
  141. package/dist/core-constants.mjs +484 -0
  142. package/dist/core-constants.mjs.map +1 -0
  143. package/dist/core-helper.d.mts +6 -0
  144. package/dist/core-helper.d.mts.map +1 -0
  145. package/dist/core-helper.mjs +28 -0
  146. package/dist/core-helper.mjs.map +1 -0
  147. package/dist/core-types.d.mts +520 -0
  148. package/dist/core-types.d.mts.map +1 -0
  149. package/dist/core-types.mjs +2 -0
  150. package/dist/core-types.mjs.map +1 -0
  151. package/dist/index.d.mts +2 -0
  152. package/dist/index.d.mts.map +1 -0
  153. package/dist/index.mjs +3 -0
  154. package/dist/index.mjs.map +1 -0
  155. package/dist/witness/app/app-base-v1.d.mts +130 -0
  156. package/dist/witness/app/app-base-v1.d.mts.map +1 -0
  157. package/dist/witness/app/app-base-v1.mjs +462 -0
  158. package/dist/witness/app/app-base-v1.mjs.map +1 -0
  159. package/dist/witness/app/app-constants.d.mts +10 -0
  160. package/dist/witness/app/app-constants.d.mts.map +1 -0
  161. package/dist/witness/app/app-constants.mjs +13 -0
  162. package/dist/witness/app/app-constants.mjs.map +1 -0
  163. package/dist/witness/app/app-helper.d.mts +85 -0
  164. package/dist/witness/app/app-helper.d.mts.map +1 -0
  165. package/dist/witness/app/app-helper.mjs +258 -0
  166. package/dist/witness/app/app-helper.mjs.map +1 -0
  167. package/dist/witness/app/app-types.d.mts +211 -0
  168. package/dist/witness/app/app-types.d.mts.map +1 -0
  169. package/dist/witness/app/app-types.mjs +49 -0
  170. package/dist/witness/app/app-types.mjs.map +1 -0
  171. package/dist/witness/app/chat-app/chat-app-types.d.mts +18 -0
  172. package/dist/witness/app/chat-app/chat-app-types.d.mts.map +1 -0
  173. package/dist/witness/app/chat-app/chat-app-types.mjs +25 -0
  174. package/dist/witness/app/chat-app/chat-app-types.mjs.map +1 -0
  175. package/dist/witness/app/flash-app/flash-app-types.d.mts +16 -0
  176. package/dist/witness/app/flash-app/flash-app-types.d.mts.map +1 -0
  177. package/dist/witness/app/flash-app/flash-app-types.mjs +23 -0
  178. package/dist/witness/app/flash-app/flash-app-types.mjs.map +1 -0
  179. package/dist/witness/app/raw-app/raw-app-types.d.mts +18 -0
  180. package/dist/witness/app/raw-app/raw-app-types.d.mts.map +1 -0
  181. package/dist/witness/app/raw-app/raw-app-types.mjs +25 -0
  182. package/dist/witness/app/raw-app/raw-app-types.mjs.map +1 -0
  183. package/dist/witness/app/todo-app/todo-app-types.d.ts +33 -0
  184. package/dist/witness/app/todo-app/todo-app-types.d.ts.map +1 -0
  185. package/dist/witness/app/todo-app/todo-app-types.js +31 -0
  186. package/dist/witness/app/todo-app/todo-app-types.js.map +1 -0
  187. package/dist/witness/robbot/robbot-base-v1.d.ts +432 -0
  188. package/dist/witness/robbot/robbot-base-v1.d.ts.map +1 -0
  189. package/dist/witness/robbot/robbot-base-v1.js +1407 -0
  190. package/dist/witness/robbot/robbot-base-v1.js.map +1 -0
  191. package/dist/witness/robbot/robbot-constants.d.mts +24 -0
  192. package/dist/witness/robbot/robbot-constants.d.mts.map +1 -0
  193. package/dist/witness/robbot/robbot-constants.mjs +24 -0
  194. package/dist/witness/robbot/robbot-constants.mjs.map +1 -0
  195. package/dist/witness/robbot/robbot-helper.d.mts +152 -0
  196. package/dist/witness/robbot/robbot-helper.d.mts.map +1 -0
  197. package/dist/witness/robbot/robbot-helper.mjs +609 -0
  198. package/dist/witness/robbot/robbot-helper.mjs.map +1 -0
  199. package/dist/witness/robbot/robbot-types.d.mts +539 -0
  200. package/dist/witness/robbot/robbot-types.d.mts.map +1 -0
  201. package/dist/witness/robbot/robbot-types.mjs +294 -0
  202. package/dist/witness/robbot/robbot-types.mjs.map +1 -0
  203. package/dist/witness/space/bootstrap/bootstrap-constants.d.mts +14 -0
  204. package/dist/witness/space/bootstrap/bootstrap-constants.d.mts.map +1 -0
  205. package/dist/witness/space/bootstrap/bootstrap-constants.mjs +15 -0
  206. package/dist/witness/space/bootstrap/bootstrap-constants.mjs.map +1 -0
  207. package/dist/witness/space/inner-space-v1.d.ts +63 -0
  208. package/dist/witness/space/inner-space-v1.d.ts.map +1 -0
  209. package/dist/witness/space/inner-space-v1.js +356 -0
  210. package/dist/witness/space/inner-space-v1.js.map +1 -0
  211. package/dist/witness/space/outer-space/outer-space-constants.d.mts +2 -0
  212. package/dist/witness/space/outer-space/outer-space-constants.d.mts.map +1 -0
  213. package/dist/witness/space/outer-space/outer-space-constants.mjs +2 -0
  214. package/dist/witness/space/outer-space/outer-space-constants.mjs.map +1 -0
  215. package/dist/witness/space/outer-space/outer-space-helper.d.mts +28 -0
  216. package/dist/witness/space/outer-space/outer-space-helper.d.mts.map +1 -0
  217. package/dist/witness/space/outer-space/outer-space-helper.mjs +87 -0
  218. package/dist/witness/space/outer-space/outer-space-helper.mjs.map +1 -0
  219. package/dist/witness/space/outer-space/outer-space-types.d.mts +548 -0
  220. package/dist/witness/space/outer-space/outer-space-types.d.mts.map +1 -0
  221. package/dist/witness/space/outer-space/outer-space-types.mjs +118 -0
  222. package/dist/witness/space/outer-space/outer-space-types.mjs.map +1 -0
  223. package/dist/witness/space/space-base-v1.d.mts +147 -0
  224. package/dist/witness/space/space-base-v1.d.mts.map +1 -0
  225. package/dist/witness/space/space-base-v1.mjs +350 -0
  226. package/dist/witness/space/space-base-v1.mjs.map +1 -0
  227. package/dist/witness/space/space-constants.d.mts +181 -0
  228. package/dist/witness/space/space-constants.d.mts.map +1 -0
  229. package/dist/witness/space/space-constants.mjs +192 -0
  230. package/dist/witness/space/space-constants.mjs.map +1 -0
  231. package/dist/witness/space/space-helper.d.mts +666 -0
  232. package/dist/witness/space/space-helper.d.mts.map +1 -0
  233. package/dist/witness/space/space-helper.mjs +2830 -0
  234. package/dist/witness/space/space-helper.mjs.map +1 -0
  235. package/dist/witness/space/space-types.d.mts +422 -0
  236. package/dist/witness/space/space-types.d.mts.map +1 -0
  237. package/dist/witness/space/space-types.mjs +52 -0
  238. package/dist/witness/space/space-types.mjs.map +1 -0
  239. package/dist/witness/witness-base-v1.d.ts +144 -0
  240. package/dist/witness/witness-base-v1.d.ts.map +1 -0
  241. package/dist/witness/witness-base-v1.js +300 -0
  242. package/dist/witness/witness-base-v1.js.map +1 -0
  243. package/dist/witness/witness-constants.d.mts +3 -0
  244. package/dist/witness/witness-constants.d.mts.map +1 -0
  245. package/dist/witness/witness-constants.mjs +3 -0
  246. package/dist/witness/witness-constants.mjs.map +1 -0
  247. package/dist/witness/witness-form-builder.d.mts +45 -0
  248. package/dist/witness/witness-form-builder.d.mts.map +1 -0
  249. package/dist/witness/witness-form-builder.mjs +95 -0
  250. package/dist/witness/witness-form-builder.mjs.map +1 -0
  251. package/dist/witness/witness-helper.d.mts +89 -0
  252. package/dist/witness/witness-helper.d.mts.map +1 -0
  253. package/dist/witness/witness-helper.mjs +229 -0
  254. package/dist/witness/witness-helper.mjs.map +1 -0
  255. package/dist/witness/witness-types.d.mts +211 -0
  256. package/dist/witness/witness-types.d.mts.map +1 -0
  257. package/dist/witness/witness-types.mjs +2 -0
  258. package/dist/witness/witness-types.mjs.map +1 -0
  259. package/jasmine-browser.json +18 -0
  260. package/jasmine.json +6 -0
  261. package/package.json +67 -0
  262. package/src/assumptions.spec.mts +45 -0
  263. package/src/common/aws-constants.mts +5 -0
  264. package/src/common/bin/bin-types.mts +17 -0
  265. package/src/common/cache/cache-types.mts +53 -0
  266. package/src/common/comment/comment-constants.mts +10 -0
  267. package/src/common/comment/comment-helper.mts +211 -0
  268. package/src/common/comment/comment-types.mts +19 -0
  269. package/src/common/display/display-helper.mts +88 -0
  270. package/src/common/display/display-types.mts +108 -0
  271. package/src/common/encrypt/encrypt-constants.mts +28 -0
  272. package/src/common/encrypt/encrypt-types.mts +130 -0
  273. package/src/common/error/error-constants.mts +8 -0
  274. package/src/common/error/error-helper.mts +155 -0
  275. package/src/common/error/error-types.mts +62 -0
  276. package/src/common/form/form-helper.mts +253 -0
  277. package/src/common/form/form-items.mts +236 -0
  278. package/src/common/import-export/import-export-types.mts +18 -0
  279. package/src/common/legacy/about-legacy.md +0 -0
  280. package/src/common/legacy/legacy-types.mts +0 -0
  281. package/src/common/link/link-constants.mts +1 -0
  282. package/src/common/link/link-helper.mts +155 -0
  283. package/src/common/link/link-types.mts +16 -0
  284. package/src/common/other/graph-helper.mts +853 -0
  285. package/src/common/other/ibgib-helper.mts +671 -0
  286. package/src/common/other/other-constants.mts +76 -0
  287. package/src/common/other/other-types.mts +186 -0
  288. package/src/common/other/svg-constants.mts +1 -0
  289. package/src/common/other/svg-helper.mts +238 -0
  290. package/src/common/pic/pic-constants.mts +13 -0
  291. package/src/common/pic/pic-helper.mts +295 -0
  292. package/src/common/pic/pic-types.mts +29 -0
  293. package/src/common/root/root-constants.mts +41 -0
  294. package/src/common/root/root-types.mts +8 -0
  295. package/src/common/tag/tag-constants.mts +34 -0
  296. package/src/common/tag/tag-types.mts +19 -0
  297. package/src/core-constants.mts +506 -0
  298. package/src/core-helper.mts +33 -0
  299. package/src/core-types.mts +519 -0
  300. package/src/helper.spec.mts +64 -0
  301. package/src/index.mts +1 -0
  302. package/src/witness/app/app-base-v1.mts +584 -0
  303. package/src/witness/app/app-constants.mts +16 -0
  304. package/src/witness/app/app-helper.mts +322 -0
  305. package/src/witness/app/app-types.mts +252 -0
  306. package/src/witness/app/chat-app/chat-app-types.mts +40 -0
  307. package/src/witness/app/flash-app/flash-app-types.mts +38 -0
  308. package/src/witness/app/raw-app/raw-app-types.mts +40 -0
  309. package/src/witness/app/todo-app/todo-app-types.ts +59 -0
  310. package/src/witness/robbot/robbot-base-v1.ts +1531 -0
  311. package/src/witness/robbot/robbot-constants.mts +25 -0
  312. package/src/witness/robbot/robbot-helper.mts +676 -0
  313. package/src/witness/robbot/robbot-helper.spec.mts +135 -0
  314. package/src/witness/robbot/robbot-types.mts +797 -0
  315. package/src/witness/space/bootstrap/bootstrap-constants.mts +15 -0
  316. package/src/witness/space/inner-space-v1.ts +372 -0
  317. package/src/witness/space/outer-space/outer-space-constants.mts +1 -0
  318. package/src/witness/space/outer-space/outer-space-helper.mts +91 -0
  319. package/src/witness/space/outer-space/outer-space-types.mts +627 -0
  320. package/src/witness/space/space-base-v1.mts +414 -0
  321. package/src/witness/space/space-constants.mts +208 -0
  322. package/src/witness/space/space-helper.mts +3242 -0
  323. package/src/witness/space/space-types.mts +476 -0
  324. package/src/witness/witness-base-v1.ts +325 -0
  325. package/src/witness/witness-constants.mts +2 -0
  326. package/src/witness/witness-form-builder.mts +128 -0
  327. package/src/witness/witness-helper.mts +256 -0
  328. package/src/witness/witness-types.mts +249 -0
  329. package/tsconfig.json +15 -0
  330. package/tsconfig.test.json +10 -0
@@ -0,0 +1,1531 @@
1
+ import { Subscription } from 'rxjs/index.js';
2
+ import { filter } from 'rxjs/operators';
3
+
4
+ import { Gib, Ib, IbGibAddr, V1, getIbGibAddr } from '@ibgib/ts-gib';
5
+ import { getGibInfo, IbGib_V1, IbGibRel8ns_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';
6
+
7
+ import { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';
8
+ import {
9
+ RobbotData_V1, RobbotRel8ns_V1, RobbotIbGib_V1,
10
+ RobbotCmd,
11
+ RobbotCmdData, RobbotCmdRel8ns, RobbotCmdIbGib,
12
+ RobbotResultData, RobbotResultRel8ns, RobbotResultIbGib, ROBBOT_MY_COMMENTS_REL8N_NAME,
13
+ ROBBOT_CONTEXT_REL8N_NAME,
14
+ SemanticHandler,
15
+ SemanticId,
16
+ SemanticInfo,
17
+ RobbotInteractionData_V1,
18
+ RobbotInteractionType,
19
+ RobbotPropsData,
20
+ DEFAULT_ROBBOT_LEX_DATA,
21
+ DEFAULT_HUMAN_LEX_DATA,
22
+ SemanticHandlerResult,
23
+ } from './robbot-types.mjs';
24
+ import { WitnessBase_V1, } from '../witness-base-v1';
25
+ import { CommentIbGib_V1 } from '../../common/comment/comment-types.mjs';
26
+ import { PicIbGib_V1 } from '../../common/pic/pic-types.mjs';
27
+ import { getInteractionIbGib_V1, validateCommonRobbotData } from './robbot-helper.mjs';
28
+ import { argy_, isArg, resulty_ } from '../witness-helper.mjs';
29
+ import { IbGibLocalSpaceService_AllPowerful as IbgibsService } from '../../core-types.mjs';
30
+ import { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';
31
+ import { ErrorIbGib_V1 } from '../../common/error/error-types.mjs';
32
+ import { Lex, clone, delay, getTimestamp, getUUID, pretty } from '@ibgib/helper-gib';
33
+ import { errorIbGib } from '../../common/error/error-helper.mjs';
34
+ import { createCommentIbGib, parseCommentIb } from '../../common/comment/comment-helper.mjs';
35
+ import { getFromSpace, getLatestAddrs } from '../space/space-helper.mjs';
36
+ import { getTjpAddr } from '../../common/other/ibgib-helper.mjs';
37
+ import { IbGibTimelineUpdateInfo } from '../../common/other/other-types.mjs';
38
+
39
+ const logalot = GLOBAL_LOG_A_LOT || true;
40
+
41
+ /**
42
+ * ## distinguishing characteristics of robbots
43
+ *
44
+ * With any witness ibgib, we are concerned with interpreting an incoming
45
+ * arg ibgib and producing at least one result ibgib. Most often, there will
46
+ * be additional ibgibs created, either creating "new" ibgibs via `fork`
47
+ * transforms, or changing existing ibgibs through `mut8` and `rel8`
48
+ * transforms. And almost always these will be persisted in at least
49
+ * one space.
50
+ *
51
+ * But Robbots in particular are meant to be increasingly adaptable over time.
52
+ *
53
+ * This results in a couple of notes:
54
+ *
55
+ * 1. They should be able to handle any incoming ibgib, including primitives.
56
+ * 2. If they are learning robbots, then they will mutate internally at some rate.
57
+ * 3. Often robbots' output ibgib(s) will be intended for others'
58
+ * consumption, in service of others - be they humans or other
59
+ * biologically living organisms, other robbots or even later versions of
60
+ * themselves.
61
+ *
62
+ * So for example, one of the simplest robbots is one which simply echos the
63
+ * incoming ibgib arg.
64
+
65
+ * ## architecture
66
+ *
67
+ * At the base, any robbot should be able to handle any incoming ibgib. This is
68
+ * in contrast to, e.g., a Space, which is more rigid in design.
69
+ *
70
+ * Certainly there are robbot's who will be more rigid, but this will be an
71
+ * abstract class on top of this one, and all robbots should be able to react to
72
+ * all incoming ibgibs.
73
+ *
74
+ * Output will default to a simple ok^gib or (ROOT) ib^gib primitive...perhaps
75
+ * we'll go with ack^gib, but whatever it is, it's just an acknowledgement of
76
+ * input received. (I'll put it in the constants file).
77
+ *
78
+ * Side effects should occur in a parallel execution thread, which ideally would
79
+ * work in a completely parallel execution context (like a service worker). But
80
+ * then we have to deal with race conditions and the real solution there is to
81
+ * abstract to the robbot having its own space and the synchronization happening
82
+ * exactly like any other sync space.
83
+ *
84
+ * For now, we'll spin off a promise with some intermittent `await delay`
85
+ * calls if they end up called for, effectively the equivalent of the
86
+ * old-fashioned "ProcessMessages/DoEvents" hack.
87
+ */
88
+ export abstract class RobbotBase_V1<
89
+ TLexPropsData extends RobbotPropsData = RobbotPropsData,
90
+ TOptionsData extends any = any,
91
+ TOptionsRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1,
92
+ TOptionsIbGib extends IbGib_V1<TOptionsData, TOptionsRel8ns>
93
+ = IbGib_V1<TOptionsData, TOptionsRel8ns>,
94
+ TResultData extends any = any,
95
+ TResultRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1,
96
+ TResultIbGib extends IbGib_V1<TResultData, TResultRel8ns> | ErrorIbGib_V1
97
+ = IbGib_V1<TResultData, TResultRel8ns>,
98
+ TData extends RobbotData_V1 = RobbotData_V1,
99
+ TRel8ns extends RobbotRel8ns_V1 = RobbotRel8ns_V1,
100
+ >
101
+ extends WitnessBase_V1<
102
+ TOptionsData, TOptionsRel8ns, TOptionsIbGib,
103
+ TResultData, TResultRel8ns, TResultIbGib,
104
+ TData, TRel8ns>
105
+ implements RobbotIbGib_V1 {
106
+
107
+ /**
108
+ * Log context for convenience with logging. (Ignore if you don't want to use this.)
109
+ *
110
+ * Often used in conjunction with `logalot`.
111
+ */
112
+ protected lc: string = `${super.lc}[${RobbotBase_V1.name}]`;
113
+
114
+ /**
115
+ * Reference to the local ibgibs service, which is one way at getting at the
116
+ * local user space.
117
+ */
118
+ public ibgibsSvc: IbgibsService | undefined;
119
+
120
+ /**
121
+ * When the robbot has to get some ibgibs, might as well store them here so
122
+ * we don't have to get them again from storage.
123
+ */
124
+ protected _cacheIbGibs: { [addr: string]: IbGib_V1 } = {};
125
+
126
+
127
+ protected _contextChangesSubscription: Subscription | undefined;
128
+ protected _currentWorkingContextIbGib: IbGib_V1 | undefined;
129
+ /**
130
+ * when we get an update to the context, we want to know what the _new_
131
+ * children are in order to interpret comments from the user that may be
132
+ * directed at us.
133
+ *
134
+ * So we will get an initial snapshot of children that we will diff against.
135
+ * We could go via the dna, but ultimately a diff is what is needed.
136
+ */
137
+ protected _currentWorkingContextIbGib_PriorChildrenAddrs: IbGibAddr[] = [];
138
+
139
+ protected _updatingContext: boolean = false;
140
+
141
+ protected _semanticHandlers: { [semanticId: string]: SemanticHandler[] } = {};
142
+
143
+ protected async handleSemanticDefault(info: SemanticInfo): Promise<SemanticHandlerResult> {
144
+ const lc = `${this.lc}[${this.handleSemanticDefault.name}]`;
145
+ try {
146
+ if (logalot) { console.log(`${lc} starting... (I: 01a2d1781851cc36b674f44b4fb69522)`); }
147
+ if (!this._robbotLex) { throw new Error(`robbotLex not initialized (E: 7be2a470645eab44ca950e9ec8b72723)`); }
148
+
149
+ const speech = this._robbotLex.get(SemanticId.unknown, {
150
+ props: (props: TLexPropsData) =>
151
+ props.semanticId === SemanticId.unknown,
152
+ });
153
+
154
+ const data = await this.getRobbotInteractionData({
155
+ type: RobbotInteractionType.info,
156
+ commentText: speech?.text ?? 'hmm, something went wrogn Dave',
157
+ });
158
+
159
+ const interaction = await getInteractionIbGib_V1({ data });
160
+ return { interaction };
161
+ } catch (error) {
162
+ console.error(`${lc} ${error.message}`);
163
+ throw error;
164
+ } finally {
165
+ if (logalot) { console.log(`${lc} complete.`); }
166
+ }
167
+ }
168
+
169
+ /**
170
+ * lex that the robbot uses to speak.
171
+ */
172
+ protected _robbotLex: Lex<TLexPropsData> | undefined;
173
+ /**
174
+ * lex that the robbot uses to interpret humans.
175
+ */
176
+ protected _userLex: Lex<TLexPropsData> | undefined;
177
+
178
+ /**
179
+ * This should be awaited before dealing with the robbot.
180
+ *
181
+ * I'm keeping this named `ready` as a shout out to
182
+ * https://stackoverflow.com/a/45070748/3897838
183
+ * (https://stackoverflow.com/questions/35743426/async-constructor-functions-in-typescript).
184
+ *
185
+ * ## comments
186
+ *
187
+ * I've been considering going forward whether or not to have robbots'
188
+ * properties all be observables to allow for subscribing to events or
189
+ * similar in the future. But this may fight against the single `witness`
190
+ * point of contact, which of course itself is somewhat experimental. One
191
+ * grand experiment.
192
+ *
193
+ * I do have an observable as a property for the aws sync space saga
194
+ * updates. This kind of observable can be passed around while still using
195
+ * the single `witness` access point, but of course these runtime aspects
196
+ * won't be memoized if storing the ibgib.
197
+ */
198
+ public initialized: Promise<void>;
199
+
200
+ constructor(initialData?: TData, initialRel8ns?: TRel8ns) {
201
+ super(initialData, initialRel8ns);
202
+ this.initialized = this.initialize();
203
+ }
204
+
205
+ // #region initialize
206
+
207
+ /**
208
+ * Initializes to default space values.
209
+ */
210
+ protected async initialize(): Promise<void> {
211
+ const lc = `${this.lc}[${this.initialize.name}]`;
212
+ try {
213
+ if (logalot) { console.log(`${lc} starting... (I: f0e65ab0f80046a59668ddfbf9f47a4a5)`); }
214
+
215
+ await this.initialize_semanticHandlers();
216
+ await this.initialize_lex();
217
+ } catch (error) {
218
+ console.error(`${lc} ${error.message}`);
219
+ } finally {
220
+ if (logalot) { console.log(`${lc} complete.`); }
221
+ }
222
+ }
223
+
224
+ protected async initialize_semanticHandlers(): Promise<void> {
225
+ const lc = `${this.lc}[${this.initialize_semanticHandlers.name}]`;
226
+ try {
227
+ if (logalot) { console.log(`${lc} starting... (I: a0f2a11688963b0156e337e7f8604f22)`); }
228
+ this._semanticHandlers = {
229
+ [SemanticId.default]: [
230
+ {
231
+ handlerId: "c8054c0b77fb4b37bff693e54e1f66bd",
232
+ semanticId: SemanticId.default,
233
+ fnCanExec: (info) => Promise.resolve(true),
234
+ fnExec: (info) => { return this.handleSemanticDefault(info); },
235
+ }
236
+ ],
237
+ [SemanticId.unknown]: [
238
+ {
239
+ handlerId: "9eb4c537cddb40d4927c2aa58e4e6f4b",
240
+ semanticId: SemanticId.default,
241
+ fnCanExec: (info) => Promise.resolve(true),
242
+ fnExec: (info) => { return this.handleSemanticDefault(info); },
243
+ }
244
+ ],
245
+ }
246
+ } catch (error) {
247
+ console.error(`${lc} ${error.message}`);
248
+ throw error;
249
+ } finally {
250
+ if (logalot) { console.log(`${lc} complete.`); }
251
+ }
252
+ }
253
+
254
+ protected async initialize_lex(): Promise<void> {
255
+ const lc = `${this.lc}[${this.initialize_lex.name}]`;
256
+ try {
257
+ if (logalot) { console.log(`${lc} starting... (I: a4668a7473027e56df42909c09f70822)`); }
258
+ this._robbotLex = new Lex<TLexPropsData>(clone(DEFAULT_ROBBOT_LEX_DATA), {
259
+ defaultPropsMode: 'props',
260
+ defaultKeywordMode: 'all',
261
+ defaultLineConcat: 'paragraph', // outgoing robbot defaults to multiple paragraphs.
262
+ });
263
+
264
+ this._robbotLex.data[SemanticId.unknown] = [
265
+ {
266
+ texts: [
267
+ `huh?`, // silly
268
+ ],
269
+ props: <TLexPropsData>{
270
+ semanticId: SemanticId.unknown,
271
+ }
272
+ }
273
+ ];
274
+
275
+ this._userLex = new Lex<TLexPropsData>(clone(DEFAULT_HUMAN_LEX_DATA), {
276
+ defaultPropsMode: 'props',
277
+ defaultKeywordMode: 'all',
278
+ defaultLineConcat: 'sentence', // incoming user lex defaults to combining sentences.
279
+ });
280
+ } catch (error) {
281
+ console.error(`${lc} ${error.message}`);
282
+ throw error;
283
+ } finally {
284
+ if (logalot) { console.log(`${lc} complete.`); }
285
+ }
286
+ }
287
+
288
+ // #endregion initialize
289
+
290
+ protected async loadNewerSelfIfAvailable(): Promise<void> {
291
+ const lc = `${this.lc}[${this.loadNewerSelfIfAvailable.name}]`;
292
+ try {
293
+ if (logalot) { console.log(`${lc} starting... (I: 94755c3131f4dfa12d20fa38e2926522)`); }
294
+ if (this.ibgibsSvc) {
295
+ // check for newer version of self locally before executing
296
+ const robbotAddr = getIbGibAddr({ ibGib: this });
297
+ const latestAddr = await this.ibgibsSvc.getLatestAddr({ ibGib: this });
298
+ if (latestAddr && latestAddr !== robbotAddr) {
299
+ // robbot has a newer ibgib in its timeline
300
+ let resGet = await this.ibgibsSvc.get({ addr: latestAddr });
301
+ if (!resGet || !resGet?.success || (resGet?.ibGibs ?? []).length === 0) {
302
+ throw new Error(`could not get newer robbot ibgib (E: 15fa346c8ac17edb96e4b0870104c122)`);
303
+ }
304
+ await this.loadIbGibDto(resGet.ibGibs![0] as IbGib_V1<TData, TRel8ns>);
305
+ const validationErrors = await this.validateThis();
306
+ if (validationErrors?.length > 0) { throw new Error(`validationErrors when loading newer version: ${pretty(validationErrors)} (E: 0d9f0684a1ff6af44e20a57130e3ac22)`); }
307
+ }
308
+ } else {
309
+ console.warn(`${lc} this.ibgibsSvc undefined (W: 44cc5bf1b14b4695b8de4c589787be06)`);
310
+ }
311
+
312
+ } catch (error) {
313
+ console.error(`${lc} ${error.message}`);
314
+ throw error;
315
+ } finally {
316
+ if (logalot) { console.log(`${lc} complete.`); }
317
+ }
318
+ }
319
+ /**
320
+ * At this point in time, the arg has already been intrinsically validated,
321
+ * as well as the internal state of this robbot. so whatever this robbot's
322
+ * function is, it should be good to go.
323
+ *
324
+ * In the base class, this just returns {@link routeAndDoArg}. If you don't
325
+ * want to route, then override this.
326
+ */
327
+ protected async witnessImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {
328
+ const lc = `${this.lc}[${this.witnessImpl.name}]`;
329
+ try {
330
+ if (logalot) { console.log(`${lc} starting...`); }
331
+
332
+ await this.loadNewerSelfIfAvailable();
333
+
334
+ return this.routeAndDoArg({ arg });
335
+ } catch (error) {
336
+ console.error(`${lc} ${error.message}`);
337
+ throw error;
338
+ } finally {
339
+ if (logalot) { console.log(`${lc} complete.`); }
340
+ }
341
+ }
342
+
343
+ /**
344
+ * Base routing executes different if incoming is a cmd options arg, i.e.,
345
+ * if the `data.cmd` is truthy (atow). If {@link isArg} is true, then routes
346
+ * to {@link doCmdArg}; else routes to {@link doDefault}.
347
+ *
348
+ * Override this function to create more advanced custom routing.
349
+ *
350
+ * ## notes
351
+ *
352
+ * I'm not overly thrilled with this, but it's a watered down version of
353
+ * what I've implemented in the space witness hierarchy.
354
+ *
355
+ * @see {@link isArg}
356
+ * @see {@link doCmdArg}
357
+ * @see {@link doDefault}.
358
+ */
359
+ protected async routeAndDoArg({
360
+ arg,
361
+ }: {
362
+ arg: TOptionsIbGib,
363
+ }): Promise<TResultIbGib | undefined> {
364
+ const lc = `${this.lc}[${this.routeAndDoArg.name}]`;
365
+ try {
366
+ if (logalot) { console.log(`${lc} starting...`); }
367
+ if (isArg({ ibGib: arg as IbGib_V1 })) {
368
+ if ((arg.data as any)?.cmd) {
369
+ return this.doCmdArg({ arg: <RobbotCmdIbGib<IbGib_V1, RobbotCmdData, RobbotCmdRel8ns>>arg });
370
+ } else {
371
+ return this.doDefault({ ibGib: arg });
372
+ }
373
+ }
374
+ } catch (error) {
375
+ console.error(`${lc} ${error.message}`);
376
+ if (this.data?.catchAllErrors) {
377
+ return <TResultIbGib>(await errorIbGib({ rawMsg: error.message }));
378
+ } else {
379
+ throw error;
380
+ }
381
+ } finally {
382
+ if (logalot) { console.log(`${lc} complete.`); }
383
+ }
384
+ }
385
+
386
+ // #region do cmd args
387
+
388
+ /**
389
+ * By default, this routes to {@link doCmdIb}, {@link doCmdGib} & {@link doCmdIbgib}.
390
+ * Override this and route to other commands before calling this with `super.doCmdArg`
391
+ * (if you still want to use this function.)
392
+ *
393
+ * You can also override the routing
394
+ */
395
+ protected doCmdArg({
396
+ arg,
397
+ }: {
398
+ arg: RobbotCmdIbGib<IbGib_V1, RobbotCmdData, RobbotCmdRel8ns>,
399
+ }): Promise<TResultIbGib> {
400
+ const lc = `${this.lc}[${this.doCmdArg.name}]`;
401
+ try {
402
+ if (logalot) { console.log(`${lc} starting...`); }
403
+ if (!arg.data?.cmd) { throw new Error(`invalid cmd arg. arg.data.cmd required. (E: aec4dd5bd967fbf36f9c4fad22210222)`); }
404
+ if (arg.data.cmd === RobbotCmd.ib) {
405
+ return this.doCmdIb({ arg: arg });
406
+ } else if (arg.data.cmd === RobbotCmd.gib) {
407
+ return this.doCmdGib({ arg: arg });
408
+ } else if (arg.data.cmd === RobbotCmd.ibgib) {
409
+ return this.doCmdIbgib({ arg: arg });
410
+ } else if (arg.data.cmd === RobbotCmd.activate) {
411
+ return this.doCmdActivate({ arg: arg });
412
+ } else if (arg.data.cmd === RobbotCmd.deactivate) {
413
+ return this.doCmdDeactivate({ arg: arg });
414
+ } else {
415
+ throw new Error(`unknown arg.data.cmd: ${arg.data.cmd} (E: 721fa6a5166327134f9504c1caa3e422)`);
416
+ }
417
+ } catch (error) {
418
+ console.error(`${lc} ${error.message}`);
419
+ throw error;
420
+ } finally {
421
+ if (logalot) { console.log(`${lc} complete.`); }
422
+ }
423
+ }
424
+
425
+ protected doCmdIb({
426
+ arg,
427
+ }: {
428
+ arg: IbGib_V1,
429
+ }): Promise<TResultIbGib> {
430
+ const lc = `${this.lc}[${this.doCmdIb.name}]`;
431
+ try {
432
+ if (logalot) { console.log(`${lc} starting...`); }
433
+ throw new Error(`not implemented in base class (E: 7298662a2b8f67611d16a8af0e499422)`);
434
+ } catch (error) {
435
+ console.error(`${lc} ${error.message}`);
436
+ throw error;
437
+ } finally {
438
+ if (logalot) { console.log(`${lc} complete.`); }
439
+ }
440
+ }
441
+ protected doCmdGib({
442
+ arg,
443
+ }: {
444
+ arg: IbGib_V1,
445
+ }): Promise<TResultIbGib> {
446
+ const lc = `${this.lc}[${this.doCmdGib.name}]`;
447
+ try {
448
+ if (logalot) { console.log(`${lc} starting...`); }
449
+ throw new Error(`not implemented in base class (E: b6bf2c788c734051956481be7283d006)`);
450
+ } catch (error) {
451
+ console.error(`${lc} ${error.message}`);
452
+ throw error;
453
+ } finally {
454
+ if (logalot) { console.log(`${lc} complete.`); }
455
+ }
456
+ }
457
+ protected doCmdIbgib({
458
+ arg,
459
+ }: {
460
+ arg: IbGib_V1,
461
+ }): Promise<TResultIbGib> {
462
+ const lc = `${this.lc}[${this.doCmdIbgib.name}]`;
463
+ try {
464
+ if (logalot) { console.log(`${lc} starting...`); }
465
+ throw new Error(`not implemented in base class (E: 4fee11f05315467abd036cd8555d27db)`);
466
+ } catch (error) {
467
+ console.error(`${lc} ${error.message}`);
468
+ throw error;
469
+ } finally {
470
+ if (logalot) { console.log(`${lc} complete.`); }
471
+ }
472
+ }
473
+ protected async doCmdActivate({
474
+ arg,
475
+ }: {
476
+ arg: RobbotCmdIbGib,
477
+ }): Promise<TResultIbGib> {
478
+ const lc = `${this.lc}[${this.doCmdActivate.name}]`;
479
+ try {
480
+ if (logalot) { console.log(`${lc} starting... (I: d453593a295d4cdbae2acb71d9f6de35)`); }
481
+ await this.initialized;
482
+
483
+ if (!arg) { throw new Error(`arg required (E: 9cddabc6dc96ddb37846807feb093423)`); }
484
+
485
+ if (arg.ibGibs?.length ?? 0 > 0) {
486
+ await this.initializeContext({ arg });
487
+ }
488
+
489
+ const result = await this.resulty({
490
+ resultData: {
491
+ optsAddr: getIbGibAddr({ ibGib: arg }),
492
+ success: true,
493
+ },
494
+ })
495
+ return <TResultIbGib>result;
496
+ } catch (error) {
497
+ console.error(`${lc} ${error.message}`);
498
+ throw error;
499
+ } finally {
500
+ if (logalot) { console.log(`${lc} complete.`); }
501
+ }
502
+ }
503
+ protected async doCmdDeactivate({
504
+ arg,
505
+ }: {
506
+ arg: RobbotCmdIbGib,
507
+ }): Promise<TResultIbGib> {
508
+ const lc = `${this.lc}[${this.doCmdDeactivate.name}]`;
509
+ try {
510
+ if (logalot) { console.log(`${lc} starting... (I: d453593a295d4cdbae2acb71d9f6de35)`); }
511
+ await this.initialized;
512
+
513
+ await this.finalizeContext({ arg });
514
+
515
+ const result = await this.resulty({
516
+ resultData: {
517
+ optsAddr: getIbGibAddr({ ibGib: arg }),
518
+ success: true,
519
+ },
520
+ })
521
+ return <TResultIbGib>result;
522
+ } catch (error) {
523
+ console.error(`${lc} ${error.message}`);
524
+ throw error;
525
+ } finally {
526
+ if (logalot) { console.log(`${lc} complete.`); }
527
+ }
528
+ }
529
+
530
+ // #endregion do cmd args
531
+
532
+ // #region other stubbed do functions (doPic, doComment, doDefault)
533
+
534
+ /**
535
+ * Stubbed in base class for convenience. Doesn't have to be implemented.
536
+ */
537
+ protected doPic({
538
+ ibGib,
539
+ }: {
540
+ ibGib: PicIbGib_V1,
541
+ }): Promise<TResultIbGib | undefined> {
542
+ const lc = `${this.lc}[${this.doPic.name}]`;
543
+ try {
544
+ if (logalot) { console.log(`${lc} starting...`); }
545
+ throw new Error(`not implemented in base class (E: 16ba889931644d42ad9e476757dd0617)`);
546
+ } catch (error) {
547
+ console.error(`${lc} ${error.message}`);
548
+ throw error;
549
+ } finally {
550
+ if (logalot) { console.log(`${lc} complete.`); }
551
+ }
552
+ }
553
+
554
+ /**
555
+ * Stubbed in base class for convenience. Doesn't have to be implemented.
556
+ */
557
+ protected doComment({
558
+ ibGib,
559
+ }: {
560
+ ibGib: CommentIbGib_V1,
561
+ }): Promise<TResultIbGib | undefined> {
562
+ const lc = `${this.lc}[${this.doComment.name}]`;
563
+ try {
564
+ if (logalot) { console.log(`${lc} starting...`); }
565
+
566
+ throw new Error(`not implemented in base class (E: 0486a7864729456d993a1afe246faea4)`);
567
+ } catch (error) {
568
+ console.error(`${lc} ${error.message}`);
569
+ throw error;
570
+ } finally {
571
+ if (logalot) { console.log(`${lc} complete.`); }
572
+ }
573
+ }
574
+
575
+ /**
576
+ * Stubbed in base class for convenience. Doesn't have to be implemented.
577
+ */
578
+ protected doDefault({
579
+ ibGib,
580
+ }: {
581
+ ibGib: TOptionsIbGib,
582
+ }): Promise<TResultIbGib | undefined> {
583
+ const lc = `${this.lc}[${this.doDefault.name}]`;
584
+ try {
585
+ if (logalot) { console.log(`${lc} starting...`); }
586
+ throw new Error(`not implemented in base class (E: 5038662186617aaf1f0cc698fd1f9622)`);
587
+ // return this.doDefaultImpl({ibGib});
588
+ } catch (error) {
589
+ console.error(`${lc} ${error.message}`);
590
+ throw error;
591
+ } finally {
592
+ if (logalot) { console.log(`${lc} complete.`); }
593
+ }
594
+ }
595
+
596
+ // #endregion other stubbed do functions (doPic, doComment, doDefault)
597
+
598
+ /**
599
+ * By default, this...
600
+ *
601
+ * * performs the raw {@link rel8} transform to the given `ibGib`.
602
+ * * persists the new ibgib's transform result in the given space.
603
+ * * registers the newer version of this robbot ibgib with the ibgibs svc.
604
+ *
605
+ * @see {@link ibGibs}
606
+ * @see {@link rel8nName}
607
+ * @see {@link ibgibsSvc}
608
+ * @see {@link space}
609
+ *
610
+ * ## notes
611
+ *
612
+ * * If there is no given `space`, then we will use the `ibgibsSvc` to get
613
+ * the local user space. If none, then we skip persistence.
614
+ * * If there is no `ibgibsSvc`, we won't register the new ibgibs locally.
615
+ */
616
+ protected async rel8To({
617
+ ibGibs,
618
+ rel8nName,
619
+ linked,
620
+ ibgibsSvc,
621
+ // space,
622
+ }: {
623
+ /**
624
+ * The ibgib to which we are relating.
625
+ */
626
+ ibGibs: IbGib_V1[],
627
+ /**
628
+ * If given, will use this as the rel8n name when performing the `rel8`
629
+ * transform.
630
+ *
631
+ * If not given, will use the `robbot.data`'s {@link RobbotData_V1.defaultRel8nName} value.
632
+ */
633
+ rel8nName?: string,
634
+ /**
635
+ * If true, will include the `rel8nName` as a linked rel8n in the `rel8`
636
+ * transform.
637
+ */
638
+ linked?: boolean,
639
+ /**
640
+ * If provided, will register the newly created ibgib.
641
+ */
642
+ ibgibsSvc?: IbgibsService,
643
+ // /**
644
+ // * If given (which atow is most likely the case), then the {@link TransformResult} will
645
+ // * be persisted in this `space`.
646
+ // */
647
+ // space?: IbGibSpaceAny,
648
+ }): Promise<void> {
649
+ const lc = `${this.lc}[${this.rel8To.name}]`;
650
+ try {
651
+ if (logalot) { console.log(`${lc} starting...`); }
652
+
653
+ // #region initialize, validate args and this
654
+
655
+ if ((ibGibs ?? []).length === 0) { throw new Error(`ibGibs required (E: 2fd13de0f025b170885bede4d7a50922)`); }
656
+
657
+ rel8nName = rel8nName || this.data?.defaultRel8nName;
658
+ if (!rel8nName) { throw new Error(`rel8nName required either as an arg or in this.data.defaultRel8nName (E: 43ab8ae63694a2a82cd8a70ed6b6b522)`); }
659
+
660
+ const thisValidationErrors = await this.validateThis();
661
+ if (thisValidationErrors?.length > 0) { throw new Error(`this is an invalid ibGib. thisValidationErrors: ${thisValidationErrors.join('|')} (E: 8f08716866cd13bf254222ee9e6a6722)`); }
662
+
663
+ ibgibsSvc = ibgibsSvc ?? this.ibgibsSvc;
664
+
665
+ if (!ibgibsSvc) {
666
+ // if (this.ibgibsSvc) {
667
+ // if (logalot) { console.log(`${lc} ibgibsSvc arg falsy, but we have a reference on this object, which we will use. (I: ee0d39a47ee8aee8ffd797721fea4322)`); }
668
+ // ibgibsSvc = this.ibgibsSvc;
669
+ // }
670
+ throw new Error(`either ibgibsSvc or this.ibgibsSvc required (E: b5f9453ddb394a2b76dec74c7304df22)`);
671
+ }
672
+
673
+ // if (!space) {
674
+ // if (ibgibsSvc) {
675
+ // if (logalot) { console.log(`${lc} space arg falsy, but ibgibsSvc truthy, so we'll use ibgibsSvc's local user space for persistence. (I: 37a4b4c1406556cb23831671755b0d22)`); }
676
+ // space = await ibgibsSvc.getLocalUserSpace({ lock: true });
677
+ // }
678
+ // }
679
+
680
+ // if (!space) { throw new Error(`(UNEXPECTED) space required and ibgibsSvc couldn't get it? (E: a3b9f9b72f6f6f18883199a19d38c622)`); }
681
+
682
+ // #endregion initialize, validate args and this
683
+
684
+ // we want to rel8 only to the ibGibs whose timelines we're not
685
+ // already related to. So we look to see if we already have the tjpGib
686
+ // per our rel8nName.
687
+ // if (!this.rel8ns) { this.rel8ns = {} as any };
688
+ const alreadyRel8dAddrs = this.rel8ns ? this.rel8ns[rel8nName] ?? [] : [];
689
+ const alreadyRel8dTjpGibs = alreadyRel8dAddrs.map(x => getGibInfo({ ibGibAddr: x }).tjpGib);
690
+ const ibGibsNotYetRel8dByTjp = ibGibs.filter(x => {
691
+ const tjpGib = getGibInfo({ ibGibAddr: getIbGibAddr({ ibGib: x }) }).tjpGib;
692
+ return !alreadyRel8dTjpGibs.includes(tjpGib);
693
+ });
694
+
695
+ if (ibGibsNotYetRel8dByTjp.length === 0) {
696
+ if (logalot) { console.log(`${lc} already rel8d to all incoming ibGib(s) via tjp. (I: 5e9d94a98ba262f146c0c0b765157922)`); }
697
+ return; /* <<<< returns early */
698
+ }
699
+
700
+ // perform the raw ibgib rel8 transform
701
+ const addrs = ibGibsNotYetRel8dByTjp.map(x => getIbGibAddr({ ibGib: x }));
702
+ const resNewRobbot = await V1.rel8({
703
+ src: this.toIbGibDto(),
704
+ rel8nsToAddByAddr: { [rel8nName]: addrs },
705
+ linkedRel8ns: linked ? ["past", "ancestor", rel8nName] : ["past", "ancestor"],
706
+ dna: true,
707
+ nCounter: true,
708
+ });
709
+ const newRobbotIbGib = resNewRobbot.newIbGib as any as IbGib_V1<TData, TRel8ns>;
710
+ const newRobbotValidationErrors =
711
+ await validateIbGibIntrinsically({ ibGib: newRobbotIbGib as any });
712
+ if (newRobbotValidationErrors?.length ?? 0 > 0) { throw new Error(`new robbot would have validation errors. aborting. newRobbotValidationErrors: ${newRobbotValidationErrors!.join('|')} (E: eb816a27156c246c121ef55e37d59322)`); }
713
+
714
+ // if space is given, perform the persistence
715
+ // if (space) {
716
+ await ibgibsSvc.persistTransformResult({ resTransform: resNewRobbot });
717
+ // } else {
718
+ // if (logalot) { console.log(`${lc} space falsy, skipping persistence (I: 90aa3553e92ad1d02bce61f83648ea22)`); }
719
+ // }
720
+
721
+ // if ibgibs svc is given, register the new ibgib
722
+ // (in the future, need to revisit the ibgibs service to the idea of locality/ies).
723
+ // if (ibgibsSvc) {
724
+ await ibgibsSvc.registerNewIbGib({ ibGib: newRobbotIbGib });
725
+ // } else {
726
+ // if (logalot) { console.log(`${lc} ibgibsSvc falsy so skipping registerNewIbGib for new robbot (I: eda4f68fffaf2435eba25cd39d4f2922)`); }
727
+ // }
728
+
729
+ // update this witness' primary ibGib properties (ib, gib, data, rel8ns).
730
+ // override `loadIbGibDto` to update secondary/derivative properties
731
+ await this.loadIbGibDto(newRobbotIbGib);
732
+ } catch (error) {
733
+ console.error(`${lc} ${error.message}`);
734
+ throw error;
735
+ } finally {
736
+ if (logalot) { console.log(`${lc} complete.`); }
737
+ }
738
+ }
739
+
740
+ /**
741
+ * validates against common robbot qualities.
742
+ *
743
+ * Override this with a call to `super.validateThis` for custom validation
744
+ * for descending robbot classes.
745
+ *
746
+ * @returns validation errors common to all robbots, if any errors exist.
747
+ */
748
+ protected async validateThis(): Promise<string[]> {
749
+ const lc = `${this.lc}[${this.validateThis.name}]`;
750
+ try {
751
+ if (logalot) { console.log(`${lc} starting...`); }
752
+ const errors = [
753
+ // ...await super.validateThis(),
754
+ ...validateCommonRobbotData({ robbotData: this.data }),
755
+ ];
756
+ return errors;
757
+ } catch (error) {
758
+ console.error(`${lc} ${error.message}`);
759
+ throw error;
760
+ } finally {
761
+ if (logalot) { console.log(`${lc} complete.`); }
762
+ }
763
+ }
764
+
765
+ /**
766
+ * builds an arg ibGib.
767
+ *
768
+ * wrapper convenience to avoid long generic calls.
769
+ */
770
+ async argy<
771
+ TCmdOptionsData extends RobbotCmdData = RobbotCmdData,
772
+ TCmdOptionsRel8ns extends RobbotCmdRel8ns = RobbotCmdRel8ns,
773
+ TCmdOptionsIbGib extends RobbotCmdIbGib<IbGib_V1, TCmdOptionsData, TCmdOptionsRel8ns> =
774
+ RobbotCmdIbGib<IbGib_V1, TCmdOptionsData, TCmdOptionsRel8ns>
775
+ >({
776
+ argData,
777
+ ibMetadata,
778
+ noTimestamp,
779
+ ibGibs,
780
+ }: {
781
+ argData: TCmdOptionsData,
782
+ ibMetadata?: string,
783
+ noTimestamp?: boolean,
784
+ ibGibs?: IbGib_V1[],
785
+ }): Promise<TCmdOptionsIbGib> {
786
+ const arg = await argy_<TCmdOptionsData, TCmdOptionsRel8ns, TCmdOptionsIbGib>({
787
+ argData,
788
+ ibMetadata,
789
+ noTimestamp
790
+ });
791
+
792
+ if (ibGibs) { arg.ibGibs = ibGibs; }
793
+
794
+ return arg;
795
+ }
796
+
797
+ /**
798
+ * builds a result ibGib, if indeed a result ibgib is required.
799
+ *
800
+ * This is only useful in robbots that have more structured inputs/outputs.
801
+ * For those that simply accept any ibgib incoming and return a
802
+ * primitive like ib^gib or whatever, then this is unnecessary.
803
+ *
804
+ * wrapper convenience to avoid long generic calls.
805
+ */
806
+ async resulty<
807
+ TResultData extends RobbotResultData = RobbotResultData,
808
+ TResultRel8ns extends RobbotResultRel8ns = RobbotResultRel8ns,
809
+ TResultIbGib extends RobbotResultIbGib<IbGib_V1, TResultData, TResultRel8ns> =
810
+ RobbotResultIbGib<IbGib_V1, TResultData, TResultRel8ns>
811
+ >({
812
+ resultData,
813
+ ibGibs,
814
+ }: {
815
+ resultData: TResultData,
816
+ ibGibs?: IbGib_V1[],
817
+ }): Promise<TResultIbGib> {
818
+ const result = await resulty_<TResultData, TResultIbGib>({
819
+ // ibMetadata: getRobbotResultMetadata({space: this}),
820
+ resultData,
821
+ });
822
+ if (ibGibs) { result.ibGibs = ibGibs; }
823
+ return result;
824
+ }
825
+
826
+ protected async rel8ToContextIbGib({
827
+ ibGibToRel8,
828
+ ibGibAddrToRel8,
829
+ contextIbGib,
830
+ rel8nNames,
831
+ // space,
832
+ }: {
833
+ ibGibToRel8?: IbGib_V1,
834
+ ibGibAddrToRel8?: IbGibAddr,
835
+ contextIbGib: IbGib_V1,
836
+ rel8nNames: string[],
837
+ // space?: IbGibSpaceAny,
838
+ }): Promise<void> {
839
+ const lc = `${this.lc}[${this.rel8ToContextIbGib.name}]`;
840
+ try {
841
+ if (!ibGibToRel8 && !ibGibAddrToRel8) { throw new Error(`ibGibToRel8 or ibGibAddrToRel8 required (E: 3ee14659fd22355a5ba0e537a477be22)`); }
842
+ if (!contextIbGib) { throw new Error(`contextIbGib required (E: 85f27c7cbf713704c21084c141cd8822)`); }
843
+ if (!this.ibgibsSvc) { throw new Error(`this.ibgibsSvc required (E: 6a38c4274bdefc8d44cafd2d6faaa222)`); }
844
+
845
+ // space = space ?? await this.ibgibsSvc.getLocalUserSpace({ lock: true });
846
+ // if (!space) { throw new Error(`space required (E: 267ad87c148942cda641349df0bbbd22)`); }
847
+
848
+ if ((rel8nNames ?? []).length === 0) {
849
+ if (!this.data?.defaultRel8nName) { throw new Error(`either rel8nNames or this.data.defaultRel8nName required (E: a14ab4b3e479d9274c61bc5a30bc2222)`); }
850
+ rel8nNames = [this.data.defaultRel8nName];
851
+ }
852
+
853
+ // set up the rel8ns to add
854
+ const rel8nsToAddByAddr: IbGibRel8ns_V1 = {};
855
+ ibGibAddrToRel8 = ibGibAddrToRel8 || getIbGibAddr({ ibGib: ibGibToRel8 });
856
+ rel8nNames.forEach((rel8nName) => { rel8nsToAddByAddr[rel8nName] = [ibGibAddrToRel8!]; });
857
+
858
+ // perform the rel8 transform and...
859
+ const resRel8ToContext =
860
+ await V1.rel8({
861
+ src: contextIbGib,
862
+ rel8nsToAddByAddr,
863
+ dna: true,
864
+ nCounter: true
865
+ });
866
+
867
+ // ...persist it...
868
+ await this.ibgibsSvc.persistTransformResult({ resTransform: resRel8ToContext });
869
+
870
+ // ...register the context.
871
+ const { newIbGib: newContext } = resRel8ToContext;
872
+ await this.ibgibsSvc.registerNewIbGib({ ibGib: newContext });
873
+ } catch (error) {
874
+ console.error(`${lc} ${error.message}`);
875
+ throw error;
876
+ }
877
+ }
878
+
879
+ protected async createCommentAndRel8ToContextIbGib({
880
+ text,
881
+ contextIbGib,
882
+ }: {
883
+ text: string,
884
+ contextIbGib: IbGib_V1,
885
+ ibgibsSvc?: IbgibsService,
886
+ }): Promise<void> {
887
+ const lc = `${this.lc}[${this.createCommentAndRel8ToContextIbGib.name}]`;
888
+ try {
889
+ if (logalot) { console.log(`${lc} starting... (I: c3a005f7d323468a5b4e1b2710901d22)`); }
890
+
891
+ if (!this.ibgibsSvc) { throw new Error(`this.ibgibsSvc required (E: 5dbb1a7f0ff5469b8ce3cb1be175e521)`); }
892
+
893
+ // space = space ?? await this.ibgibsSvc.getLocalUserSpace({ lock: true });
894
+ // if (!space) { throw new Error(`(UNEXPECTED) space required and wasn't able to get it from ibgibsSvc? (E: 7159f9893a66c28a7e09b61384545622)`); }
895
+ let space = await this.ibgibsSvc.getLocalUserSpace({ lock: true });
896
+
897
+ /** tag this comment with metadata to show it came from this robbot */
898
+ let resComment = await createCommentIbGib({ text, addlMetadataText: this.getAddlMetadata(), saveInSpace: true, space });
899
+
900
+ // get again to be sure it's the latest space.
901
+ space = await this.ibgibsSvc.getLocalUserSpace({ lock: true });
902
+
903
+ const commentIbGib = resComment.newIbGib as CommentIbGib_V1;
904
+ if (!commentIbGib) { throw new Error(`(UNEXPECTED) failed to create comment? (E: 6d668f4e55198e654324622eabaac922)`); }
905
+ await this.ibgibsSvc.registerNewIbGib({ ibGib: commentIbGib });
906
+
907
+ await this.rel8ToContextIbGib({ ibGibToRel8: commentIbGib, contextIbGib, rel8nNames: ['comment'] });
908
+ await this.rel8To({
909
+ ibGibs: [commentIbGib],
910
+ rel8nName: ROBBOT_MY_COMMENTS_REL8N_NAME,
911
+ });
912
+ } catch (error) {
913
+ console.error(`${lc} ${error.message}`);
914
+ throw error;
915
+ } finally {
916
+ if (logalot) { console.log(`${lc} complete.`); }
917
+ }
918
+ }
919
+
920
+ /**
921
+ * used to identify when comments are made by these robbots.
922
+ *
923
+ * atow this is `robbot_${this.data.classname}_${this.data.name}_${this.data.uuid.slice(0, 8)}`;
924
+ *
925
+ * @returns addlmetadata string to be used in comment ib's
926
+ */
927
+ protected getAddlMetadata(): string {
928
+ const lc = `${this.lc}[${this.getAddlMetadata.name}]`;
929
+ try {
930
+ if (logalot) { console.log(`${lc} starting... (I: 7800732facf3783943fdf1b2423b0c22)`); }
931
+ if (!this.data) { throw new Error(`(UNEXPECTED) this.data falsy? (E: 7cb044b39b2b8e31f363f3b82f256323)`); }
932
+ const classnameIsh = this.data.classname?.replace(/[_]/mg, '') || undefined;
933
+ const robbotNameIsh = this.data.name?.slice(0, 8).replace(/[__]/mg, '') || undefined;
934
+ const robbotIdIsh = this.data.uuid?.slice(0, 8) || undefined;
935
+ const addlMetadataText = `robbot_${classnameIsh}_${robbotNameIsh}_${robbotIdIsh}`;
936
+ if (logalot) { console.log(`${lc} addlMetadataText: ${addlMetadataText} (I: 53c0044671dc99fb75635367d2e63c22)`); }
937
+ return addlMetadataText;
938
+ } catch (error) {
939
+ console.error(`${lc} ${error.message}`);
940
+ throw error;
941
+ } finally {
942
+ if (logalot) { console.log(`${lc} complete.`); }
943
+ }
944
+ }
945
+
946
+ protected parseAddlMetadataString({ ib }: { ib: Ib }): {
947
+ robbotClassnameIsh?: string;
948
+ robbotNameIsh?: string;
949
+ robbotIdIsh?: string;
950
+ } {
951
+ const lc = `${this.lc}[${this.parseAddlMetadataString.name}]`;
952
+ try {
953
+ if (logalot) { console.log(`${lc} starting... (I: d0cf162bc5f4cbf65bf1f7e29e3bd922)`); }
954
+ const { safeIbCommentMetadataText } = parseCommentIb({ ib });
955
+
956
+ if (safeIbCommentMetadataText) {
957
+ const [_, robbotClassnameIsh, robbotNameIsh, robbotIdIsh] = safeIbCommentMetadataText.split('__');
958
+ return { robbotClassnameIsh, robbotNameIsh, robbotIdIsh };
959
+ } else {
960
+ return { robbotClassnameIsh: undefined, robbotNameIsh: undefined, robbotIdIsh: undefined };
961
+ }
962
+ } catch (error) {
963
+ console.error(`${lc} ${error.message}`);
964
+ throw error;
965
+ } finally {
966
+ if (logalot) { console.log(`${lc} complete.`); }
967
+ }
968
+ }
969
+
970
+ /**
971
+ * by default in base class, this compares exactly the metadata string in a comment
972
+ * with this robbot.getaddlmetadata result.
973
+ */
974
+ protected isMyComment({ ibGib }: { ibGib: IbGib_V1 }): boolean {
975
+ const lc = `${this.lc}[${this.isMyComment.name}]`;
976
+ try {
977
+ if (logalot) { console.log(`${lc} starting... (I: 18fc0c7132e2b5297a9c00df7f79e622)`); }
978
+ const { safeIbCommentMetadataText } = parseCommentIb({ ib: ibGib.ib });
979
+ const isMine = safeIbCommentMetadataText === this.getAddlMetadata();
980
+ if (logalot) { console.log(`${lc} metadata (${safeIbCommentMetadataText ?? 'undefined'}) isMine: ${isMine} (I: 1915fc7fd20e0ee8a2f8b554741b6622)`); }
981
+ return isMine;
982
+ } catch (error) {
983
+ console.error(`${lc} ${error.message}`);
984
+ throw error;
985
+ } finally {
986
+ if (logalot) { console.log(`${lc} complete.`); }
987
+ }
988
+ }
989
+
990
+ /**
991
+ * gets ibgibs to which this robbot is directly rel8d WRT rel8nNames.
992
+ *
993
+ * @returns map of rel8nName -> ibgibs that this robbot is related to.
994
+ */
995
+ protected async getRel8dIbGibs({
996
+ rel8nNames,
997
+ }: {
998
+ rel8nNames?: string[],
999
+ }): Promise<{ [rel8nName: string]: IbGib_V1[] }> {
1000
+ const lc = `${this.lc}[${this.getRel8dIbGibs.name}]`;
1001
+ try {
1002
+ if (logalot) { console.log(`${lc} starting... (I: f183ca9d23e8f67721b614cf01327b22)`); }
1003
+ if (!rel8nNames) { rel8nNames = this.data?.allRel8nNames ?? []; }
1004
+ if (!this.data) { console.warn(`${lc} (UNEXPECTED) this.data falsy? (W: d9dc3b322da443228c35209621ae96a4)`); }
1005
+ if (this.data?.defaultRel8nName && !rel8nNames.includes(this.data.defaultRel8nName)) {
1006
+ rel8nNames.push(this.data.defaultRel8nName);
1007
+ }
1008
+ if (rel8nNames.length === 0) { throw new Error(`rel8nNames arg required or this.data.allRel8nNames must have at least one rel8nName. (E: 32380232f04f6cb01e0791a754672722)`); }
1009
+
1010
+ await this.loadNewerSelfIfAvailable();
1011
+
1012
+ if (!this.ibgibsSvc) { throw new Error(`this.ibgibsSvc falsy (E: fd2f9e4384a725122f4de2eb76696923)`); }
1013
+ const space = await this.ibgibsSvc.getLocalUserSpace({ lock: true });
1014
+
1015
+ const rel8dIbGibs: { [rel8nName: string]: IbGib_V1[] } = {};
1016
+
1017
+ // todo: adjust to use the cacheIbGibs (not get them if already have in cache, but still return them in this fn's result)
1018
+ for (let i = 0; i < rel8nNames.length; i++) {
1019
+ const rel8nName = rel8nNames[i];
1020
+ const rel8dAddrs: IbGibAddr[] = this.rel8ns ? (this.rel8ns[rel8nName] ?? []) : undefined ?? [];
1021
+
1022
+ if (rel8dAddrs.length > 0) {
1023
+ const resGet = await getFromSpace({ addrs: rel8dAddrs, space });
1024
+ if (resGet.success && resGet.ibGibs?.length === rel8dAddrs!.length) {
1025
+ rel8dIbGibs[rel8nName] = resGet.ibGibs.concat();
1026
+ } else {
1027
+ throw new Error(`there was a problem getting this robbot's rel8d ibgibs. ${resGet.errorMsg ?? 'some kinda problem...hmm..'} (E: 81e26309422ab87e5bd6bcf152059622)`);
1028
+ }
1029
+ } else {
1030
+ rel8dIbGibs[rel8nName] = [];
1031
+ }
1032
+ }
1033
+
1034
+ return rel8dIbGibs;
1035
+ } catch (error) {
1036
+ console.error(`${lc} ${error.message}`);
1037
+ throw error;
1038
+ } finally {
1039
+ if (logalot) { console.log(`${lc} complete.`); }
1040
+ }
1041
+ }
1042
+
1043
+ /**
1044
+ * helper function to wrap text in outputPrefix/Suffix
1045
+ *
1046
+ * @returns wrapped text, depending on param values.
1047
+ */
1048
+ protected async getOutputText({
1049
+ text,
1050
+ skipPrefix,
1051
+ skipSuffix,
1052
+ prefixOverride,
1053
+ suffixOverride,
1054
+ }: {
1055
+ text: string,
1056
+ skipPrefix?: boolean,
1057
+ skipSuffix?: boolean,
1058
+ prefixOverride?: string,
1059
+ suffixOverride?: string,
1060
+ }): Promise<string> {
1061
+ const lc = `${this.lc}[${this.getOutputText.name}]`;
1062
+ try {
1063
+ if (logalot) { console.log(`${lc} starting... (I: 7107ae1bcbee485e96123ea1733cc191)`); }
1064
+ if (!text) {
1065
+ console.error(`${lc} text required. (E: e1f5716c2a5744b5b5ca22dee6af8a85)`);
1066
+ text = 'urmm, something went awry...the text is empty at this point.';
1067
+ }
1068
+
1069
+ if (!this.data) { throw new Error(`(UNEXPECTED) this.data falsy? (E: 0f0aab6b7f258d1a386cfb22349e9923)`); }
1070
+
1071
+ let resText = skipPrefix || !this.data.outputPrefix ? text : `${prefixOverride ?? this.data.outputPrefix}\n\n${text}`;
1072
+ if (!skipSuffix && this.data.outputSuffix) {
1073
+ resText += `\n\n${suffixOverride ?? this.data.outputSuffix}`;
1074
+ }
1075
+
1076
+ return resText;
1077
+ } catch (error) {
1078
+ console.error(`${lc} ${error.message}`);
1079
+ throw error;
1080
+ } finally {
1081
+ if (logalot) { console.log(`${lc} complete.`); }
1082
+ }
1083
+ }
1084
+
1085
+ /**
1086
+ * By default, this rel8s to the given ibgibs via this.data.defaultRel8nName
1087
+ */
1088
+ protected async lookAt({
1089
+ ibGibs
1090
+ }: {
1091
+ ibGibs: IbGib_V1[]
1092
+ }): Promise<void> {
1093
+ const lc = `${this.lc}[${this.lookAt.name}]`;
1094
+ try {
1095
+ if (logalot) { console.log(`${lc} starting... (I: ea0e0ed92756ca339b8c03b700599722)`); }
1096
+ await this.rel8To({ ibGibs });
1097
+ } catch (error) {
1098
+ console.error(`${lc} ${error.message}`);
1099
+ throw error;
1100
+ } finally {
1101
+ if (logalot) { console.log(`${lc} complete.`); }
1102
+ }
1103
+
1104
+ }
1105
+
1106
+ /**
1107
+ * I originally created this just to extract the context from the arg, but
1108
+ * I'm reusing it to get the latest context from the addr alone.
1109
+ */
1110
+ protected async getContextIbGibFromArgOrAddr({
1111
+ arg,
1112
+ addr,
1113
+ latest,
1114
+ }: {
1115
+ arg?: RobbotCmdIbGib<IbGib_V1, RobbotCmdData, RobbotCmdRel8ns>,
1116
+ addr?: IbGibAddr,
1117
+ /**
1118
+ * if true, after extracting the context from the arg, will get the
1119
+ * latest ibgib (if there is a newer version).
1120
+ */
1121
+ latest?: boolean,
1122
+ }): Promise<IbGib_V1> {
1123
+ const lc = `${this.lc}[${this.getContextIbGibFromArgOrAddr.name}]`;
1124
+ try {
1125
+ if (logalot) { console.log(`${lc} starting... (I: c13f7cb92133984048f606075efb8a22)`); }
1126
+ let contextIbGib: IbGib_V1;
1127
+ if (!arg && !addr) { throw new Error(`either arg or addr required. (E: 3f647b65742242fd9ba878521acf7c22)`); }
1128
+ if (!this.ibgibsSvc) { throw new Error(`(UNEXPECTED) this.ibgibsSvc required (E: f0046290b0d66d28c4bbbf83d9d9f523)`); }
1129
+ if (arg) {
1130
+ if ((arg.ibGibs ?? []).length === 0) { throw new Error(`(UNEXPECTED) invalid arg? no context ibgib on arg (E: 89997eb4bdeb3885bee9de5d33ee0f22)`); }
1131
+ if ((arg.ibGibs ?? []).length !== 1) { throw new Error(`(UNEXPECTED) invalid arg? only expected one ibgib on arg.ibGibs (E: 1a1498af668740fe9439f4953a74ea8a)`); }
1132
+ contextIbGib = arg.ibGibs![0];
1133
+ } else {
1134
+ // addr provided
1135
+ const resGet = await this.ibgibsSvc.get({ addr });
1136
+ if (!resGet.success || resGet.ibGibs?.length !== 1) { throw new Error(`could not get context addr (${addr}) (E: 834492313512a45b23a7bebacdc48122)`); }
1137
+ contextIbGib = resGet.ibGibs[0];
1138
+ }
1139
+
1140
+ if (latest) {
1141
+ const resLatestAddr = await this.ibgibsSvc.getLatestAddr({ ibGib: contextIbGib });
1142
+ if (resLatestAddr !== getIbGibAddr({ ibGib: contextIbGib })) {
1143
+ const resGet = await this.ibgibsSvc.get({ addr: resLatestAddr });
1144
+ if (resGet.success && resGet.ibGibs?.length === 1) {
1145
+ contextIbGib = resGet.ibGibs[0];
1146
+ } else {
1147
+ throw new Error(`unable to get resLatestAddr (${resLatestAddr}) (E: ce1e1297743e9a16c8f082321e52a122)`);
1148
+ }
1149
+ }
1150
+ }
1151
+ return contextIbGib;
1152
+ } catch (error) {
1153
+ console.error(`${lc} ${error.message}`);
1154
+ throw error;
1155
+ } finally {
1156
+ if (logalot) { console.log(`${lc} complete.`); }
1157
+ }
1158
+ }
1159
+
1160
+ /**
1161
+ * The context is the ibgib where we are interacting with the user(s) (only
1162
+ * singlular atow).
1163
+ *
1164
+ * When we initialize, we are setting state on this robbot as well as subscribing
1165
+ * to the context ibgib's updates in `this.ibgibsSvc`.
1166
+ *
1167
+ * if we already have a context, then this will check the new incoming
1168
+ * context against it. If it's the same timeline, then this won't do
1169
+ * anything. Otherwise, it will finalize the previous context.
1170
+ */
1171
+ protected async initializeContext({
1172
+ arg,
1173
+ }: {
1174
+ arg: RobbotCmdIbGib<IbGib_V1, RobbotCmdData, RobbotCmdRel8ns>,
1175
+ }): Promise<void> {
1176
+ const lc = `${this.lc}[${this.initializeContext.name}]`;
1177
+ try {
1178
+ if (logalot) { console.log(`${lc} starting... (I: d93429c85b0a494388f66fba3eece922)`); }
1179
+
1180
+ // get context from arg just to compare the tjp's so we don't need
1181
+ // the latest at this point
1182
+ const incomingContext_NotLatest = await this.getContextIbGibFromArgOrAddr({ arg, latest: false });
1183
+ if (this._currentWorkingContextIbGib) {
1184
+ let currentTjpAddr = getTjpAddr({ ibGib: this._currentWorkingContextIbGib });
1185
+ const incomingTjpAddr = getTjpAddr({ ibGib: incomingContext_NotLatest })
1186
+ if (currentTjpAddr === incomingTjpAddr) {
1187
+ console.warn(`${lc} initializing context but it's the same timeline (${currentTjpAddr}). (W: 7609f8f51172443183e0c93ad52bfe56)`);
1188
+ return;
1189
+ } else {
1190
+ await this.finalizeContext({ arg });
1191
+ }
1192
+ }
1193
+
1194
+ /** used both now and when context ibgib is updated via observable */
1195
+ const updatePriorChildren = () => {
1196
+ this._currentWorkingContextIbGib_PriorChildrenAddrs = [
1197
+ ...this._currentWorkingContextIbGib?.rel8ns?.comment ?? [],
1198
+ ...this._currentWorkingContextIbGib?.rel8ns?.pic ?? [],
1199
+ ...this._currentWorkingContextIbGib?.rel8ns?.link ?? [],
1200
+ ];
1201
+ };
1202
+
1203
+ // set the props
1204
+ this._currentWorkingContextIbGib = await this.getContextIbGibFromArgOrAddr({ arg, latest: true });
1205
+ updatePriorChildren();
1206
+
1207
+ // subscribe to context ibgib updates
1208
+ const contextTjpAddr = getTjpAddr({ ibGib: this._currentWorkingContextIbGib });
1209
+ if (!this.ibgibsSvc) { throw new Error(`this.ibgibsSvc falsy...not initialized? (E: 6e38bfdc5c2eb5fef884f0183889e823)`); }
1210
+ this._contextChangesSubscription =
1211
+ this.ibgibsSvc.latestObs.pipe(filter(x => x.tjpAddr === contextTjpAddr)).subscribe(async (update: any) => {
1212
+ const currentAddr = getIbGibAddr({ ibGib: this._currentWorkingContextIbGib });
1213
+ if (update.latestAddr !== currentAddr) {
1214
+ if (logalot) { console.warn(`${lc} checking if new context is actually new...damn getLatestAddr maybe not working in ionic space... argh (W: 3d1a12154dfafb9c96d07e6f75f7a322)`); }
1215
+ if (update.latestIbGib) {
1216
+ let latestN_Supposedly = update.latestIbGib.data?.n ?? -1;
1217
+ let currentN = this._currentWorkingContextIbGib?.data?.n ?? -2;
1218
+ if (latestN_Supposedly <= currentN) {
1219
+ console.warn(`${lc} latestN is not really the latest. latestN_Supposedly: ${latestN_Supposedly}, currentN: ${currentN} (W: 6792c9a596c44c03b262614ae79a715e)`)
1220
+ return; /* <<<< returns early */
1221
+ }
1222
+ }
1223
+ if (logalot) { console.log(`${lc} update to context.\ncurrentAddr: ${currentAddr}\nlatestAddr: ${update.latestAddr} (I: d0adcc392e6e974c9917730ebad51322)`); }
1224
+ this._currentWorkingContextIbGib =
1225
+ update.latestIbGib ??
1226
+ await this.getContextIbGibFromArgOrAddr({ addr: update.latestAddr, latest: false }); // already latest
1227
+ if (!this._updatingContext) {
1228
+ await this.handleContextUpdate({ update });
1229
+ updatePriorChildren();
1230
+ } else {
1231
+ if (logalot) { console.log(`${lc} already updating context (I: f856f9414627ab00418dccd285b55822)`); }
1232
+ }
1233
+ }
1234
+ });
1235
+
1236
+ // rel8 to the context (conversation)
1237
+ await this.rel8To({
1238
+ ibGibs: [this._currentWorkingContextIbGib],
1239
+ rel8nName: ROBBOT_CONTEXT_REL8N_NAME,
1240
+ });
1241
+
1242
+ // subscribe to receive updates to the context so we can participate
1243
+ // in the conversation (i.e. interpret incoming ibgibs like commands
1244
+ // if needed)
1245
+ // let gibInfo = getGibInfo({ gib: this._currentWorkingContextIbGib.gib });
1246
+ // if (gibInfo.tjpGib) {
1247
+ // this.ibgibsSvc.latestObs
1248
+ // .subscribe(update => {
1249
+ // if (!update.tjpAddr) { return; /* <<<< returns early */ }
1250
+ // if (getIbAndGib({ ibGibAddr: update.tjpAddr }).gib !== gibInfo.tjpGib) { return; /* <<<< returns early */ }
1251
+ // if (update.latestAddr === getIbGibAddr({ ibGib: this._currentWorkingContextIbGib })) {
1252
+ // if (logalot) { console.log(`${lc} already have that context... (I: a6e17ec40d620f0bd5b231db39eaa522)`); }
1253
+ // return; /* <<<< returns early */
1254
+ // }
1255
+ // if (this._updatingContext) {
1256
+ // if (logalot) { console.log(`${lc} already updating context (I: f856f9414627ab00418dccd285b55822)`); }
1257
+ // return; /* <<<< returns early */
1258
+ // }
1259
+ // this.handleContextUpdate({ update });
1260
+ // });
1261
+ // }
1262
+ } catch (error) {
1263
+ console.error(`${lc} ${error.message}`);
1264
+ throw error;
1265
+ } finally {
1266
+ if (logalot) { console.log(`${lc} complete.`); }
1267
+ }
1268
+ }
1269
+
1270
+ protected async finalizeContext({
1271
+ arg,
1272
+ }: {
1273
+ arg: RobbotCmdIbGib<IbGib_V1, RobbotCmdData, RobbotCmdRel8ns>,
1274
+ }): Promise<void> {
1275
+ const lc = `${this.lc}[${this.finalizeContext.name}]`;
1276
+ try {
1277
+ if (logalot) { console.log(`${lc} starting... (I: dd53dfc745864dd19fde5f209ceb82c8)`); }
1278
+
1279
+
1280
+ let tries = 0;
1281
+ const maxTries = 100;
1282
+ while (this._updatingContext && tries < maxTries) {
1283
+ await delay(100);
1284
+ tries++;
1285
+ if (tries % 10 === 0) {
1286
+ console.log(`${lc} already updating context and taking a litle while... waiting still. tries: ${tries}/${maxTries} (I: d45ab59af9ea43518432e34ddad95c19)`)
1287
+ }
1288
+ }
1289
+ if (this._updatingContext) {
1290
+ console.error(`${lc} previous call to updatingContext took too long. Ignoring flag and finalizing context. (E: 9a2dc4e1923442fa90fbeae72f358acd)`);
1291
+ }
1292
+
1293
+ this._updatingContext = true;
1294
+ if (this._contextChangesSubscription) {
1295
+ debugger;
1296
+ this._contextChangesSubscription.unsubscribe();
1297
+ delete this._contextChangesSubscription;
1298
+ }
1299
+ delete this._currentWorkingContextIbGib;
1300
+
1301
+ if (this._currentWorkingContextIbGib) {
1302
+ await this.createCommentAndRel8ToContextIbGib({
1303
+ text: await this.getOutputText({ text: 'end of line' }),
1304
+ contextIbGib: this._currentWorkingContextIbGib,
1305
+ });
1306
+ delete this._currentWorkingContextIbGib;
1307
+ }
1308
+ } catch (error) {
1309
+ console.error(`${lc} ${error.message}`);
1310
+ throw error;
1311
+ } finally {
1312
+ this._updatingContext = false;
1313
+ if (logalot) { console.log(`${lc} complete.`); }
1314
+ }
1315
+ }
1316
+
1317
+ /**
1318
+ * Handles a new ibgib in the current working context.
1319
+ *
1320
+ * If it originated from the robbot him/herself, then we will ignore it.
1321
+ * Otherwise this is interpreted either as a "command" or something to remember.
1322
+ *
1323
+ * ## notes
1324
+ *
1325
+ * If the user says something and we're listening (this is triggered), then
1326
+ * it should be either interpreted as a "command" or ignored. I put
1327
+ * "command" in quotes because the word is a very short-sighted
1328
+ * understanding of the conversational aspect. Or perhaps I speak to the
1329
+ * connotations to current belief's regarding robbots and commands.
1330
+ *
1331
+ * This is complicated by the possibility in the future of multiple robbots
1332
+ * being engaged in a conversation within the same context.
1333
+ */
1334
+ private async handleContextUpdate({ update }: { update: IbGibTimelineUpdateInfo }): Promise<void> {
1335
+ const lc = `${this.lc}[${this.handleContextUpdate.name}]`;
1336
+ // I don't see this as really being very likely in the near future,
1337
+ // but putting in a wait delay in case there are multiple updates
1338
+ while (this._updatingContext) {
1339
+ console.warn(`${lc} already updating context? delaying... (W: 19d2ebeaaf2340fb91a7d6c717e9cb41)`);
1340
+ await delay(1000);
1341
+ }
1342
+ this._updatingContext = true;
1343
+ try {
1344
+ if (logalot) { console.log(`${lc} starting... (I: 3eeaa40cad49094f125f9f5cd6ff6e22)`); }
1345
+
1346
+ // if it's caused by this robbot speaking, then we don't really need
1347
+ // it. but if it's from the user, then we want to respond.
1348
+ if (logalot) {
1349
+ console.log(`${lc} update: (I: ad0abae7de472e3b4d3891ea0b937322)`);
1350
+ console.table(update);
1351
+ }
1352
+ if (!update.latestIbGib) {
1353
+ debugger;
1354
+ throw new Error(`(UNEXPECTED) update.latestIbGib falsy? (E: e18a048d7e95757238396ddd84748f22)`);
1355
+ }
1356
+
1357
+ const newContext = update.latestIbGib;
1358
+ const newChildrenIbGibs = await this.getNewChildrenIbGibs({ newContext });
1359
+ // should normally be just one (would be very edge casey if not atow)
1360
+ let newChild: IbGib_V1;
1361
+ if (newChildrenIbGibs.length === 1) {
1362
+ newChild = newChildrenIbGibs[0];
1363
+ } else if (newChildrenIbGibs.length > 1) {
1364
+ console.warn(`${lc} (UNEXPECTED) found multiple new children in conversation? Using only the last. (W: 02d82a8f755f418d95fa30f0f52ad58e)`);
1365
+ newChild = newChildrenIbGibs[newChildrenIbGibs.length - 1];
1366
+ } else {
1367
+ // no new children, so maybe the user deleted something or who knows.
1368
+ if (logalot) { console.log(`${lc} no new children in context update. returning early... (I: 31397b04965351ab29bb3f78cb709122)`); }
1369
+ return; /* <<<< returns early */
1370
+ }
1371
+
1372
+ // we have a new chidl inthe context.
1373
+ await this.handleNewContextChild({ newChild });
1374
+
1375
+ } catch (error) {
1376
+ console.error(`${lc} ${error.message}`);
1377
+ throw error;
1378
+ } finally {
1379
+ this._updatingContext = false;
1380
+ if (logalot) { console.log(`${lc} complete.`); }
1381
+ }
1382
+ }
1383
+
1384
+ async getNewChildrenIbGibs({ newContext }: { newContext: IbGib_V1 }): Promise<IbGib_V1[]> {
1385
+ const lc = `${this.lc}[${this.getNewChildrenIbGibs.name}]`;
1386
+ try {
1387
+ if (logalot) { console.log(`${lc} starting... (I: 1b3d1cf908489087fa3b281f55b9a522)`); }
1388
+ // get a diff of the new addrs vs. the old addrs.
1389
+ /** all of the children addrs of the new context */
1390
+ const newContextChildrenAddrs = [
1391
+ ...newContext.rel8ns?.comment ?? [],
1392
+ ...newContext.rel8ns?.pic ?? [],
1393
+ ...newContext.rel8ns?.link ?? [],
1394
+ ];
1395
+ /** just the new addrs from the context */
1396
+ const newChildrenAddrs = newContextChildrenAddrs.filter(x =>
1397
+ !this._currentWorkingContextIbGib_PriorChildrenAddrs.includes(x)
1398
+ );
1399
+ if (newChildrenAddrs.length === 0) {
1400
+ // no new children
1401
+ if (logalot) { console.log(`${lc} no new children addrs in newContext. returning early... (I: 8f9c3658c194c472cb1e2bc19d847b22)`); }
1402
+ return []; /* <<<< returns early */
1403
+ }
1404
+
1405
+ // get the latest addrs for those children
1406
+ if (!this.ibgibsSvc) { throw new Error(`this.ibgibsSvc falsy. not initialized? (E: 1cc26ca7de7fadcdbaecbd6613350e23)`); }
1407
+ const space = await this.ibgibsSvc.getLocalUserSpace({});
1408
+ if (!space) { throw new Error(`couldn't get local user space? (E: f118f75e5852fc22bba3a6495beec723)`); }
1409
+ const resLatestAddrs = await getLatestAddrs({ addrs: newChildrenAddrs, space, });
1410
+ const latestAddrs = Object.values(resLatestAddrs?.data?.latestAddrsMap ?? {});
1411
+ if (!resLatestAddrs?.data?.success || latestAddrs.length !== newChildrenAddrs.length) { throw new Error(`could not get latest addrs. (E: 2e1619e7e2e166696fe8ff78cb02cc22)`); }
1412
+
1413
+ // get the addrs' corresponding ibgibs
1414
+ if (latestAddrs.some(x => x === null)) {
1415
+ // some of the addrs were not found in the space
1416
+ throw new Error(`some addrs were not found in the space. (E: 2216d8e5ad7fb600ceb025ed7c90f323)`);
1417
+ }
1418
+ const resGet = await this.ibgibsSvc.get({ addrs: latestAddrs as IbGibAddr[] });
1419
+ if (!resGet.success || resGet.ibGibs?.length !== newChildrenAddrs.length) {
1420
+ throw new Error(`failed to get newChildren with addrs: ${newChildrenAddrs.join('|')}. Error: ${resGet.errorMsg ?? 'unknown error 5737bd0996d5445b8bd80975bedc0d57'} (E: 05722e11350ec6ffffdb5c7d0caa2922)`);
1421
+ }
1422
+
1423
+ return resGet.ibGibs;
1424
+ } catch (error) {
1425
+ console.error(`${lc} ${error.message}`);
1426
+ throw error;
1427
+ } finally {
1428
+ if (logalot) { console.log(`${lc} complete.`); }
1429
+ }
1430
+ }
1431
+
1432
+ protected async handleNewContextChild({ newChild }: { newChild: IbGib_V1 }): Promise<void> {
1433
+ const lc = `${this.lc}[${this.handleNewContextChild.name}]`;
1434
+ try {
1435
+ throw new Error(`not implemented in base class (E: 833038a17d04e38b9b97be19ed010922)`);
1436
+ } catch (error) {
1437
+ console.error(`${lc} ${error.message}`);
1438
+ throw error;
1439
+ }
1440
+ }
1441
+
1442
+ protected async getRobbotInteractionData({
1443
+ type,
1444
+ commentText,
1445
+ subjectTjpGibs,
1446
+ details,
1447
+ expectingResponse,
1448
+ uuid,
1449
+ timestamp,
1450
+ }: {
1451
+ /**
1452
+ * the tyep of interaction.
1453
+ *
1454
+ * @see {@link RobbotInteractionType}
1455
+ */
1456
+ type: RobbotInteractionType,
1457
+ /**
1458
+ * the comment text of the interaction.
1459
+ *
1460
+ * Does not include any prefix/suffix of the robbot.
1461
+ */
1462
+ commentText: string,
1463
+ /**
1464
+ * If the interaction has one or more specific target/subject, then this
1465
+ * is where their gibs go.
1466
+ *
1467
+ * ## driving use case
1468
+ *
1469
+ * I need a way from starting with an ibgib and getting its related
1470
+ * interactions.
1471
+ */
1472
+ subjectTjpGibs?: Gib[],
1473
+ /**
1474
+ * interaction details.
1475
+ */
1476
+ details?: any,
1477
+ /**
1478
+ * if interaction intends to evoke a response
1479
+ */
1480
+ expectingResponse?: boolean,
1481
+ /**
1482
+ * If provided, will be the id of the interaction.
1483
+ */
1484
+ uuid?: string,
1485
+ /**
1486
+ * if provided, will be the timestamp of the interaction data.
1487
+ */
1488
+ timestamp?: string,
1489
+ }): Promise<RobbotInteractionData_V1> {
1490
+ const lc = `${this.lc}[${this.getRobbotInteractionData.name}]`;
1491
+ try {
1492
+ if (logalot) { console.log(`${lc} starting... (I: b05837a91c6973326fde8cf51aac1922)`); }
1493
+
1494
+ if (!type) { throw new Error(`type required (E: 737f8ecc21c519d1d61bce2a91fe2d22)`); }
1495
+ if (!this._currentWorkingContextIbGib?.gib) { throw new Error(`this._currentWorkingContextIbGib?.gib is falsy (E: 6489a36ab0c797f1b5d52db709ea0322)`); }
1496
+
1497
+ uuid = uuid || await getUUID();
1498
+ timestamp = timestamp || getTimestamp();
1499
+
1500
+ let contextTjpGib: Gib | undefined = getGibInfo({ gib: this._currentWorkingContextIbGib.gib }).tjpGib;
1501
+ if (!contextTjpGib) {
1502
+ contextTjpGib = this._currentWorkingContextIbGib.gib;
1503
+ if (!contextTjpGib) { throw new Error(`(UNEXPECTED) this._currentWorkingContextIbGib.gib falsy? (E: 50cddb787f1a0af19567531b30bd5522)`); }
1504
+ console.warn(`${lc} contextTjpGib is falsy? This means that the robbot context does not have a timeline. This might be ok, but not expected. contextTjp will be considered the gib of the context (${contextTjpGib}) (W: f2a6f91ef5e44170a5e3d5456f2fb2f2)`);
1505
+ }
1506
+
1507
+ const data: RobbotInteractionData_V1 = {
1508
+ uuid,
1509
+ timestamp,
1510
+ type,
1511
+ contextTjpGib,
1512
+ commentText,
1513
+ expectingResponse,
1514
+ subjectTjpGibs,
1515
+ };
1516
+
1517
+ if (details) { data.details = details; }
1518
+
1519
+ return data;
1520
+ } catch (error) {
1521
+ console.error(`${lc} ${error.message}`);
1522
+ throw error;
1523
+ } finally {
1524
+ if (logalot) { console.log(`${lc} complete.`); }
1525
+ }
1526
+ }
1527
+ }
1528
+
1529
+ export interface IbGibRobbotAny
1530
+ extends RobbotBase_V1<any, any, any, any, any, any, any, any> {
1531
+ }