atom.io 0.32.4 → 0.33.1

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 (362) hide show
  1. package/dist/chunk-Cl8Af3a2.js +11 -0
  2. package/dist/data/index.d.ts +28 -0
  3. package/dist/data/index.d.ts.map +1 -0
  4. package/dist/data/index.js +66 -0
  5. package/dist/data/index.js.map +1 -0
  6. package/dist/devtools-CAg2k57t.js +0 -0
  7. package/dist/devtools-Jyn42mZm.css +311 -0
  8. package/dist/devtools-Jyn42mZm.css.map +1 -0
  9. package/dist/eslint-plugin/index.d.ts +36 -0
  10. package/dist/eslint-plugin/index.d.ts.map +1 -0
  11. package/dist/eslint-plugin/index.js +196 -0
  12. package/dist/eslint-plugin/index.js.map +1 -0
  13. package/{internal/dist → dist/internal}/index.d.ts +495 -378
  14. package/dist/internal/index.d.ts.map +1 -0
  15. package/dist/internal/index.js +3213 -0
  16. package/dist/internal/index.js.map +1 -0
  17. package/dist/introspection/index.d.ts +153 -0
  18. package/dist/introspection/index.d.ts.map +1 -0
  19. package/dist/introspection/index.js +520 -0
  20. package/dist/introspection/index.js.map +1 -0
  21. package/{json/dist → dist/json}/index.d.ts +38 -32
  22. package/dist/json/index.d.ts.map +1 -0
  23. package/dist/json/index.js +75 -0
  24. package/dist/json/index.js.map +1 -0
  25. package/dist/main/index.d.ts +691 -0
  26. package/dist/main/index.d.ts.map +1 -0
  27. package/dist/main/index.js +237 -0
  28. package/dist/main/index.js.map +1 -0
  29. package/{react/dist → dist/react}/index.d.ts +22 -11
  30. package/dist/react/index.d.ts.map +1 -0
  31. package/dist/react/index.js +91 -0
  32. package/dist/react/index.js.map +1 -0
  33. package/dist/react-devtools/index.d.ts +194 -0
  34. package/dist/react-devtools/index.d.ts.map +1 -0
  35. package/dist/react-devtools/index.js +1274 -0
  36. package/dist/react-devtools/index.js.map +1 -0
  37. package/dist/realtime/index.d.ts +55 -0
  38. package/dist/realtime/index.d.ts.map +1 -0
  39. package/dist/realtime/index.js +113 -0
  40. package/dist/realtime/index.js.map +1 -0
  41. package/dist/realtime-client/index.d.ts +81 -0
  42. package/dist/realtime-client/index.d.ts.map +1 -0
  43. package/dist/realtime-client/index.js +376 -0
  44. package/dist/realtime-client/index.js.map +1 -0
  45. package/dist/realtime-react/index.d.ts +68 -0
  46. package/dist/realtime-react/index.d.ts.map +1 -0
  47. package/dist/realtime-react/index.js +182 -0
  48. package/dist/realtime-react/index.js.map +1 -0
  49. package/dist/realtime-server/index.d.ts +190 -0
  50. package/dist/realtime-server/index.d.ts.map +1 -0
  51. package/dist/realtime-server/index.js +795 -0
  52. package/dist/realtime-server/index.js.map +1 -0
  53. package/dist/realtime-testing/index.d.ts +60 -0
  54. package/dist/realtime-testing/index.d.ts.map +1 -0
  55. package/dist/realtime-testing/index.js +181 -0
  56. package/dist/realtime-testing/index.js.map +1 -0
  57. package/dist/transceivers/set-rtx/index.d.ts +44 -0
  58. package/dist/transceivers/set-rtx/index.d.ts.map +1 -0
  59. package/dist/transceivers/set-rtx/index.js +204 -0
  60. package/dist/transceivers/set-rtx/index.js.map +1 -0
  61. package/dist/web/index.d.ts +15 -0
  62. package/dist/web/index.d.ts.map +1 -0
  63. package/dist/web/index.js +16 -0
  64. package/dist/web/index.js.map +1 -0
  65. package/package.json +66 -117
  66. package/{eslint-plugin/src → src/eslint-plugin}/index.ts +3 -1
  67. package/{eslint-plugin/src → src/eslint-plugin}/rules/explicit-state-types.ts +6 -1
  68. package/{eslint-plugin/src → src/eslint-plugin}/rules/synchronous-selector-dependencies.ts +14 -1
  69. package/{internal/src → src/internal}/families/index.ts +2 -0
  70. package/{internal/src → src/internal}/index.ts +1 -0
  71. package/{internal/src → src/internal}/junction.ts +3 -2
  72. package/{internal/src → src/internal}/lazy-map.ts +1 -1
  73. package/{internal/src → src/internal}/mutable/tracker-family.ts +2 -5
  74. package/{internal/src → src/internal}/mutable/tracker.ts +15 -9
  75. package/{internal/src → src/internal}/store/store.ts +60 -47
  76. package/{internal/src → src/internal}/subject.ts +1 -1
  77. package/{introspection/src → src/introspection}/auditor.ts +1 -1
  78. package/{introspection/src → src/introspection}/differ.ts +12 -1
  79. package/{introspection/src → src/introspection}/refinery.ts +18 -3
  80. package/{json/src → src/json}/entries.ts +1 -1
  81. package/{json/src → src/json}/select-json-family.ts +1 -1
  82. package/src/{realm.ts → main/realm.ts} +1 -1
  83. package/src/{silo.ts → main/silo.ts} +1 -1
  84. package/src/{transaction.ts → main/transaction.ts} +1 -1
  85. package/{react/src → src/react}/store-context.tsx +3 -1
  86. package/{react-devtools/src → src/react-devtools}/AtomIODevtools.tsx +1 -1
  87. package/{react-devtools/src → src/react-devtools}/Button.tsx +3 -1
  88. package/{react-devtools/src → src/react-devtools}/Updates.tsx +5 -1
  89. package/src/react-devtools/devtools.css +308 -0
  90. package/{react-devtools/src → src/react-devtools}/json-editor/index.ts +5 -2
  91. package/{react-devtools/src → src/react-devtools}/store.ts +3 -2
  92. package/{realtime/src → src/realtime}/shared-room-store.ts +28 -5
  93. package/src/realtime-client/realtime-client-stores/client-main-store.ts +23 -0
  94. package/src/realtime-client/realtime-client-stores/client-sync-store.ts +15 -0
  95. package/{realtime-react/src → src/realtime-react}/index.ts +1 -0
  96. package/{realtime-react/src → src/realtime-react}/on-mount.ts +1 -1
  97. package/{realtime-react/src → src/realtime-react}/realtime-context.tsx +5 -4
  98. package/{realtime-react/src → src/realtime-react}/use-single-effect.ts +1 -1
  99. package/{realtime-server/src → src/realtime-server}/realtime-server-stores/server-room-external-actions.ts +20 -19
  100. package/{realtime-server/src → src/realtime-server}/realtime-server-stores/server-room-external-store.ts +12 -7
  101. package/{realtime-server/src → src/realtime-server}/realtime-server-stores/server-sync-store.ts +13 -4
  102. package/{realtime-server/src → src/realtime-server}/realtime-server-stores/server-user-store.ts +26 -8
  103. package/{transceivers/set-rtx/src → src/transceivers/set-rtx}/set-rtx.ts +2 -2
  104. package/data/dist/index.d.ts +0 -31
  105. package/data/dist/index.js +0 -69
  106. package/data/package.json +0 -13
  107. package/dist/chunk-4LWKCEW3.js +0 -14
  108. package/dist/chunk-7SJVR7FZ.js +0 -4499
  109. package/dist/chunk-IR77IXS7.js +0 -526
  110. package/dist/chunk-PG57JXN4.js +0 -1035
  111. package/dist/chunk-PXB4YZDI.js +0 -153
  112. package/dist/chunk-Q6OOJWM4.js +0 -634
  113. package/dist/chunk-TJPLOX7Z.js +0 -81
  114. package/dist/chunk-U4K63VLA.js +0 -109
  115. package/dist/chunk-XWL6SNVU.js +0 -7
  116. package/dist/index.d.ts +0 -701
  117. package/dist/index.js +0 -2
  118. package/eslint-plugin/dist/index.d.ts +0 -51
  119. package/eslint-plugin/dist/index.js +0 -238
  120. package/eslint-plugin/package.json +0 -13
  121. package/internal/dist/index.js +0 -2
  122. package/internal/package.json +0 -13
  123. package/introspection/dist/index.d.ts +0 -149
  124. package/introspection/dist/index.js +0 -3
  125. package/introspection/package.json +0 -13
  126. package/json/dist/index.js +0 -2
  127. package/json/package.json +0 -13
  128. package/react/dist/index.js +0 -3
  129. package/react/package.json +0 -13
  130. package/react-devtools/dist/index.css +0 -309
  131. package/react-devtools/dist/index.d.ts +0 -169
  132. package/react-devtools/dist/index.js +0 -1481
  133. package/react-devtools/package.json +0 -13
  134. package/react-devtools/src/devtools.scss +0 -309
  135. package/realtime/dist/index.d.ts +0 -51
  136. package/realtime/dist/index.js +0 -3
  137. package/realtime/package.json +0 -13
  138. package/realtime-client/dist/index.d.ts +0 -41
  139. package/realtime-client/dist/index.js +0 -4
  140. package/realtime-client/package.json +0 -13
  141. package/realtime-client/src/realtime-client-stores/client-main-store.ts +0 -20
  142. package/realtime-client/src/realtime-client-stores/client-sync-store.ts +0 -15
  143. package/realtime-react/dist/index.d.ts +0 -39
  144. package/realtime-react/dist/index.js +0 -6
  145. package/realtime-react/package.json +0 -13
  146. package/realtime-server/dist/index.d.ts +0 -139
  147. package/realtime-server/dist/index.js +0 -4
  148. package/realtime-server/package.json +0 -13
  149. package/realtime-testing/dist/index.d.ts +0 -59
  150. package/realtime-testing/dist/index.js +0 -198
  151. package/realtime-testing/package.json +0 -13
  152. package/transceivers/set-rtx/dist/index.d.ts +0 -41
  153. package/transceivers/set-rtx/dist/index.js +0 -2
  154. package/transceivers/set-rtx/package.json +0 -13
  155. package/web/dist/index.d.ts +0 -9
  156. package/web/dist/index.js +0 -2
  157. package/web/package.json +0 -13
  158. /package/{data/src → src/data}/dict.ts +0 -0
  159. /package/{data/src → src/data}/index.ts +0 -0
  160. /package/{data/src → src/data}/struct-family.ts +0 -0
  161. /package/{data/src → src/data}/struct.ts +0 -0
  162. /package/{eslint-plugin/src → src/eslint-plugin}/rules/index.ts +0 -0
  163. /package/{eslint-plugin/src → src/eslint-plugin}/walk.ts +0 -0
  164. /package/{internal/src → src/internal}/arbitrary.ts +0 -0
  165. /package/{internal/src → src/internal}/atom/create-regular-atom.ts +0 -0
  166. /package/{internal/src → src/internal}/atom/create-standalone-atom.ts +0 -0
  167. /package/{internal/src → src/internal}/atom/dispose-atom.ts +0 -0
  168. /package/{internal/src → src/internal}/atom/index.ts +0 -0
  169. /package/{internal/src → src/internal}/atom/is-default.ts +0 -0
  170. /package/{internal/src → src/internal}/caching.ts +0 -0
  171. /package/{internal/src → src/internal}/capitalize.ts +0 -0
  172. /package/{internal/src → src/internal}/families/create-atom-family.ts +0 -0
  173. /package/{internal/src → src/internal}/families/create-readonly-selector-family.ts +0 -0
  174. /package/{internal/src → src/internal}/families/create-regular-atom-family.ts +0 -0
  175. /package/{internal/src → src/internal}/families/create-selector-family.ts +0 -0
  176. /package/{internal/src → src/internal}/families/create-writable-selector-family.ts +0 -0
  177. /package/{internal/src → src/internal}/families/dispose-from-store.ts +0 -0
  178. /package/{internal/src → src/internal}/families/find-in-store.ts +0 -0
  179. /package/{internal/src → src/internal}/families/get-family-of-token.ts +0 -0
  180. /package/{internal/src → src/internal}/families/init-family-member.ts +0 -0
  181. /package/{internal/src → src/internal}/families/seek-in-store.ts +0 -0
  182. /package/{internal/src → src/internal}/future.ts +0 -0
  183. /package/{internal/src → src/internal}/get-environment-data.ts +0 -0
  184. /package/{internal/src → src/internal}/get-state/get-from-store.ts +0 -0
  185. /package/{internal/src → src/internal}/get-state/index.ts +0 -0
  186. /package/{internal/src → src/internal}/get-state/read-or-compute-value.ts +0 -0
  187. /package/{internal/src → src/internal}/get-trace.ts +0 -0
  188. /package/{internal/src → src/internal}/ingest-updates/index.ts +0 -0
  189. /package/{internal/src → src/internal}/ingest-updates/ingest-atom-update.ts +0 -0
  190. /package/{internal/src → src/internal}/ingest-updates/ingest-creation-disposal.ts +0 -0
  191. /package/{internal/src → src/internal}/ingest-updates/ingest-selector-update.ts +0 -0
  192. /package/{internal/src → src/internal}/ingest-updates/ingest-transaction-update.ts +0 -0
  193. /package/{internal/src → src/internal}/install-into-store.ts +0 -0
  194. /package/{internal/src → src/internal}/join/edit-relations-in-store.ts +0 -0
  195. /package/{internal/src → src/internal}/join/find-relations-in-store.ts +0 -0
  196. /package/{internal/src → src/internal}/join/get-internal-relations-from-store.ts +0 -0
  197. /package/{internal/src → src/internal}/join/get-join.ts +0 -0
  198. /package/{internal/src → src/internal}/join/index.ts +0 -0
  199. /package/{internal/src → src/internal}/join/join-internal.ts +0 -0
  200. /package/{internal/src → src/internal}/keys.ts +0 -0
  201. /package/{internal/src → src/internal}/lineage.ts +0 -0
  202. /package/{internal/src → src/internal}/molecule.ts +0 -0
  203. /package/{internal/src → src/internal}/mutable/create-mutable-atom-family.ts +0 -0
  204. /package/{internal/src → src/internal}/mutable/create-mutable-atom.ts +0 -0
  205. /package/{internal/src → src/internal}/mutable/get-json-family.ts +0 -0
  206. /package/{internal/src → src/internal}/mutable/get-json-token.ts +0 -0
  207. /package/{internal/src → src/internal}/mutable/get-update-family.ts +0 -0
  208. /package/{internal/src → src/internal}/mutable/get-update-token.ts +0 -0
  209. /package/{internal/src → src/internal}/mutable/index.ts +0 -0
  210. /package/{internal/src → src/internal}/mutable/transceiver.ts +0 -0
  211. /package/{internal/src → src/internal}/not-found-error.ts +0 -0
  212. /package/{internal/src → src/internal}/operation.ts +0 -0
  213. /package/{internal/src → src/internal}/pretty-print.ts +0 -0
  214. /package/{internal/src → src/internal}/reserved-keys.ts +0 -0
  215. /package/{internal/src → src/internal}/selector/create-readonly-selector.ts +0 -0
  216. /package/{internal/src → src/internal}/selector/create-standalone-selector.ts +0 -0
  217. /package/{internal/src → src/internal}/selector/create-writable-selector.ts +0 -0
  218. /package/{internal/src → src/internal}/selector/dispose-selector.ts +0 -0
  219. /package/{internal/src → src/internal}/selector/get-selector-dependency-keys.ts +0 -0
  220. /package/{internal/src → src/internal}/selector/index.ts +0 -0
  221. /package/{internal/src → src/internal}/selector/register-selector.ts +0 -0
  222. /package/{internal/src → src/internal}/selector/trace-selector-atoms.ts +0 -0
  223. /package/{internal/src → src/internal}/selector/update-selector-atoms.ts +0 -0
  224. /package/{internal/src → src/internal}/set-state/become.ts +0 -0
  225. /package/{internal/src → src/internal}/set-state/copy-mutable-if-needed.ts +0 -0
  226. /package/{internal/src → src/internal}/set-state/emit-update.ts +0 -0
  227. /package/{internal/src → src/internal}/set-state/evict-downstream.ts +0 -0
  228. /package/{internal/src → src/internal}/set-state/index.ts +0 -0
  229. /package/{internal/src → src/internal}/set-state/set-atom-or-selector.ts +0 -0
  230. /package/{internal/src → src/internal}/set-state/set-atom.ts +0 -0
  231. /package/{internal/src → src/internal}/set-state/set-into-store.ts +0 -0
  232. /package/{internal/src → src/internal}/store/circular-buffer.ts +0 -0
  233. /package/{internal/src → src/internal}/store/counterfeit.ts +0 -0
  234. /package/{internal/src → src/internal}/store/deposit.ts +0 -0
  235. /package/{internal/src → src/internal}/store/index.ts +0 -0
  236. /package/{internal/src → src/internal}/store/withdraw.ts +0 -0
  237. /package/{internal/src → src/internal}/subscribe/index.ts +0 -0
  238. /package/{internal/src → src/internal}/subscribe/recall-state.ts +0 -0
  239. /package/{internal/src → src/internal}/subscribe/subscribe-in-store.ts +0 -0
  240. /package/{internal/src → src/internal}/subscribe/subscribe-to-root-atoms.ts +0 -0
  241. /package/{internal/src → src/internal}/subscribe/subscribe-to-state.ts +0 -0
  242. /package/{internal/src → src/internal}/subscribe/subscribe-to-timeline.ts +0 -0
  243. /package/{internal/src → src/internal}/subscribe/subscribe-to-transaction.ts +0 -0
  244. /package/{internal/src → src/internal}/timeline/create-timeline.ts +0 -0
  245. /package/{internal/src → src/internal}/timeline/index.ts +0 -0
  246. /package/{internal/src → src/internal}/timeline/time-travel.ts +0 -0
  247. /package/{internal/src → src/internal}/transaction/abort-transaction.ts +0 -0
  248. /package/{internal/src → src/internal}/transaction/act-upon-store.ts +0 -0
  249. /package/{internal/src → src/internal}/transaction/apply-transaction.ts +0 -0
  250. /package/{internal/src → src/internal}/transaction/assign-transaction-to-continuity.ts +0 -0
  251. /package/{internal/src → src/internal}/transaction/build-transaction.ts +0 -0
  252. /package/{internal/src → src/internal}/transaction/create-transaction.ts +0 -0
  253. /package/{internal/src → src/internal}/transaction/get-epoch-number.ts +0 -0
  254. /package/{internal/src → src/internal}/transaction/index.ts +0 -0
  255. /package/{internal/src → src/internal}/transaction/is-root-store.ts +0 -0
  256. /package/{internal/src → src/internal}/transaction/set-epoch-number.ts +0 -0
  257. /package/{internal/src → src/internal}/utility-types.ts +0 -0
  258. /package/{introspection/src → src/introspection}/attach-atom-index.ts +0 -0
  259. /package/{introspection/src → src/introspection}/attach-introspection-states.ts +0 -0
  260. /package/{introspection/src → src/introspection}/attach-selector-index.ts +0 -0
  261. /package/{introspection/src → src/introspection}/attach-timeline-family.ts +0 -0
  262. /package/{introspection/src → src/introspection}/attach-timeline-index.ts +0 -0
  263. /package/{introspection/src → src/introspection}/attach-transaction-index.ts +0 -0
  264. /package/{introspection/src → src/introspection}/attach-transaction-logs.ts +0 -0
  265. /package/{introspection/src → src/introspection}/attach-type-selectors.ts +0 -0
  266. /package/{introspection/src → src/introspection}/index.ts +0 -0
  267. /package/{introspection/src → src/introspection}/sprawl.ts +0 -0
  268. /package/{json/src → src/json}/index.ts +0 -0
  269. /package/{json/src → src/json}/select-json.ts +0 -0
  270. /package/src/{atom.ts → main/atom.ts} +0 -0
  271. /package/src/{dispose-state.ts → main/dispose-state.ts} +0 -0
  272. /package/src/{find-state.ts → main/find-state.ts} +0 -0
  273. /package/src/{get-state.ts → main/get-state.ts} +0 -0
  274. /package/src/{index.ts → main/index.ts} +0 -0
  275. /package/src/{join.ts → main/join.ts} +0 -0
  276. /package/src/{logger.ts → main/logger.ts} +0 -0
  277. /package/src/{selector.ts → main/selector.ts} +0 -0
  278. /package/src/{set-state.ts → main/set-state.ts} +0 -0
  279. /package/src/{subscribe.ts → main/subscribe.ts} +0 -0
  280. /package/src/{timeline.ts → main/timeline.ts} +0 -0
  281. /package/src/{validators.ts → main/validators.ts} +0 -0
  282. /package/{react/src → src/react}/index.ts +0 -0
  283. /package/{react/src → src/react}/parse-state-overloads.ts +0 -0
  284. /package/{react/src → src/react}/use-i.ts +0 -0
  285. /package/{react/src → src/react}/use-json.ts +0 -0
  286. /package/{react/src → src/react}/use-o.ts +0 -0
  287. /package/{react/src → src/react}/use-tl.ts +0 -0
  288. /package/{react-devtools/src → src/react-devtools}/StateEditor.tsx +0 -0
  289. /package/{react-devtools/src → src/react-devtools}/StateIndex.tsx +0 -0
  290. /package/{react-devtools/src → src/react-devtools}/TimelineIndex.tsx +0 -0
  291. /package/{react-devtools/src → src/react-devtools}/TransactionIndex.tsx +0 -0
  292. /package/{react-devtools/src → src/react-devtools}/elastic-input/ElasticInput.tsx +0 -0
  293. /package/{react-devtools/src → src/react-devtools}/elastic-input/NumberInput.tsx +0 -0
  294. /package/{react-devtools/src → src/react-devtools}/elastic-input/TextInput.tsx +0 -0
  295. /package/{react-devtools/src → src/react-devtools}/elastic-input/index.ts +0 -0
  296. /package/{react-devtools/src → src/react-devtools}/error-boundary/DefaultFallback.tsx +0 -0
  297. /package/{react-devtools/src → src/react-devtools}/error-boundary/ReactErrorBoundary.tsx +0 -0
  298. /package/{react-devtools/src → src/react-devtools}/error-boundary/index.ts +0 -0
  299. /package/{react-devtools/src → src/react-devtools}/index.ts +0 -0
  300. /package/{react-devtools/src → src/react-devtools}/json-editor/default-components.tsx +0 -0
  301. /package/{react-devtools/src → src/react-devtools}/json-editor/developer-interface.tsx +0 -0
  302. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/array-editor.tsx +0 -0
  303. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/non-json.tsx +0 -0
  304. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/object-editor.tsx +0 -0
  305. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/primitive-editors.tsx +0 -0
  306. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/utilities/array-elements.ts +0 -0
  307. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/utilities/cast-json.ts +0 -0
  308. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/utilities/cast-to-json.ts +0 -0
  309. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/utilities/object-properties.ts +0 -0
  310. /package/{react-devtools/src → src/react-devtools}/json-editor/json-editor-internal.tsx +0 -0
  311. /package/{react-devtools/src → src/react-devtools}/json-editor/todo.md +0 -0
  312. /package/{realtime/src → src/realtime}/index.ts +0 -0
  313. /package/{realtime/src → src/realtime}/realtime-continuity.ts +0 -0
  314. /package/{realtime-client/src → src/realtime-client}/continuity/index.ts +0 -0
  315. /package/{realtime-client/src → src/realtime-client}/continuity/register-and-attempt-confirmed-update.ts +0 -0
  316. /package/{realtime-client/src → src/realtime-client}/continuity/use-conceal-state.ts +0 -0
  317. /package/{realtime-client/src → src/realtime-client}/continuity/use-reveal-state.ts +0 -0
  318. /package/{realtime-client/src → src/realtime-client}/index.ts +0 -0
  319. /package/{realtime-client/src → src/realtime-client}/pull-atom-family-member.ts +0 -0
  320. /package/{realtime-client/src → src/realtime-client}/pull-atom.ts +0 -0
  321. /package/{realtime-client/src → src/realtime-client}/pull-mutable-atom-family-member.ts +0 -0
  322. /package/{realtime-client/src → src/realtime-client}/pull-mutable-atom.ts +0 -0
  323. /package/{realtime-client/src → src/realtime-client}/pull-selector-family-member.ts +0 -0
  324. /package/{realtime-client/src → src/realtime-client}/pull-selector.ts +0 -0
  325. /package/{realtime-client/src → src/realtime-client}/push-state.ts +0 -0
  326. /package/{realtime-client/src → src/realtime-client}/realtime-client-stores/index.ts +0 -0
  327. /package/{realtime-client/src → src/realtime-client}/server-action.ts +0 -0
  328. /package/{realtime-client/src → src/realtime-client}/sync-continuity.ts +0 -0
  329. /package/{realtime-react/src → src/realtime-react}/use-pull-atom-family-member.ts +0 -0
  330. /package/{realtime-react/src → src/realtime-react}/use-pull-atom.ts +0 -0
  331. /package/{realtime-react/src → src/realtime-react}/use-pull-mutable-atom.ts +0 -0
  332. /package/{realtime-react/src → src/realtime-react}/use-pull-mutable-family-member.ts +0 -0
  333. /package/{realtime-react/src → src/realtime-react}/use-pull-selector-family-member.ts +0 -0
  334. /package/{realtime-react/src → src/realtime-react}/use-pull-selector.ts +0 -0
  335. /package/{realtime-react/src → src/realtime-react}/use-push.ts +0 -0
  336. /package/{realtime-react/src → src/realtime-react}/use-realtime-service.ts +0 -0
  337. /package/{realtime-react/src → src/realtime-react}/use-server-action.ts +0 -0
  338. /package/{realtime-react/src → src/realtime-react}/use-sync-continuity.ts +0 -0
  339. /package/{realtime-server/src → src/realtime-server}/README.md +0 -0
  340. /package/{realtime-server/src → src/realtime-server}/continuity/prepare-to-send-initial-payload.ts +0 -0
  341. /package/{realtime-server/src → src/realtime-server}/continuity/prepare-to-serve-transaction-request.ts +0 -0
  342. /package/{realtime-server/src → src/realtime-server}/continuity/prepare-to-sync-realtime-continuity.ts +0 -0
  343. /package/{realtime-server/src → src/realtime-server}/continuity/prepare-to-track-client-acknowledgement.ts +0 -0
  344. /package/{realtime-server/src → src/realtime-server}/continuity/subscribe-to-continuity-actions.ts +0 -0
  345. /package/{realtime-server/src → src/realtime-server}/continuity/subscribe-to-continuity-perpectives.ts +0 -0
  346. /package/{realtime-server/src → src/realtime-server}/index.ts +0 -0
  347. /package/{realtime-server/src → src/realtime-server}/ipc-sockets/child-socket.ts +0 -0
  348. /package/{realtime-server/src → src/realtime-server}/ipc-sockets/custom-socket.ts +0 -0
  349. /package/{realtime-server/src → src/realtime-server}/ipc-sockets/index.ts +0 -0
  350. /package/{realtime-server/src → src/realtime-server}/ipc-sockets/parent-socket.ts +0 -0
  351. /package/{realtime-server/src → src/realtime-server}/realtime-action-receiver.ts +0 -0
  352. /package/{realtime-server/src → src/realtime-server}/realtime-family-provider.ts +0 -0
  353. /package/{realtime-server/src → src/realtime-server}/realtime-mutable-family-provider.ts +0 -0
  354. /package/{realtime-server/src → src/realtime-server}/realtime-mutable-provider.ts +0 -0
  355. /package/{realtime-server/src → src/realtime-server}/realtime-server-stores/index.ts +0 -0
  356. /package/{realtime-server/src → src/realtime-server}/realtime-state-provider.ts +0 -0
  357. /package/{realtime-server/src → src/realtime-server}/realtime-state-receiver.ts +0 -0
  358. /package/{realtime-testing/src → src/realtime-testing}/index.ts +0 -0
  359. /package/{realtime-testing/src → src/realtime-testing}/setup-realtime-test.tsx +0 -0
  360. /package/{transceivers/set-rtx/src → src/transceivers/set-rtx}/index.ts +0 -0
  361. /package/{web/src → src/web}/index.ts +0 -0
  362. /package/{web/src → src/web}/persist-sync.ts +0 -0
@@ -0,0 +1,3213 @@
1
+ import { arbitrary as arbitrary$1, subscribeToState as subscribeToState$1, subscribeToTimeline as subscribeToTimeline$1, subscribeToTransaction as subscribeToTransaction$1 } from "atom.io/internal";
2
+ import { parseJson, selectJson, selectJsonFamily, stringifyJson } from "atom.io/json";
3
+ import { Anarchy, AtomIOLogger } from "atom.io";
4
+ import { SetRTX } from "atom.io/transceivers/set-rtx";
5
+
6
+ //#region src/internal/arbitrary.ts
7
+ function arbitrary(random = Math.random) {
8
+ return random().toString(36).slice(2);
9
+ }
10
+
11
+ //#endregion
12
+ //#region src/internal/future.ts
13
+ /**
14
+ * A Promise whose incoming value can be hot swapped.
15
+ * @internal
16
+ * @private
17
+ * @typeParam T The type of the value that the promise will resolve to.
18
+ *
19
+ * @remarks
20
+ * Can be constructed like a Promise, or from an existing Promise.
21
+ */
22
+ var Future = class extends Promise {
23
+ fate;
24
+ resolve;
25
+ reject;
26
+ done = false;
27
+ constructor(executor) {
28
+ let superResolve;
29
+ let superReject;
30
+ super((resolve, reject) => {
31
+ superResolve = resolve;
32
+ superReject = reject;
33
+ });
34
+ this.resolve = superResolve;
35
+ this.reject = superReject;
36
+ this.use(executor instanceof Promise ? executor : new Promise(executor));
37
+ }
38
+ pass(promise, value) {
39
+ if (promise === this.fate) {
40
+ this.resolve(value);
41
+ this.done = true;
42
+ }
43
+ }
44
+ fail(promise, reason) {
45
+ if (promise === this.fate) {
46
+ this.reject(reason);
47
+ this.done = true;
48
+ }
49
+ }
50
+ use(value) {
51
+ if (value instanceof Promise) {
52
+ const promise = value;
53
+ this.fate = promise;
54
+ promise.then((resolved) => {
55
+ this.pass(promise, resolved);
56
+ }, (reason) => {
57
+ this.fail(promise, reason);
58
+ });
59
+ } else {
60
+ this.resolve(value);
61
+ this.fate = void 0;
62
+ }
63
+ }
64
+ };
65
+
66
+ //#endregion
67
+ //#region src/internal/lineage.ts
68
+ function newest(scion) {
69
+ while (scion.child !== null) scion = scion.child;
70
+ return scion;
71
+ }
72
+
73
+ //#endregion
74
+ //#region src/internal/store/circular-buffer.ts
75
+ var CircularBuffer = class CircularBuffer {
76
+ _buffer;
77
+ _index = 0;
78
+ constructor(lengthOrArray) {
79
+ let length;
80
+ if (typeof lengthOrArray === `number`) length = lengthOrArray;
81
+ else length = lengthOrArray.length;
82
+ this._buffer = Array.from({ length });
83
+ }
84
+ get buffer() {
85
+ return this._buffer;
86
+ }
87
+ get index() {
88
+ return this._index;
89
+ }
90
+ add(item) {
91
+ this._buffer[this._index] = item;
92
+ this._index = (this._index + 1) % this._buffer.length;
93
+ }
94
+ copy() {
95
+ const copy = new CircularBuffer([...this._buffer]);
96
+ copy._index = this._index;
97
+ return copy;
98
+ }
99
+ };
100
+
101
+ //#endregion
102
+ //#region src/internal/store/counterfeit.ts
103
+ const FAMILY_MEMBER_TOKEN_TYPES = {
104
+ atom_family: `atom`,
105
+ mutable_atom_family: `mutable_atom`,
106
+ selector_family: `selector`,
107
+ readonly_selector_family: `readonly_selector`,
108
+ molecule_family: `molecule`
109
+ };
110
+ function counterfeit(token, key) {
111
+ const subKey = stringifyJson(key);
112
+ const fullKey = `${token.key}(${subKey})`;
113
+ const type = FAMILY_MEMBER_TOKEN_TYPES[token.type];
114
+ const stateToken = {
115
+ key: fullKey,
116
+ type
117
+ };
118
+ Object.assign(stateToken, { family: {
119
+ key: token.key,
120
+ subKey
121
+ } });
122
+ Object.assign(stateToken, { counterfeit: true });
123
+ return stateToken;
124
+ }
125
+
126
+ //#endregion
127
+ //#region src/internal/store/deposit.ts
128
+ function deposit(state) {
129
+ const token = {
130
+ key: state.key,
131
+ type: state.type
132
+ };
133
+ if (`family` in state) token.family = state.family;
134
+ return token;
135
+ }
136
+
137
+ //#endregion
138
+ //#region src/internal/junction.ts
139
+ var Junction = class {
140
+ a;
141
+ b;
142
+ cardinality;
143
+ relations = new Map();
144
+ contents = new Map();
145
+ isAType;
146
+ isBType;
147
+ isContent;
148
+ makeContentKey = (a, b) => `${a}:${b}`;
149
+ warn;
150
+ getRelatedKeys(key) {
151
+ return this.relations.get(key);
152
+ }
153
+ addRelation(a, b) {
154
+ let aRelations = this.relations.get(a);
155
+ let bRelations = this.relations.get(b);
156
+ if (aRelations) aRelations.add(b);
157
+ else {
158
+ aRelations = new Set([b]);
159
+ this.relations.set(a, aRelations);
160
+ }
161
+ if (bRelations) bRelations.add(a);
162
+ else {
163
+ bRelations = new Set([a]);
164
+ this.relations.set(b, bRelations);
165
+ }
166
+ }
167
+ deleteRelation(a, b) {
168
+ const aRelations = this.relations.get(a);
169
+ if (aRelations) {
170
+ aRelations.delete(b);
171
+ if (aRelations.size === 0) this.relations.delete(a);
172
+ const bRelations = this.relations.get(b);
173
+ if (bRelations) {
174
+ bRelations.delete(a);
175
+ if (bRelations.size === 0) this.relations.delete(b);
176
+ }
177
+ }
178
+ }
179
+ replaceRelationsUnsafely(x, ys) {
180
+ this.relations.set(x, new Set(ys));
181
+ for (const y of ys) {
182
+ const yRelations = new Set().add(x);
183
+ this.relations.set(y, yRelations);
184
+ }
185
+ }
186
+ replaceRelationsSafely(x, ys) {
187
+ const xRelationsPrev = this.relations.get(x);
188
+ let a = this.isAType?.(x) ? x : void 0;
189
+ let b = a === void 0 ? x : void 0;
190
+ if (xRelationsPrev) for (const y of xRelationsPrev) {
191
+ a ??= y;
192
+ b ??= y;
193
+ const yRelations = this.relations.get(y);
194
+ if (yRelations) {
195
+ if (yRelations.size === 1) this.relations.delete(y);
196
+ else yRelations.delete(x);
197
+ this.contents.delete(this.makeContentKey(a, b));
198
+ }
199
+ }
200
+ this.relations.set(x, new Set(ys));
201
+ for (const y of ys) {
202
+ let yRelations = this.relations.get(y);
203
+ if (yRelations) yRelations.add(x);
204
+ else {
205
+ yRelations = new Set().add(x);
206
+ this.relations.set(y, yRelations);
207
+ }
208
+ }
209
+ }
210
+ getContentInternal(contentKey) {
211
+ return this.contents.get(contentKey);
212
+ }
213
+ setContent(contentKey, content) {
214
+ this.contents.set(contentKey, content);
215
+ }
216
+ deleteContent(contentKey) {
217
+ this.contents.delete(contentKey);
218
+ }
219
+ constructor(data, config) {
220
+ this.a = data.between[0];
221
+ this.b = data.between[1];
222
+ this.cardinality = data.cardinality;
223
+ if (!config?.externalStore) {
224
+ this.relations = new Map(data.relations?.map(([x, ys]) => [x, new Set(ys)]));
225
+ this.contents = new Map(data.contents);
226
+ }
227
+ this.isAType = config?.isAType ?? null;
228
+ this.isBType = config?.isBType ?? null;
229
+ this.isContent = config?.isContent ?? null;
230
+ if (config?.makeContentKey) this.makeContentKey = config.makeContentKey;
231
+ if (config?.externalStore) {
232
+ const externalStore = config.externalStore;
233
+ this.has = (a, b) => externalStore.has(a, b);
234
+ this.addRelation = (a, b) => {
235
+ externalStore.addRelation(a, b);
236
+ };
237
+ this.deleteRelation = (a, b) => {
238
+ externalStore.deleteRelation(a, b);
239
+ };
240
+ this.replaceRelationsSafely = (a, bs) => {
241
+ externalStore.replaceRelationsSafely(a, bs);
242
+ };
243
+ this.replaceRelationsUnsafely = (a, bs) => {
244
+ externalStore.replaceRelationsUnsafely(a, bs);
245
+ };
246
+ this.getRelatedKeys = (key) => externalStore.getRelatedKeys(key);
247
+ if (externalStore.getContent) {
248
+ this.getContentInternal = (contentKey) => {
249
+ return externalStore.getContent(contentKey);
250
+ };
251
+ this.setContent = (contentKey, content) => {
252
+ externalStore.setContent(contentKey, content);
253
+ };
254
+ this.deleteContent = (contentKey) => {
255
+ externalStore.deleteContent(contentKey);
256
+ };
257
+ }
258
+ for (const [x, ys] of data.relations ?? []) {
259
+ let a = this.isAType?.(x) ? x : void 0;
260
+ let b = a === void 0 ? x : void 0;
261
+ for (const y of ys) {
262
+ a ??= y;
263
+ b ??= y;
264
+ this.addRelation(a, b);
265
+ }
266
+ }
267
+ for (const [contentKey, content] of data.contents ?? []) this.setContent(contentKey, content);
268
+ }
269
+ if (config?.warn) this.warn = config.warn;
270
+ }
271
+ toJSON() {
272
+ return {
273
+ between: [this.a, this.b],
274
+ cardinality: this.cardinality,
275
+ relations: [...this.relations.entries()].map(([a, b]) => [a, [...b]]),
276
+ contents: [...this.contents.entries()]
277
+ };
278
+ }
279
+ set(...params) {
280
+ let a;
281
+ let b;
282
+ let content;
283
+ switch (params.length) {
284
+ case 1: {
285
+ const relation = params[0];
286
+ a = relation[this.a];
287
+ b = relation[this.b];
288
+ content = void 0;
289
+ break;
290
+ }
291
+ case 2: {
292
+ const zeroth = params[0];
293
+ if (typeof zeroth === `string`) [a, b] = params;
294
+ else {
295
+ a = zeroth[this.a];
296
+ b = zeroth[this.b];
297
+ content = params[1];
298
+ }
299
+ break;
300
+ }
301
+ default: {
302
+ a = params[0];
303
+ b = params[1];
304
+ content = params[2];
305
+ break;
306
+ }
307
+ }
308
+ switch (this.cardinality) {
309
+ case `1:1`: {
310
+ const bPrev = this.getRelatedKey(a);
311
+ if (bPrev && bPrev !== b) this.delete(a, bPrev);
312
+ }
313
+ case `1:n`:
314
+ {
315
+ const aPrev = this.getRelatedKey(b);
316
+ if (aPrev && aPrev !== a) this.delete(aPrev, b);
317
+ }
318
+ break;
319
+ case `n:n`:
320
+ }
321
+ if (content) {
322
+ const contentKey = this.makeContentKey(a, b);
323
+ this.setContent(contentKey, content);
324
+ }
325
+ this.addRelation(a, b);
326
+ return this;
327
+ }
328
+ delete(x, b) {
329
+ b = typeof b === `string` ? b : x[this.b];
330
+ const a = typeof x === `string` ? x : x[this.a];
331
+ if (a === void 0 && typeof b === `string`) {
332
+ const bRelations = this.getRelatedKeys(b);
333
+ if (bRelations) for (const bRelation of bRelations) this.delete(bRelation, b);
334
+ }
335
+ if (typeof a === `string` && b === void 0) {
336
+ const aRelations = this.getRelatedKeys(a);
337
+ if (aRelations) for (const aRelation of aRelations) this.delete(a, aRelation);
338
+ }
339
+ if (typeof a === `string` && typeof b === `string`) {
340
+ this.deleteRelation(a, b);
341
+ const contentKey = this.makeContentKey(a, b);
342
+ this.deleteContent(contentKey);
343
+ }
344
+ return this;
345
+ }
346
+ getRelatedKey(key) {
347
+ const relations = this.getRelatedKeys(key);
348
+ if (relations) {
349
+ if (relations.size > 1) this.warn?.(`${relations.size} related keys were found for key "${key}": (${[...relations].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`);
350
+ let singleRelation;
351
+ for (const relation of relations) {
352
+ singleRelation = relation;
353
+ break;
354
+ }
355
+ return singleRelation;
356
+ }
357
+ }
358
+ replaceRelations(x, relations, config) {
359
+ const hasContent = !Array.isArray(relations);
360
+ const ys = hasContent ? Object.keys(relations) : relations;
361
+ if (config?.reckless) this.replaceRelationsUnsafely(x, ys);
362
+ else this.replaceRelationsSafely(x, ys);
363
+ if (hasContent) for (const y of ys) {
364
+ const contentKey = this.makeContentKey(x, y);
365
+ const content = relations[y];
366
+ this.setContent(contentKey, content);
367
+ }
368
+ return this;
369
+ }
370
+ getContent(a, b) {
371
+ const contentKey = this.makeContentKey(a, b);
372
+ return this.getContentInternal(contentKey);
373
+ }
374
+ getRelationEntries(input) {
375
+ const a = input[this.a];
376
+ const b = input[this.b];
377
+ if (a !== void 0 && b === void 0) {
378
+ const aRelations = this.getRelatedKeys(a);
379
+ if (aRelations) return [...aRelations].map((aRelation) => {
380
+ return [aRelation, this.getContent(a, aRelation)];
381
+ });
382
+ }
383
+ if (a === void 0 && b !== void 0) {
384
+ const bRelations = this.getRelatedKeys(b);
385
+ if (bRelations) return [...bRelations].map((bRelation) => {
386
+ return [bRelation, this.getContent(bRelation, b)];
387
+ });
388
+ }
389
+ return [];
390
+ }
391
+ has(a, b) {
392
+ if (b) {
393
+ const setA = this.getRelatedKeys(a);
394
+ return setA?.has(b) ?? false;
395
+ }
396
+ return this.relations.has(a);
397
+ }
398
+ };
399
+
400
+ //#endregion
401
+ //#region src/internal/subject.ts
402
+ var Subject = class {
403
+ Subscriber;
404
+ subscribers = new Map();
405
+ subscribe(key, subscriber) {
406
+ this.subscribers.set(key, subscriber);
407
+ const unsubscribe = () => {
408
+ this.unsubscribe(key);
409
+ };
410
+ return unsubscribe;
411
+ }
412
+ unsubscribe(key) {
413
+ this.subscribers.delete(key);
414
+ }
415
+ next(value) {
416
+ const subscribers = this.subscribers.values();
417
+ for (const subscriber of subscribers) subscriber(value);
418
+ }
419
+ };
420
+ var StatefulSubject = class extends Subject {
421
+ state;
422
+ constructor(initialState) {
423
+ super();
424
+ this.state = initialState;
425
+ }
426
+ next(value) {
427
+ this.state = value;
428
+ super.next(value);
429
+ }
430
+ };
431
+
432
+ //#endregion
433
+ //#region src/internal/transaction/is-root-store.ts
434
+ function isRootStore(store) {
435
+ return `epoch` in store.transactionMeta;
436
+ }
437
+ function isChildStore(store) {
438
+ return `phase` in store.transactionMeta;
439
+ }
440
+
441
+ //#endregion
442
+ //#region src/internal/transaction/abort-transaction.ts
443
+ const abortTransaction = (store) => {
444
+ const target = newest(store);
445
+ if (!isChildStore(target)) {
446
+ store.logger.warn(`🐞`, `transaction`, `???`, `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`);
447
+ return;
448
+ }
449
+ store.logger.info(`🪂`, `transaction`, target.transactionMeta.update.key, `Aborting transaction`);
450
+ target.parent.child = null;
451
+ };
452
+
453
+ //#endregion
454
+ //#region src/internal/capitalize.ts
455
+ function capitalize(string) {
456
+ return string[0].toUpperCase() + string.slice(1);
457
+ }
458
+
459
+ //#endregion
460
+ //#region src/internal/pretty-print.ts
461
+ function prettyPrintTokenType(token) {
462
+ return token.type.split(`_`).map(capitalize).join(` `);
463
+ }
464
+
465
+ //#endregion
466
+ //#region src/internal/not-found-error.ts
467
+ var NotFoundError = class extends Error {
468
+ constructor(token, store) {
469
+ super(`${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${store.config.name}".`);
470
+ }
471
+ };
472
+
473
+ //#endregion
474
+ //#region src/internal/transaction/act-upon-store.ts
475
+ function actUponStore(store, token, id) {
476
+ return (...parameters) => {
477
+ const tx = withdraw(store, token);
478
+ if (tx) return tx.run(parameters, id);
479
+ throw new NotFoundError(token, store);
480
+ };
481
+ }
482
+
483
+ //#endregion
484
+ //#region src/internal/set-state/become.ts
485
+ const become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(originalThing) : nextVersionOfThing;
486
+
487
+ //#endregion
488
+ //#region src/internal/get-state/read-or-compute-value.ts
489
+ const readOrComputeValue = (target, state) => {
490
+ if (target.valueMap.has(state.key)) {
491
+ target.logger.info(`📖`, state.type, state.key, `reading cached value`);
492
+ return readCachedValue(state, target);
493
+ }
494
+ switch (state.type) {
495
+ case `selector`:
496
+ case `readonly_selector`:
497
+ target.logger.info(`🧮`, state.type, state.key, `computing value`);
498
+ return state.get();
499
+ case `atom`:
500
+ case `mutable_atom`: {
501
+ const def = state.default;
502
+ let fallback;
503
+ if (def instanceof Function) fallback = def();
504
+ else fallback = def;
505
+ target.logger.info(`💁`, `atom`, state.key, `could not find cached value; using default`, fallback);
506
+ return fallback;
507
+ }
508
+ }
509
+ };
510
+
511
+ //#endregion
512
+ //#region src/internal/operation.ts
513
+ const openOperation = (store, token) => {
514
+ if (store.operation.open) {
515
+ const rejectionTime = performance.now();
516
+ store.logger.info(`❗`, token.type, token.key, `deferring setState at T-${rejectionTime} until setState for "${store.operation.token.key}" is done`);
517
+ return rejectionTime;
518
+ }
519
+ store.operation = {
520
+ open: true,
521
+ done: new Set(),
522
+ prev: new Map(),
523
+ time: Date.now(),
524
+ token
525
+ };
526
+ store.logger.info(`⭕`, token.type, token.key, `operation start in store "${store.config.name}"${!isChildStore(store) ? `` : ` ${store.transactionMeta.phase} "${store.transactionMeta.update.key}"`}`);
527
+ };
528
+ const closeOperation = (store) => {
529
+ if (store.operation.open) store.logger.info(`🔴`, store.operation.token.type, store.operation.token.key, `operation done in store "${store.config.name}"`);
530
+ store.operation = { open: false };
531
+ store.on.operationClose.next(store.operation);
532
+ };
533
+ const isDone = (store, key) => {
534
+ if (!store.operation.open) {
535
+ store.logger.error(`🐞`, `unknown`, key, `isDone called outside of an operation. This is probably a bug in AtomIO.`);
536
+ return true;
537
+ }
538
+ return store.operation.done.has(key);
539
+ };
540
+ const markDone = (store, key) => {
541
+ if (!store.operation.open) {
542
+ store.logger.error(`🐞`, `unknown`, key, `markDone called outside of an operation. This is probably a bug in AtomIO.`);
543
+ return;
544
+ }
545
+ store.operation.done.add(key);
546
+ };
547
+
548
+ //#endregion
549
+ //#region src/internal/set-state/emit-update.ts
550
+ const emitUpdate = (store, state, update) => {
551
+ switch (state.type) {
552
+ case `mutable_atom`:
553
+ store.logger.info(`📢`, state.type, state.key, `is now (`, update.newValue, `) subscribers:`, state.subject.subscribers);
554
+ break;
555
+ case `atom`:
556
+ case `selector`:
557
+ case `readonly_selector`: store.logger.info(`📢`, state.type, state.key, `went (`, update.oldValue, `->`, update.newValue, `) subscribers:`, state.subject.subscribers);
558
+ }
559
+ state.subject.next(update);
560
+ };
561
+
562
+ //#endregion
563
+ //#region src/internal/set-state/evict-downstream.ts
564
+ const evictDownStream = (store, atom$1) => {
565
+ const target = newest(store);
566
+ const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom$1.key);
567
+ target.logger.info(`🧹`, atom$1.type, atom$1.key, downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`, downstreamKeys ?? `to evict`);
568
+ if (downstreamKeys) {
569
+ if (target.operation.open) target.logger.info(`🧹`, atom$1.type, atom$1.key, `[ ${[...target.operation.done].join(`, `)} ] already done`);
570
+ for (const key of downstreamKeys) {
571
+ if (isDone(target, key)) continue;
572
+ evictCachedValue(key, target);
573
+ markDone(target, key);
574
+ }
575
+ }
576
+ };
577
+
578
+ //#endregion
579
+ //#region src/internal/set-state/set-atom.ts
580
+ const setAtom = (target, atom$1, next) => {
581
+ const oldValue = readOrComputeValue(target, atom$1);
582
+ let newValue = oldValue;
583
+ if (atom$1.type === `mutable_atom` && isChildStore(target)) {
584
+ const { parent } = target;
585
+ const copiedValue = copyMutableIfNeeded(target, atom$1, parent);
586
+ newValue = copiedValue;
587
+ }
588
+ newValue = become(next)(newValue);
589
+ target.logger.info(`📝`, `atom`, atom$1.key, `set to`, newValue);
590
+ newValue = cacheValue(target, atom$1.key, newValue, atom$1.subject);
591
+ if (isAtomDefault(target, atom$1.key)) markAtomAsNotDefault(target, atom$1.key);
592
+ markDone(target, atom$1.key);
593
+ evictDownStream(target, atom$1);
594
+ const update = {
595
+ oldValue,
596
+ newValue
597
+ };
598
+ if (!isChildStore(target)) {
599
+ emitUpdate(target, atom$1, update);
600
+ return;
601
+ }
602
+ if (target.on.transactionApplying.state === null) {
603
+ const { key } = atom$1;
604
+ if (isTransceiver(update.newValue)) return;
605
+ const atomUpdate = {
606
+ type: `atom_update`,
607
+ key,
608
+ ...update
609
+ };
610
+ if (atom$1.family) atomUpdate.family = atom$1.family;
611
+ target.transactionMeta.update.updates.push(atomUpdate);
612
+ target.logger.info(`📁`, `atom`, key, `stowed (`, update.oldValue, `->`, update.newValue, `)`);
613
+ } else if (atom$1.key.startsWith(`*`)) {
614
+ const mutableKey = atom$1.key.slice(1);
615
+ const mutableAtom = target.atoms.get(mutableKey);
616
+ let transceiver = target.valueMap.get(mutableKey);
617
+ if (mutableAtom.type === `mutable_atom` && isChildStore(target)) {
618
+ const { parent } = target;
619
+ const copiedValue = copyMutableIfNeeded(target, mutableAtom, parent);
620
+ transceiver = copiedValue;
621
+ }
622
+ const accepted = transceiver.do(update.newValue) === null;
623
+ if (accepted) evictDownStream(target, mutableAtom);
624
+ }
625
+ };
626
+
627
+ //#endregion
628
+ //#region src/internal/set-state/set-atom-or-selector.ts
629
+ const setAtomOrSelector = (store, state, value) => {
630
+ switch (state.type) {
631
+ case `atom`:
632
+ case `mutable_atom`:
633
+ setAtom(store, state, value);
634
+ break;
635
+ case `selector`:
636
+ state.set(value);
637
+ break;
638
+ }
639
+ };
640
+
641
+ //#endregion
642
+ //#region src/internal/families/create-regular-atom-family.ts
643
+ function createRegularAtomFamily(store, options, internalRoles) {
644
+ const familyToken = {
645
+ key: options.key,
646
+ type: `atom_family`
647
+ };
648
+ const existing = store.families.get(options.key);
649
+ if (existing) store.logger.error(`❗`, `atom_family`, options.key, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
650
+ const subject = new Subject();
651
+ const familyFunction = (key) => {
652
+ const subKey = stringifyJson(key);
653
+ const family = {
654
+ key: options.key,
655
+ subKey
656
+ };
657
+ const fullKey = `${options.key}(${subKey})`;
658
+ const target = newest(store);
659
+ const def = options.default;
660
+ const individualOptions = {
661
+ key: fullKey,
662
+ default: def instanceof Function ? def(key) : def
663
+ };
664
+ if (options.effects) individualOptions.effects = options.effects(key);
665
+ const token = createRegularAtom(target, individualOptions, family);
666
+ subject.next({
667
+ type: `state_creation`,
668
+ token
669
+ });
670
+ return token;
671
+ };
672
+ const atomFamily$1 = Object.assign(familyFunction, familyToken, {
673
+ subject,
674
+ install: (s) => createRegularAtomFamily(s, options),
675
+ internalRoles
676
+ });
677
+ store.families.set(options.key, atomFamily$1);
678
+ store.defaults.set(options.key, options.default);
679
+ return familyToken;
680
+ }
681
+
682
+ //#endregion
683
+ //#region src/internal/families/create-atom-family.ts
684
+ function createAtomFamily(store, options) {
685
+ const isMutable = `mutable` in options;
686
+ if (isMutable) return createMutableAtomFamily(store, options);
687
+ return createRegularAtomFamily(store, options);
688
+ }
689
+
690
+ //#endregion
691
+ //#region src/internal/keys.ts
692
+ const isAtomKey = (store, key) => newest(store).atoms.has(key);
693
+ const isSelectorKey = (store, key) => newest(store).selectors.has(key);
694
+ const isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
695
+ const isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
696
+
697
+ //#endregion
698
+ //#region src/internal/selector/get-selector-dependency-keys.ts
699
+ const getSelectorDependencyKeys = (key, store) => {
700
+ const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(store, source));
701
+ return sources;
702
+ };
703
+
704
+ //#endregion
705
+ //#region src/internal/selector/trace-selector-atoms.ts
706
+ const traceSelectorAtoms = (directDependencyKey, covered, store) => {
707
+ const rootKeys = [];
708
+ const indirectDependencyKeys = getSelectorDependencyKeys(directDependencyKey, store);
709
+ while (indirectDependencyKeys.length > 0) {
710
+ const indirectDependencyKey = indirectDependencyKeys.shift();
711
+ if (covered.has(indirectDependencyKey)) continue;
712
+ covered.add(indirectDependencyKey);
713
+ if (!isAtomKey(store, indirectDependencyKey)) indirectDependencyKeys.push(...getSelectorDependencyKeys(indirectDependencyKey, store));
714
+ else if (!rootKeys.includes(indirectDependencyKey)) rootKeys.push(indirectDependencyKey);
715
+ }
716
+ return rootKeys;
717
+ };
718
+ const traceAllSelectorAtoms = (selector, store) => {
719
+ const selectorKey = selector.key;
720
+ const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
721
+ const covered = new Set();
722
+ return directDependencyKeys.flatMap((depKey) => isAtomKey(store, depKey) ? depKey : traceSelectorAtoms(depKey, covered, store));
723
+ };
724
+
725
+ //#endregion
726
+ //#region src/internal/selector/update-selector-atoms.ts
727
+ const updateSelectorAtoms = (selectorKey, dependency, covered, store) => {
728
+ const target = newest(store);
729
+ if (dependency.type === `atom` || dependency.type === `mutable_atom`) {
730
+ target.selectorAtoms.set({
731
+ selectorKey,
732
+ atomKey: dependency.key
733
+ });
734
+ store.logger.info(`🔍`, `selector`, selectorKey, `discovers root atom "${dependency.key}"`);
735
+ } else {
736
+ const rootKeys = traceSelectorAtoms(dependency.key, covered, store);
737
+ store.logger.info(`🔍`, `selector`, selectorKey, `discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`);
738
+ for (const atomKey of rootKeys) target.selectorAtoms = target.selectorAtoms.set({
739
+ selectorKey,
740
+ atomKey
741
+ });
742
+ }
743
+ covered.add(dependency.key);
744
+ };
745
+
746
+ //#endregion
747
+ //#region src/internal/selector/register-selector.ts
748
+ const registerSelector = (selectorKey, covered, store) => ({
749
+ get: (...params) => {
750
+ const target = newest(store);
751
+ let dependency;
752
+ if (params.length === 2) {
753
+ const [family, key] = params;
754
+ dependency = findInStore(store, family, key);
755
+ } else [dependency] = params;
756
+ const dependencyState = withdraw(store, dependency);
757
+ const dependencyValue = readOrComputeValue(store, dependencyState);
758
+ store.logger.info(`🔌`, `selector`, selectorKey, `registers dependency ( "${dependency.key}" =`, dependencyValue, `)`);
759
+ target.selectorGraph.set({
760
+ upstreamSelectorKey: dependency.key,
761
+ downstreamSelectorKey: selectorKey
762
+ }, { source: dependency.key });
763
+ updateSelectorAtoms(selectorKey, dependency, covered, store);
764
+ return dependencyValue;
765
+ },
766
+ set: (...params) => {
767
+ let token;
768
+ let value;
769
+ if (params.length === 2) {
770
+ token = params[0];
771
+ value = params[1];
772
+ } else {
773
+ const family = params[0];
774
+ const key = params[1];
775
+ value = params[2];
776
+ token = findInStore(store, family, key);
777
+ }
778
+ const target = newest(store);
779
+ const state = withdraw(target, token);
780
+ setAtomOrSelector(target, state, value);
781
+ },
782
+ find: (...args) => findInStore(store, ...args),
783
+ json: (token) => getJsonToken(store, token)
784
+ });
785
+
786
+ //#endregion
787
+ //#region src/internal/selector/create-readonly-selector.ts
788
+ const createReadonlySelector = (store, options, family) => {
789
+ const target = newest(store);
790
+ const subject = new Subject();
791
+ const covered = new Set();
792
+ const { get, find, json } = registerSelector(options.key, covered, target);
793
+ const getSelf = () => {
794
+ const value = options.get({
795
+ get,
796
+ find,
797
+ json
798
+ });
799
+ cacheValue(newest(store), options.key, value, subject);
800
+ covered.clear();
801
+ return value;
802
+ };
803
+ const readonlySelector = {
804
+ ...options,
805
+ subject,
806
+ install: (s) => createReadonlySelector(s, options, family),
807
+ get: getSelf,
808
+ type: `readonly_selector`,
809
+ ...family && { family }
810
+ };
811
+ target.readonlySelectors.set(options.key, readonlySelector);
812
+ const initialValue = getSelf();
813
+ store.logger.info(`✨`, readonlySelector.type, readonlySelector.key, `=`, initialValue);
814
+ const token = {
815
+ key: options.key,
816
+ type: `readonly_selector`
817
+ };
818
+ if (family) token.family = family;
819
+ return token;
820
+ };
821
+
822
+ //#endregion
823
+ //#region src/internal/selector/create-writable-selector.ts
824
+ const createWritableSelector = (store, options, family) => {
825
+ const target = newest(store);
826
+ const subject = new Subject();
827
+ const covered = new Set();
828
+ const setterToolkit = registerSelector(options.key, covered, target);
829
+ const { find, get, json } = setterToolkit;
830
+ const getterToolkit = {
831
+ find,
832
+ get,
833
+ json
834
+ };
835
+ const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
836
+ const value = getFn(getterToolkit);
837
+ cacheValue(innerTarget, options.key, value, subject);
838
+ covered.clear();
839
+ return value;
840
+ };
841
+ const setSelf = (next) => {
842
+ const innerTarget = newest(store);
843
+ const oldValue = getSelf(options.get, innerTarget);
844
+ const newValue = become(next)(oldValue);
845
+ store.logger.info(`📝`, `selector`, options.key, `set (`, oldValue, `->`, newValue, `)`);
846
+ cacheValue(innerTarget, options.key, newValue, subject);
847
+ markDone(innerTarget, options.key);
848
+ if (isRootStore(innerTarget)) subject.next({
849
+ newValue,
850
+ oldValue
851
+ });
852
+ options.set(setterToolkit, newValue);
853
+ };
854
+ const mySelector = {
855
+ ...options,
856
+ subject,
857
+ install: (s) => createWritableSelector(s, options, family),
858
+ get: getSelf,
859
+ set: setSelf,
860
+ type: `selector`,
861
+ ...family && { family }
862
+ };
863
+ target.selectors.set(options.key, mySelector);
864
+ const initialValue = getSelf();
865
+ store.logger.info(`✨`, mySelector.type, mySelector.key, `=`, initialValue);
866
+ const token = {
867
+ key: options.key,
868
+ type: `selector`
869
+ };
870
+ if (family) token.family = family;
871
+ return token;
872
+ };
873
+
874
+ //#endregion
875
+ //#region src/internal/selector/create-standalone-selector.ts
876
+ function createStandaloneSelector(store, options) {
877
+ const isWritable = `set` in options;
878
+ if (isWritable) {
879
+ const state$1 = createWritableSelector(store, options, void 0);
880
+ store.on.selectorCreation.next(state$1);
881
+ return state$1;
882
+ }
883
+ const state = createReadonlySelector(store, options, void 0);
884
+ store.on.selectorCreation.next(state);
885
+ return state;
886
+ }
887
+
888
+ //#endregion
889
+ //#region src/internal/selector/dispose-selector.ts
890
+ function disposeSelector(store, selectorToken) {
891
+ const target = newest(store);
892
+ const { key } = selectorToken;
893
+ const selector = withdraw(target, selectorToken);
894
+ if (!selector.family) store.logger.error(`❌`, `selector`, key, `Standalone selectors cannot be disposed.`);
895
+ else {
896
+ const molecule = target.molecules.get(selector.family.subKey);
897
+ if (molecule) target.moleculeData.delete(selector.family.subKey, selector.family.key);
898
+ let familyToken;
899
+ switch (selectorToken.type) {
900
+ case `selector`:
901
+ {
902
+ target.selectors.delete(key);
903
+ familyToken = {
904
+ key: selector.family.key,
905
+ type: `selector_family`
906
+ };
907
+ const family = withdraw(store, familyToken);
908
+ family.subject.next({
909
+ type: `state_disposal`,
910
+ subType: `selector`,
911
+ token: selectorToken
912
+ });
913
+ }
914
+ break;
915
+ case `readonly_selector`:
916
+ {
917
+ target.readonlySelectors.delete(key);
918
+ familyToken = {
919
+ key: selector.family.key,
920
+ type: `readonly_selector_family`
921
+ };
922
+ const family = withdraw(store, familyToken);
923
+ family.subject.next({
924
+ type: `state_disposal`,
925
+ subType: `selector`,
926
+ token: selectorToken
927
+ });
928
+ }
929
+ break;
930
+ }
931
+ target.valueMap.delete(key);
932
+ target.selectorAtoms.delete(key);
933
+ target.selectorGraph.delete(key);
934
+ store.logger.info(`🔥`, selectorToken.type, key, `deleted`);
935
+ if (isChildStore(target) && target.transactionMeta.phase === `building`) target.transactionMeta.update.updates.push({
936
+ type: `state_disposal`,
937
+ subType: `selector`,
938
+ token: selectorToken
939
+ });
940
+ else store.on.selectorDisposal.next(selectorToken);
941
+ }
942
+ }
943
+
944
+ //#endregion
945
+ //#region src/internal/families/create-readonly-selector-family.ts
946
+ function createReadonlySelectorFamily(store, options, internalRoles) {
947
+ const familyToken = {
948
+ key: options.key,
949
+ type: `readonly_selector_family`
950
+ };
951
+ const existing = store.families.get(options.key);
952
+ if (existing) store.logger.error(`❗`, `readonly_selector_family`, options.key, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
953
+ const subject = new Subject();
954
+ const familyFunction = (key) => {
955
+ const subKey = stringifyJson(key);
956
+ const family = {
957
+ key: options.key,
958
+ subKey
959
+ };
960
+ const fullKey = `${options.key}(${subKey})`;
961
+ const target = newest(store);
962
+ const token = createReadonlySelector(target, {
963
+ key: fullKey,
964
+ get: options.get(key)
965
+ }, family);
966
+ subject.next({
967
+ type: `state_creation`,
968
+ token
969
+ });
970
+ return token;
971
+ };
972
+ const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
973
+ internalRoles,
974
+ subject,
975
+ install: (s) => createReadonlySelectorFamily(s, options),
976
+ default: (key) => {
977
+ const getFn = options.get(key);
978
+ return getFn({
979
+ get: (...args) => getFromStore(store, ...args),
980
+ find: (...args) => findInStore(store, ...args),
981
+ json: (token) => getJsonToken(store, token)
982
+ });
983
+ }
984
+ });
985
+ store.families.set(options.key, readonlySelectorFamily);
986
+ return familyToken;
987
+ }
988
+
989
+ //#endregion
990
+ //#region src/internal/families/create-writable-selector-family.ts
991
+ function createWritableSelectorFamily(store, options, internalRoles) {
992
+ const familyToken = {
993
+ key: options.key,
994
+ type: `selector_family`
995
+ };
996
+ const existing = store.families.get(options.key);
997
+ if (existing) store.logger.error(`❗`, `selector_family`, options.key, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
998
+ const subject = new Subject();
999
+ const familyFunction = (key) => {
1000
+ const subKey = stringifyJson(key);
1001
+ const family = {
1002
+ key: options.key,
1003
+ subKey
1004
+ };
1005
+ const fullKey = `${options.key}(${subKey})`;
1006
+ const target = newest(store);
1007
+ const token = createWritableSelector(target, {
1008
+ key: fullKey,
1009
+ get: options.get(key),
1010
+ set: options.set(key)
1011
+ }, family);
1012
+ subject.next({
1013
+ type: `state_creation`,
1014
+ token
1015
+ });
1016
+ return token;
1017
+ };
1018
+ const selectorFamily$1 = Object.assign(familyFunction, familyToken, {
1019
+ internalRoles,
1020
+ subject,
1021
+ install: (s) => createWritableSelectorFamily(s, options),
1022
+ default: (key) => {
1023
+ const getFn = options.get(key);
1024
+ return getFn({
1025
+ get: (...args) => getFromStore(store, ...args),
1026
+ find: (...args) => findInStore(store, ...args),
1027
+ json: (token) => getJsonToken(store, token)
1028
+ });
1029
+ }
1030
+ });
1031
+ store.families.set(options.key, selectorFamily$1);
1032
+ return familyToken;
1033
+ }
1034
+
1035
+ //#endregion
1036
+ //#region src/internal/families/create-selector-family.ts
1037
+ function createSelectorFamily(store, options) {
1038
+ const isWritable = `set` in options;
1039
+ if (isWritable) return createWritableSelectorFamily(store, options);
1040
+ return createReadonlySelectorFamily(store, options);
1041
+ }
1042
+
1043
+ //#endregion
1044
+ //#region src/internal/families/init-family-member.ts
1045
+ function initFamilyMemberInStore(store, token, key) {
1046
+ const family = store.families.get(token.key);
1047
+ if (family === void 0) throw new NotFoundError(token, store);
1048
+ const state = family(key);
1049
+ const target = newest(store);
1050
+ if (state.family) {
1051
+ if (isRootStore(target)) switch (state.type) {
1052
+ case `atom`:
1053
+ case `mutable_atom`:
1054
+ store.on.atomCreation.next(state);
1055
+ break;
1056
+ case `selector`:
1057
+ case `readonly_selector`:
1058
+ store.on.selectorCreation.next(state);
1059
+ break;
1060
+ }
1061
+ else if (isChildStore(target) && target.on.transactionApplying.state === null) target.transactionMeta.update.updates.push({
1062
+ type: `state_creation`,
1063
+ token: state
1064
+ });
1065
+ }
1066
+ return state;
1067
+ }
1068
+
1069
+ //#endregion
1070
+ //#region src/internal/families/seek-in-store.ts
1071
+ function seekInStore(store, token, key) {
1072
+ const subKey = stringifyJson(key);
1073
+ const fullKey = `${token.key}(${subKey})`;
1074
+ const target = newest(store);
1075
+ let state;
1076
+ switch (token.type) {
1077
+ case `atom_family`:
1078
+ case `mutable_atom_family`:
1079
+ state = target.atoms.get(fullKey);
1080
+ break;
1081
+ case `selector_family`:
1082
+ state = target.selectors.get(fullKey);
1083
+ break;
1084
+ case `readonly_selector_family`:
1085
+ state = target.readonlySelectors.get(fullKey);
1086
+ break;
1087
+ }
1088
+ if (state) return deposit(state);
1089
+ return state;
1090
+ }
1091
+
1092
+ //#endregion
1093
+ //#region src/internal/families/find-in-store.ts
1094
+ function findInStore(store, token, key) {
1095
+ let state = seekInStore(store, token, key);
1096
+ if (state) return state;
1097
+ const stringKey = stringifyJson(key);
1098
+ const molecule = store.molecules.get(stringKey);
1099
+ if (!molecule && store.config.lifespan === `immortal`) {
1100
+ const fakeToken = counterfeit(token, key);
1101
+ store.logger.error(`❌`, fakeToken.type, fakeToken.key, `was not found in store "${store.config.name}"; returned a counterfeit token.`);
1102
+ return fakeToken;
1103
+ }
1104
+ state = initFamilyMemberInStore(store, token, key);
1105
+ if (molecule) {
1106
+ const target = newest(store);
1107
+ target.moleculeData.set(stringKey, token.key);
1108
+ }
1109
+ return state;
1110
+ }
1111
+
1112
+ //#endregion
1113
+ //#region src/internal/families/dispose-from-store.ts
1114
+ function disposeFromStore(store, ...params) {
1115
+ let token;
1116
+ if (params.length === 1) token = params[0];
1117
+ else {
1118
+ const family = params[0];
1119
+ const key = params[1];
1120
+ const maybeToken = findInStore(store, family, key);
1121
+ token = maybeToken;
1122
+ }
1123
+ try {
1124
+ withdraw(store, token);
1125
+ } catch (thrown) {
1126
+ store.logger.error(`❌`, token.type, token.key, `could not be disposed because it was not found in the store "${store.config.name}".`);
1127
+ return;
1128
+ }
1129
+ switch (token.type) {
1130
+ case `atom`:
1131
+ case `mutable_atom`:
1132
+ disposeAtom(store, token);
1133
+ break;
1134
+ case `selector`:
1135
+ case `readonly_selector`:
1136
+ disposeSelector(store, token);
1137
+ break;
1138
+ }
1139
+ }
1140
+
1141
+ //#endregion
1142
+ //#region src/internal/families/get-family-of-token.ts
1143
+ function getFamilyOfToken(store, token) {
1144
+ if (token.family) {
1145
+ const family = store.families.get(token.family.key);
1146
+ if (family) return family;
1147
+ }
1148
+ }
1149
+
1150
+ //#endregion
1151
+ //#region src/internal/set-state/set-into-store.ts
1152
+ function setIntoStore(store, ...params) {
1153
+ let token;
1154
+ let family;
1155
+ let key;
1156
+ let value;
1157
+ if (params.length === 2) {
1158
+ token = params[0];
1159
+ value = params[1];
1160
+ family = getFamilyOfToken(store, token) ?? null;
1161
+ if (family) {
1162
+ key = token.family ? parseJson(token.family.subKey) : null;
1163
+ token = findInStore(store, family, key);
1164
+ }
1165
+ } else {
1166
+ family = params[0];
1167
+ key = params[1];
1168
+ value = params[2];
1169
+ token = findInStore(store, family, key);
1170
+ }
1171
+ if (`counterfeit` in token && `family` in token) {
1172
+ const subKey = token.family.subKey;
1173
+ const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
1174
+ store.logger.error(`❌`, token.type, token.key, `could not be set because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
1175
+ return;
1176
+ }
1177
+ const rejectionTime = openOperation(store, token);
1178
+ if (rejectionTime) {
1179
+ const unsubscribe = store.on.operationClose.subscribe(`waiting to set "${token.key}" at T-${rejectionTime}`, () => {
1180
+ unsubscribe();
1181
+ store.logger.info(`🟢`, token.type, token.key, `resuming deferred setState from T-${rejectionTime}`);
1182
+ setIntoStore(store, token, value);
1183
+ });
1184
+ return;
1185
+ }
1186
+ const state = withdraw(store, token);
1187
+ setAtomOrSelector(store, state, value);
1188
+ closeOperation(store);
1189
+ }
1190
+
1191
+ //#endregion
1192
+ //#region src/internal/ingest-updates/ingest-atom-update.ts
1193
+ function ingestAtomUpdate(applying, atomUpdate, store) {
1194
+ const { key, newValue, oldValue } = atomUpdate;
1195
+ const value = applying === `newValue` ? newValue : oldValue;
1196
+ const token = {
1197
+ key,
1198
+ type: `atom`
1199
+ };
1200
+ if (atomUpdate.family) Object.assign(token, { family: atomUpdate.family });
1201
+ setIntoStore(store, token, value);
1202
+ }
1203
+
1204
+ //#endregion
1205
+ //#region src/internal/get-trace.ts
1206
+ function getTrace(error) {
1207
+ const { stack } = error;
1208
+ if (stack) return `\n` + stack.split(`\n`)?.slice(1)?.join(`\n`);
1209
+ return ``;
1210
+ }
1211
+
1212
+ //#endregion
1213
+ //#region src/internal/molecule.ts
1214
+ function makeRootMoleculeInStore(key, store = IMPLICIT.STORE) {
1215
+ const molecule = {
1216
+ key,
1217
+ stringKey: stringifyJson(key),
1218
+ dependsOn: `any`
1219
+ };
1220
+ store.molecules.set(stringifyJson(key), molecule);
1221
+ return key;
1222
+ }
1223
+ function allocateIntoStore(store, provenance, key, dependsOn = `any`) {
1224
+ const origin = provenance;
1225
+ const stringKey = stringifyJson(key);
1226
+ const invalidKeys = [];
1227
+ const target = newest(store);
1228
+ if (Array.isArray(origin)) for (const formerClaim of origin) {
1229
+ const claimString = stringifyJson(formerClaim);
1230
+ const claim = target.molecules.get(claimString);
1231
+ if (claim) store.moleculeGraph.set(claimString, stringKey, { source: claimString });
1232
+ else invalidKeys.push(claimString);
1233
+ }
1234
+ else {
1235
+ const claimString = stringifyJson(origin);
1236
+ const claim = target.molecules.get(claimString);
1237
+ if (claim) store.moleculeGraph.set(claimString, stringKey, { source: claimString });
1238
+ else invalidKeys.push(claimString);
1239
+ }
1240
+ if (invalidKeys.length === 0) target.molecules.set(stringKey, {
1241
+ key,
1242
+ stringKey,
1243
+ dependsOn
1244
+ });
1245
+ const creationEvent = {
1246
+ type: `molecule_creation`,
1247
+ key,
1248
+ provenance: origin
1249
+ };
1250
+ const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1251
+ if (isTransaction) target.transactionMeta.update.updates.push(creationEvent);
1252
+ else target.on.moleculeCreation.next(creationEvent);
1253
+ for (const claim of invalidKeys) {
1254
+ const disposal = store.disposalTraces.buffer.find((item) => item?.key === claim);
1255
+ store.logger.error(`❌`, `molecule`, key, `allocation failed:`, `Could not allocate to ${claim} in store "${store.config.name}".`, disposal ? `\n ${claim} was most recently disposed\n${disposal.trace}` : `No previous disposal trace for ${claim} was found.`);
1256
+ }
1257
+ return key;
1258
+ }
1259
+ function fuseWithinStore(store, type, sideA, sideB) {
1260
+ const compoundKey = `T$--${type}==${sideA}++${sideB}`;
1261
+ const above = [sideA, sideB];
1262
+ allocateIntoStore(store, above, compoundKey, `all`);
1263
+ return compoundKey;
1264
+ }
1265
+ function deallocateFromStore(store, claim) {
1266
+ const stringKey = stringifyJson(claim);
1267
+ const molecule = store.molecules.get(stringKey);
1268
+ if (!molecule) {
1269
+ const disposal = store.disposalTraces.buffer.find((item) => item?.key === stringKey);
1270
+ store.logger.error(`❌`, `molecule`, claim, `deallocation failed:`, `Could not find allocation for ${stringKey} in store "${store.config.name}".`, disposal ? `\n This state was most recently deallocated\n${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`);
1271
+ return;
1272
+ }
1273
+ const joinKeys = store.moleculeJoins.getRelatedKeys(molecule.key);
1274
+ if (joinKeys) for (const joinKey of joinKeys) {
1275
+ const join$1 = store.joins.get(joinKey);
1276
+ if (join$1) {
1277
+ join$1.relations.delete(molecule.key);
1278
+ join$1.molecules.delete(molecule.stringKey);
1279
+ }
1280
+ }
1281
+ store.moleculeJoins.delete(molecule.stringKey);
1282
+ const provenance = [];
1283
+ const values = [];
1284
+ const disposalEvent = {
1285
+ type: `molecule_disposal`,
1286
+ key: molecule.key,
1287
+ values,
1288
+ provenance
1289
+ };
1290
+ const target = newest(store);
1291
+ target.molecules.delete(stringKey);
1292
+ const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1293
+ if (isTransaction) target.transactionMeta.update.updates.push(disposalEvent);
1294
+ const relatedMolecules = store.moleculeGraph.getRelationEntries({ downstreamMoleculeKey: molecule.stringKey });
1295
+ if (relatedMolecules) for (const [relatedStringKey, { source }] of relatedMolecules) if (source === molecule.stringKey) {
1296
+ const relatedKey = parseJson(relatedStringKey);
1297
+ deallocateFromStore(store, relatedKey);
1298
+ } else provenance.push(source);
1299
+ const familyKeys = target.moleculeData.getRelatedKeys(molecule.stringKey);
1300
+ if (familyKeys) for (const familyKey of familyKeys) {
1301
+ const family = target.families.get(familyKey);
1302
+ const token = findInStore(store, family, molecule.key);
1303
+ values.push([family.key, token]);
1304
+ disposeFromStore(store, token);
1305
+ }
1306
+ target.moleculeGraph.delete(molecule.stringKey);
1307
+ target.moleculeJoins.delete(molecule.stringKey);
1308
+ target.moleculeData.delete(molecule.stringKey);
1309
+ if (!isTransaction) target.on.moleculeDisposal.next(disposalEvent);
1310
+ target.molecules.delete(molecule.stringKey);
1311
+ const trace = getTrace(new Error());
1312
+ store.disposalTraces.add({
1313
+ key: stringKey,
1314
+ trace
1315
+ });
1316
+ }
1317
+ function claimWithinStore(store, newProvenance, claim, exclusive) {
1318
+ const stringKey = stringifyJson(claim);
1319
+ const target = newest(store);
1320
+ const molecule = target.molecules.get(stringKey);
1321
+ if (!molecule) {
1322
+ const disposal = store.disposalTraces.buffer.find((item) => item?.key === stringKey);
1323
+ store.logger.error(`❌`, `molecule`, claim, `claim failed:`, `Could not allocate to ${stringKey} in store "${store.config.name}".`, disposal ? `\n ${stringKey} was most recently disposed\n${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`);
1324
+ return claim;
1325
+ }
1326
+ const newProvenanceKey = stringifyJson(newProvenance);
1327
+ const newProvenanceMolecule = target.molecules.get(newProvenanceKey);
1328
+ if (!newProvenanceMolecule) {
1329
+ const disposal = store.disposalTraces.buffer.find((item) => item?.key === newProvenanceKey);
1330
+ store.logger.error(`❌`, `molecule`, claim, `claim failed:`, `Could not allocate to ${newProvenanceKey} in store "${store.config.name}".`, disposal ? `\n ${newProvenanceKey} was most recently disposed\n${disposal.trace}` : `No previous disposal trace for ${newProvenanceKey} was found.`);
1331
+ return claim;
1332
+ }
1333
+ const priorProvenance = store.moleculeGraph.getRelationEntries({ downstreamMoleculeKey: molecule.stringKey }).filter(([, { source }]) => source !== stringKey).map(([key]) => parseJson(key));
1334
+ if (exclusive) target.moleculeGraph.delete(stringKey);
1335
+ target.moleculeGraph.set({
1336
+ upstreamMoleculeKey: newProvenanceMolecule.stringKey,
1337
+ downstreamMoleculeKey: molecule.stringKey
1338
+ }, { source: newProvenanceMolecule.stringKey });
1339
+ const transferEvent = {
1340
+ type: `molecule_transfer`,
1341
+ key: molecule.key,
1342
+ from: priorProvenance,
1343
+ to: [newProvenanceMolecule.key]
1344
+ };
1345
+ const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1346
+ if (isTransaction) target.transactionMeta.update.updates.push(transferEvent);
1347
+ return claim;
1348
+ }
1349
+
1350
+ //#endregion
1351
+ //#region src/internal/ingest-updates/ingest-creation-disposal.ts
1352
+ function ingestCreationEvent(update, applying, store) {
1353
+ switch (applying) {
1354
+ case `newValue`: {
1355
+ createInStore(update, store);
1356
+ break;
1357
+ }
1358
+ case `oldValue`: {
1359
+ disposeFromStore(store, update.token);
1360
+ break;
1361
+ }
1362
+ }
1363
+ }
1364
+ function ingestDisposalEvent(update, applying, store) {
1365
+ switch (applying) {
1366
+ case `newValue`: {
1367
+ disposeFromStore(store, update.token);
1368
+ break;
1369
+ }
1370
+ case `oldValue`: {
1371
+ createInStore(update, store);
1372
+ if (update.subType === `atom`) store.valueMap.set(update.token.key, update.value);
1373
+ break;
1374
+ }
1375
+ }
1376
+ }
1377
+ function createInStore(update, store) {
1378
+ const { family: familyMeta } = update.token;
1379
+ if (familyMeta) {
1380
+ const family = store.families.get(familyMeta.key);
1381
+ if (family) findInStore(store, family, parseJson(familyMeta.subKey));
1382
+ }
1383
+ }
1384
+ function ingestMoleculeCreationEvent(update, applying, store) {
1385
+ switch (applying) {
1386
+ case `newValue`:
1387
+ allocateIntoStore(store, update.provenance, update.key);
1388
+ break;
1389
+ case `oldValue`:
1390
+ deallocateFromStore(store, update.key);
1391
+ break;
1392
+ }
1393
+ }
1394
+ function ingestMoleculeDisposalEvent(update, applying, store) {
1395
+ switch (applying) {
1396
+ case `newValue`:
1397
+ deallocateFromStore(store, update.key);
1398
+ break;
1399
+ case `oldValue`:
1400
+ {
1401
+ const provenanceJson = update.provenance.map(parseJson);
1402
+ allocateIntoStore(store, provenanceJson, update.key);
1403
+ for (const [familyKey, value] of update.values) {
1404
+ const family = store.families.get(familyKey);
1405
+ if (family) {
1406
+ findInStore(store, family, update.key);
1407
+ const memberKey = `${familyKey}(${stringifyJson(update.key)})`;
1408
+ store.valueMap.set(memberKey, value);
1409
+ }
1410
+ }
1411
+ }
1412
+ break;
1413
+ }
1414
+ }
1415
+ function ingestMoleculeTransferEvent(update, applying, store) {
1416
+ switch (applying) {
1417
+ case `newValue`:
1418
+ {
1419
+ const provenance = update.to.length === 1 ? update.to[0] : update.to;
1420
+ claimWithinStore(store, provenance, update.key, `exclusive`);
1421
+ }
1422
+ break;
1423
+ case `oldValue`:
1424
+ {
1425
+ const provenance = update.from.length === 1 ? update.from[0] : update.from;
1426
+ claimWithinStore(store, provenance, update.key, `exclusive`);
1427
+ }
1428
+ break;
1429
+ }
1430
+ }
1431
+
1432
+ //#endregion
1433
+ //#region src/internal/ingest-updates/ingest-selector-update.ts
1434
+ function ingestSelectorUpdate(applying, selectorUpdate, store) {
1435
+ const updates = applying === `newValue` ? selectorUpdate.atomUpdates : selectorUpdate.atomUpdates.toReversed();
1436
+ for (const atomUpdate of updates) ingestAtomUpdate(applying, atomUpdate, store);
1437
+ }
1438
+
1439
+ //#endregion
1440
+ //#region src/internal/ingest-updates/ingest-transaction-update.ts
1441
+ function ingestTransactionUpdate(applying, transactionUpdate, store) {
1442
+ const updates = applying === `newValue` ? transactionUpdate.updates : [...transactionUpdate.updates].reverse();
1443
+ for (const updateFromTransaction of updates) switch (updateFromTransaction.type) {
1444
+ case `atom_update`:
1445
+ case `selector_update`:
1446
+ ingestAtomUpdate(applying, updateFromTransaction, store);
1447
+ break;
1448
+ case `state_creation`:
1449
+ ingestCreationEvent(updateFromTransaction, applying, store);
1450
+ break;
1451
+ case `state_disposal`:
1452
+ ingestDisposalEvent(updateFromTransaction, applying, store);
1453
+ break;
1454
+ case `molecule_creation`:
1455
+ ingestMoleculeCreationEvent(updateFromTransaction, applying, store);
1456
+ break;
1457
+ case `molecule_disposal`:
1458
+ ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
1459
+ break;
1460
+ case `molecule_transfer`:
1461
+ ingestMoleculeTransferEvent(updateFromTransaction, applying, store);
1462
+ break;
1463
+ case `transaction_update`:
1464
+ ingestTransactionUpdate(applying, updateFromTransaction, store);
1465
+ break;
1466
+ }
1467
+ }
1468
+
1469
+ //#endregion
1470
+ //#region src/internal/transaction/get-epoch-number.ts
1471
+ function getContinuityKey(store, transactionKey) {
1472
+ const continuity = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
1473
+ return continuity;
1474
+ }
1475
+ function getEpochNumberOfContinuity(store, continuityKey) {
1476
+ const epoch = store.transactionMeta.epoch.get(continuityKey);
1477
+ return epoch;
1478
+ }
1479
+ function getEpochNumberOfAction(store, transactionKey) {
1480
+ const isRoot = isRootStore(store);
1481
+ if (!isRoot) return void 0;
1482
+ const continuityKey = getContinuityKey(store, transactionKey);
1483
+ if (continuityKey === void 0) return void 0;
1484
+ return getEpochNumberOfContinuity(store, continuityKey);
1485
+ }
1486
+
1487
+ //#endregion
1488
+ //#region src/internal/transaction/set-epoch-number.ts
1489
+ function setEpochNumberOfContinuity(store, continuityKey, newEpoch) {
1490
+ const isRoot = isRootStore(store);
1491
+ if (isRoot && continuityKey) store.transactionMeta.epoch.set(continuityKey, newEpoch);
1492
+ }
1493
+ function setEpochNumberOfAction(store, transactionKey, newEpoch) {
1494
+ const isRoot = isRootStore(store);
1495
+ if (!isRoot) return;
1496
+ const continuityKey = getContinuityKey(store, transactionKey);
1497
+ if (continuityKey !== void 0) store.transactionMeta.epoch.set(continuityKey, newEpoch);
1498
+ }
1499
+
1500
+ //#endregion
1501
+ //#region src/internal/transaction/apply-transaction.ts
1502
+ const applyTransaction = (output, store) => {
1503
+ const child = newest(store);
1504
+ const { parent } = child;
1505
+ if (parent === null || !isChildStore(child) || child.transactionMeta?.phase !== `building`) {
1506
+ store.logger.warn(`🐞`, `transaction`, `???`, `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`);
1507
+ return;
1508
+ }
1509
+ child.transactionMeta.phase = `applying`;
1510
+ child.transactionMeta.update.output = output;
1511
+ parent.child = null;
1512
+ parent.on.transactionApplying.next(child.transactionMeta);
1513
+ const { updates } = child.transactionMeta.update;
1514
+ store.logger.info(`🛄`, `transaction`, child.transactionMeta.update.key, `Applying transaction with ${updates.length} updates:`, updates);
1515
+ ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
1516
+ if (isRootStore(parent)) {
1517
+ setEpochNumberOfAction(parent, child.transactionMeta.update.key, child.transactionMeta.update.epoch);
1518
+ const myTransaction = withdraw(store, {
1519
+ key: child.transactionMeta.update.key,
1520
+ type: `transaction`
1521
+ });
1522
+ myTransaction?.subject.next(child.transactionMeta.update);
1523
+ store.logger.info(`🛬`, `transaction`, child.transactionMeta.update.key, `Finished applying transaction.`);
1524
+ } else if (isChildStore(parent)) parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1525
+ parent.on.transactionApplying.next(null);
1526
+ };
1527
+
1528
+ //#endregion
1529
+ //#region src/internal/transaction/assign-transaction-to-continuity.ts
1530
+ function assignTransactionToContinuity(store, continuityKey, transactionKey) {
1531
+ const isRoot = isRootStore(store);
1532
+ if (!isRoot) return;
1533
+ const { epoch, actionContinuities } = store.transactionMeta;
1534
+ actionContinuities.set(continuityKey, transactionKey);
1535
+ if (!epoch.has(continuityKey)) epoch.set(continuityKey, -1);
1536
+ }
1537
+
1538
+ //#endregion
1539
+ //#region src/internal/get-environment-data.ts
1540
+ function getEnvironmentData(store) {
1541
+ return { store };
1542
+ }
1543
+
1544
+ //#endregion
1545
+ //#region src/internal/get-state/get-from-store.ts
1546
+ function getFromStore(store, ...params) {
1547
+ let token;
1548
+ let family;
1549
+ let key;
1550
+ if (params.length === 1) token = params[0];
1551
+ else {
1552
+ family = params[0];
1553
+ key = params[1];
1554
+ token = findInStore(store, family, key);
1555
+ }
1556
+ if (`counterfeit` in token && `family` in token) {
1557
+ family = store.families.get(token.family.key);
1558
+ const subKey = token.family.subKey;
1559
+ const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
1560
+ store.logger.error(`❌`, token.type, token.key, `could not be retrieved because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
1561
+ switch (family.type) {
1562
+ case `atom_family`:
1563
+ case `mutable_atom_family`: return store.defaults.get(family.key);
1564
+ case `selector_family`:
1565
+ case `readonly_selector_family`: {
1566
+ if (store.defaults.has(family.key)) return store.defaults.get(token.family.key);
1567
+ const defaultValue = withdraw(store, family).default(subKey);
1568
+ store.defaults.set(family.key, defaultValue);
1569
+ return defaultValue;
1570
+ }
1571
+ }
1572
+ }
1573
+ return readOrComputeValue(store, withdraw(store, token));
1574
+ }
1575
+
1576
+ //#endregion
1577
+ //#region src/internal/lazy-map.ts
1578
+ var LazyMap = class extends Map {
1579
+ deleted = new Set();
1580
+ source;
1581
+ constructor(source) {
1582
+ super();
1583
+ this.source = source;
1584
+ }
1585
+ get(key) {
1586
+ const has = super.has(key);
1587
+ if (has) return super.get(key);
1588
+ if (!this.deleted.has(key) && this.source.has(key)) {
1589
+ const value = this.source.get(key);
1590
+ return value;
1591
+ }
1592
+ return void 0;
1593
+ }
1594
+ set(key, value) {
1595
+ this.deleted.delete(key);
1596
+ return super.set(key, value);
1597
+ }
1598
+ hasOwn(key) {
1599
+ return super.has(key);
1600
+ }
1601
+ has(key) {
1602
+ return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
1603
+ }
1604
+ delete(key) {
1605
+ this.deleted.add(key);
1606
+ return super.delete(key);
1607
+ }
1608
+ };
1609
+
1610
+ //#endregion
1611
+ //#region src/internal/transaction/build-transaction.ts
1612
+ const buildTransaction = (store, key, params, id) => {
1613
+ const parent = newest(store);
1614
+ const childBase = {
1615
+ parent,
1616
+ child: null,
1617
+ on: parent.on,
1618
+ loggers: parent.loggers,
1619
+ logger: parent.logger,
1620
+ config: parent.config,
1621
+ atoms: new LazyMap(parent.atoms),
1622
+ atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
1623
+ families: new LazyMap(parent.families),
1624
+ joins: new LazyMap(parent.joins),
1625
+ operation: { open: false },
1626
+ readonlySelectors: new LazyMap(parent.readonlySelectors),
1627
+ timelines: new LazyMap(parent.timelines),
1628
+ timelineTopics: new Junction(parent.timelineTopics.toJSON()),
1629
+ trackers: new Map(),
1630
+ transactions: new LazyMap(parent.transactions),
1631
+ selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
1632
+ selectorGraph: new Junction(parent.selectorGraph.toJSON(), { makeContentKey: (...keys) => keys.sort().join(`:`) }),
1633
+ selectors: new LazyMap(parent.selectors),
1634
+ valueMap: new LazyMap(parent.valueMap),
1635
+ defaults: parent.defaults,
1636
+ disposalTraces: store.disposalTraces.copy(),
1637
+ molecules: new LazyMap(parent.molecules),
1638
+ moleculeGraph: new Junction(parent.moleculeGraph.toJSON(), { makeContentKey: parent.moleculeGraph.makeContentKey }),
1639
+ moleculeData: new Junction(parent.moleculeData.toJSON(), { makeContentKey: parent.moleculeData.makeContentKey }),
1640
+ moleculeJoins: new Junction(parent.moleculeJoins.toJSON(), { makeContentKey: parent.moleculeJoins.makeContentKey }),
1641
+ miscResources: new LazyMap(parent.miscResources)
1642
+ };
1643
+ const epoch = getEpochNumberOfAction(store, key);
1644
+ const transactionMeta = {
1645
+ phase: `building`,
1646
+ update: {
1647
+ type: `transaction_update`,
1648
+ key,
1649
+ id,
1650
+ epoch: epoch === void 0 ? Number.NaN : epoch + 1,
1651
+ updates: [],
1652
+ params,
1653
+ output: void 0
1654
+ },
1655
+ toolkit: {
1656
+ get: (...ps) => getFromStore(child, ...ps),
1657
+ set: (...ps) => {
1658
+ setIntoStore(child, ...ps);
1659
+ },
1660
+ run: (token, identifier = arbitrary()) => actUponStore(child, token, identifier),
1661
+ find: (...ps) => findInStore(store, ...ps),
1662
+ json: (token) => getJsonToken(child, token),
1663
+ dispose: (...ps) => {
1664
+ disposeFromStore(child, ...ps);
1665
+ },
1666
+ env: () => getEnvironmentData(child)
1667
+ }
1668
+ };
1669
+ const child = Object.assign(childBase, { transactionMeta });
1670
+ parent.child = child;
1671
+ store.logger.info(`🛫`, `transaction`, key, `Building transaction with params:`, params);
1672
+ return child;
1673
+ };
1674
+
1675
+ //#endregion
1676
+ //#region src/internal/transaction/create-transaction.ts
1677
+ function createTransaction(store, options) {
1678
+ const newTransaction = {
1679
+ key: options.key,
1680
+ type: `transaction`,
1681
+ run: (params, id) => {
1682
+ const childStore = buildTransaction(store, options.key, params, id);
1683
+ try {
1684
+ const target$1 = newest(store);
1685
+ const { toolkit } = childStore.transactionMeta;
1686
+ const output = options.do(toolkit, ...params);
1687
+ applyTransaction(output, target$1);
1688
+ return output;
1689
+ } catch (thrown) {
1690
+ abortTransaction(target);
1691
+ store.logger.warn(`💥`, `transaction`, options.key, `caught:`, thrown);
1692
+ throw thrown;
1693
+ }
1694
+ },
1695
+ install: (s) => createTransaction(s, options),
1696
+ subject: new Subject()
1697
+ };
1698
+ const target = newest(store);
1699
+ target.transactions.set(newTransaction.key, newTransaction);
1700
+ const token = deposit(newTransaction);
1701
+ store.on.transactionCreation.next(token);
1702
+ return token;
1703
+ }
1704
+
1705
+ //#endregion
1706
+ //#region src/internal/transaction/index.ts
1707
+ const TRANSACTION_PHASES = [
1708
+ `idle`,
1709
+ `building`,
1710
+ `applying`
1711
+ ];
1712
+
1713
+ //#endregion
1714
+ //#region src/internal/store/store.ts
1715
+ var Store = class {
1716
+ parent = null;
1717
+ child = null;
1718
+ valueMap = new Map();
1719
+ defaults = new Map();
1720
+ atoms = new Map();
1721
+ selectors = new Map();
1722
+ readonlySelectors = new Map();
1723
+ atomsThatAreDefault = new Set();
1724
+ selectorAtoms = new Junction({
1725
+ between: [`selectorKey`, `atomKey`],
1726
+ cardinality: `n:n`
1727
+ });
1728
+ selectorGraph = new Junction({
1729
+ between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
1730
+ cardinality: `n:n`
1731
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
1732
+ trackers = new Map();
1733
+ families = new Map();
1734
+ joins = new Map();
1735
+ transactions = new Map();
1736
+ transactionMeta = {
1737
+ epoch: new Map(),
1738
+ actionContinuities: new Junction({
1739
+ between: [`continuity`, `action`],
1740
+ cardinality: `1:n`
1741
+ })
1742
+ };
1743
+ timelines = new Map();
1744
+ timelineTopics = new Junction({
1745
+ between: [`timelineKey`, `topicKey`],
1746
+ cardinality: `1:n`
1747
+ });
1748
+ disposalTraces = new CircularBuffer(100);
1749
+ molecules = new Map();
1750
+ moleculeJoins = new Junction({
1751
+ between: [`moleculeKey`, `joinKey`],
1752
+ cardinality: `n:n`
1753
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
1754
+ moleculeGraph = new Junction({
1755
+ between: [`upstreamMoleculeKey`, `downstreamMoleculeKey`],
1756
+ cardinality: `n:n`
1757
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
1758
+ moleculeData = new Junction({
1759
+ between: [`moleculeKey`, `stateFamilyKey`],
1760
+ cardinality: `n:n`
1761
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
1762
+ miscResources = new Map();
1763
+ on = {
1764
+ atomCreation: new Subject(),
1765
+ atomDisposal: new Subject(),
1766
+ selectorCreation: new Subject(),
1767
+ selectorDisposal: new Subject(),
1768
+ timelineCreation: new Subject(),
1769
+ transactionCreation: new Subject(),
1770
+ transactionApplying: new StatefulSubject(null),
1771
+ operationClose: new Subject(),
1772
+ moleculeCreation: new Subject(),
1773
+ moleculeDisposal: new Subject()
1774
+ };
1775
+ operation = { open: false };
1776
+ config = {
1777
+ name: `IMPLICIT_STORE`,
1778
+ lifespan: `ephemeral`
1779
+ };
1780
+ loggers = [new AtomIOLogger(`warn`, (_, __, key) => !isReservedIntrospectionKey(key))];
1781
+ logger = {
1782
+ error: (...messages) => {
1783
+ for (const logger of this.loggers) logger.error(...messages);
1784
+ },
1785
+ info: (...messages) => {
1786
+ for (const logger of this.loggers) logger.info(...messages);
1787
+ },
1788
+ warn: (...messages) => {
1789
+ for (const logger of this.loggers) logger.warn(...messages);
1790
+ }
1791
+ };
1792
+ constructor(config, store = null) {
1793
+ this.config = {
1794
+ ...store?.config,
1795
+ ...config
1796
+ };
1797
+ if (store !== null) {
1798
+ this.valueMap = new Map(store?.valueMap);
1799
+ this.operation = { ...store?.operation };
1800
+ if (isRootStore(store)) this.transactionMeta = {
1801
+ epoch: new Map(store?.transactionMeta.epoch),
1802
+ actionContinuities: new Junction(store?.transactionMeta.actionContinuities.toJSON())
1803
+ };
1804
+ for (const [, family] of store.families) {
1805
+ if (family.internalRoles?.includes(`mutable`) || family.internalRoles?.includes(`join`)) continue;
1806
+ family.install(this);
1807
+ }
1808
+ const mutableHelpers = new Set();
1809
+ for (const [, atom$1] of store.atoms) {
1810
+ if (mutableHelpers.has(atom$1.key)) continue;
1811
+ atom$1.install(this);
1812
+ if (atom$1.type === `mutable_atom`) {
1813
+ const originalJsonToken = getJsonToken(store, atom$1);
1814
+ const originalUpdateToken = getUpdateToken(atom$1);
1815
+ mutableHelpers.add(originalJsonToken.key);
1816
+ mutableHelpers.add(originalUpdateToken.key);
1817
+ }
1818
+ }
1819
+ for (const [, selector] of store.readonlySelectors) selector.install(this);
1820
+ for (const [, selector] of store.selectors) {
1821
+ if (mutableHelpers.has(selector.key)) continue;
1822
+ selector.install(this);
1823
+ }
1824
+ for (const [, tx] of store.transactions) tx.install(this);
1825
+ for (const [, timeline] of store.timelines) timeline.install(this);
1826
+ }
1827
+ }
1828
+ };
1829
+ const IMPLICIT = { get STORE() {
1830
+ globalThis.ATOM_IO_IMPLICIT_STORE ??= new Store({
1831
+ name: `IMPLICIT_STORE`,
1832
+ lifespan: `ephemeral`
1833
+ });
1834
+ return globalThis.ATOM_IO_IMPLICIT_STORE;
1835
+ } };
1836
+ const clearStore = (store) => {
1837
+ const { config } = store;
1838
+ for (const disposable of store.miscResources.values()) disposable[Symbol.dispose]();
1839
+ Object.assign(store, new Store(config));
1840
+ store.config = config;
1841
+ };
1842
+
1843
+ //#endregion
1844
+ //#region src/internal/store/withdraw.ts
1845
+ function withdraw(store, token) {
1846
+ let withdrawn;
1847
+ let target = store;
1848
+ while (target !== null) {
1849
+ switch (token.type) {
1850
+ case `atom`:
1851
+ case `mutable_atom`:
1852
+ withdrawn = target.atoms.get(token.key);
1853
+ break;
1854
+ case `selector`:
1855
+ withdrawn = target.selectors.get(token.key);
1856
+ break;
1857
+ case `readonly_selector`:
1858
+ withdrawn = target.readonlySelectors.get(token.key);
1859
+ break;
1860
+ case `atom_family`:
1861
+ case `mutable_atom_family`:
1862
+ case `selector_family`:
1863
+ case `readonly_selector_family`:
1864
+ withdrawn = target.families.get(token.key);
1865
+ break;
1866
+ case `timeline`:
1867
+ withdrawn = target.timelines.get(token.key);
1868
+ break;
1869
+ case `transaction`:
1870
+ withdrawn = target.transactions.get(token.key);
1871
+ break;
1872
+ }
1873
+ if (withdrawn) return withdrawn;
1874
+ target = target.child;
1875
+ }
1876
+ throw new NotFoundError(token, store);
1877
+ }
1878
+
1879
+ //#endregion
1880
+ //#region src/internal/subscribe/recall-state.ts
1881
+ const recallState = (store, state) => {
1882
+ const target = newest(store);
1883
+ if (target.operation.open) return target.operation.prev.get(state.key);
1884
+ return target.valueMap.get(state.key);
1885
+ };
1886
+
1887
+ //#endregion
1888
+ //#region src/internal/subscribe/subscribe-in-store.ts
1889
+ function subscribeInStore(store, token, handleUpdate, key = arbitrary$1()) {
1890
+ switch (token.type) {
1891
+ case `atom`:
1892
+ case `mutable_atom`:
1893
+ case `readonly_selector`:
1894
+ case `selector`: return subscribeToState$1(store, token, key, handleUpdate);
1895
+ case `transaction`: return subscribeToTransaction$1(store, token, key, handleUpdate);
1896
+ case `timeline`: return subscribeToTimeline$1(store, token, key, handleUpdate);
1897
+ }
1898
+ }
1899
+
1900
+ //#endregion
1901
+ //#region src/internal/subscribe/subscribe-to-root-atoms.ts
1902
+ const subscribeToRootAtoms = (store, selector) => {
1903
+ const target = newest(store);
1904
+ const dependencySubscriptions = traceAllSelectorAtoms(selector, store).map((atomKey) => {
1905
+ const atom$1 = target.atoms.get(atomKey);
1906
+ if (atom$1 === void 0) throw new Error(`Atom "${atomKey}", a dependency of selector "${selector.key}", not found in store "${store.config.name}".`);
1907
+ return atom$1.subject.subscribe(`${selector.type}:${selector.key}`, (atomChange) => {
1908
+ store.logger.info(`📢`, selector.type, selector.key, `root`, atomKey, `went`, atomChange.oldValue, `->`, atomChange.newValue);
1909
+ const oldValue = recallState(target, selector);
1910
+ const newValue = readOrComputeValue(target, selector);
1911
+ store.logger.info(`✨`, selector.type, selector.key, `went`, oldValue, `->`, newValue);
1912
+ selector.subject.next({
1913
+ newValue,
1914
+ oldValue
1915
+ });
1916
+ });
1917
+ });
1918
+ return dependencySubscriptions;
1919
+ };
1920
+
1921
+ //#endregion
1922
+ //#region src/internal/subscribe/subscribe-to-state.ts
1923
+ function subscribeToState(store, token, key, handleUpdate) {
1924
+ function safelyHandleUpdate(update) {
1925
+ if (store.operation.open) {
1926
+ const unsubscribe$1 = store.on.operationClose.subscribe(`state subscription ${key}`, () => {
1927
+ unsubscribe$1();
1928
+ handleUpdate(update);
1929
+ });
1930
+ } else handleUpdate(update);
1931
+ }
1932
+ const state = withdraw(store, token);
1933
+ store.logger.info(`👀`, state.type, state.key, `Adding subscription "${key}"`);
1934
+ const isSelector = state.type === `selector` || state.type === `readonly_selector`;
1935
+ let dependencyUnsubFunctions = null;
1936
+ let updateHandler = safelyHandleUpdate;
1937
+ if (isSelector) {
1938
+ dependencyUnsubFunctions = subscribeToRootAtoms(store, state);
1939
+ updateHandler = (update) => {
1940
+ if (dependencyUnsubFunctions) {
1941
+ dependencyUnsubFunctions.length = 0;
1942
+ dependencyUnsubFunctions.push(...subscribeToRootAtoms(store, state));
1943
+ }
1944
+ safelyHandleUpdate(update);
1945
+ };
1946
+ }
1947
+ const mainUnsubFunction = state.subject.subscribe(key, updateHandler);
1948
+ const unsubscribe = () => {
1949
+ store.logger.info(`🙈`, state.type, state.key, `Removing subscription "${key}"`);
1950
+ mainUnsubFunction();
1951
+ if (dependencyUnsubFunctions) for (const unsubFromDependency of dependencyUnsubFunctions) unsubFromDependency();
1952
+ };
1953
+ return unsubscribe;
1954
+ }
1955
+
1956
+ //#endregion
1957
+ //#region src/internal/subscribe/subscribe-to-timeline.ts
1958
+ const subscribeToTimeline = (store, token, key, handleUpdate) => {
1959
+ const tl = withdraw(store, token);
1960
+ store.logger.info(`👀`, `timeline`, token.key, `Adding subscription "${key}"`);
1961
+ const unsubscribe = tl.subject.subscribe(key, handleUpdate);
1962
+ return () => {
1963
+ store.logger.info(`🙈`, `timeline`, token.key, `Removing subscription "${key}" from timeline`);
1964
+ unsubscribe();
1965
+ };
1966
+ };
1967
+
1968
+ //#endregion
1969
+ //#region src/internal/subscribe/subscribe-to-transaction.ts
1970
+ const subscribeToTransaction = (store, token, key, handleUpdate) => {
1971
+ const tx = withdraw(store, token);
1972
+ store.logger.info(`👀`, `transaction`, token.key, `Adding subscription "${key}"`);
1973
+ const unsubscribe = tx.subject.subscribe(key, handleUpdate);
1974
+ return () => {
1975
+ store.logger.info(`🙈`, `transaction`, token.key, `Removing subscription "${key}"`);
1976
+ unsubscribe();
1977
+ };
1978
+ };
1979
+
1980
+ //#endregion
1981
+ //#region src/internal/mutable/tracker.ts
1982
+ /**
1983
+ * @internal Give the tracker a transceiver state and a store, and it will
1984
+ * subscribe to the transceiver's inner value. When the inner value changes,
1985
+ * the tracker will update its own state to reflect the change.
1986
+ */
1987
+ var Tracker = class {
1988
+ initializeState(mutableState, store) {
1989
+ const latestUpdateStateKey = `*${mutableState.key}`;
1990
+ store.atoms.delete(latestUpdateStateKey);
1991
+ store.valueMap.delete(latestUpdateStateKey);
1992
+ const familyMetaData = mutableState.family ? {
1993
+ key: `*${mutableState.family.key}`,
1994
+ subKey: mutableState.family.subKey
1995
+ } : void 0;
1996
+ const latestUpdateState = createRegularAtom(store, {
1997
+ key: latestUpdateStateKey,
1998
+ default: null
1999
+ }, familyMetaData);
2000
+ if (store.parent?.valueMap.has(latestUpdateStateKey)) {
2001
+ const parentValue = store.parent.valueMap.get(latestUpdateStateKey);
2002
+ store.valueMap.set(latestUpdateStateKey, parentValue);
2003
+ }
2004
+ return latestUpdateState;
2005
+ }
2006
+ unsubscribeFromInnerValue;
2007
+ unsubscribeFromState;
2008
+ observeCore(mutableState, latestUpdateState, target) {
2009
+ const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
2010
+ const originalInnerValue = getFromStore(target, mutableState);
2011
+ this.unsubscribeFromInnerValue = originalInnerValue.subscribe(subscriptionKey, (update) => {
2012
+ setIntoStore(target, latestUpdateState, update);
2013
+ });
2014
+ this.unsubscribeFromState = subscribeToState(target, mutableState, subscriptionKey, (update) => {
2015
+ if (update.newValue !== update.oldValue) {
2016
+ this.unsubscribeFromInnerValue();
2017
+ this.unsubscribeFromInnerValue = update.newValue.subscribe(subscriptionKey, (transceiverUpdate) => {
2018
+ setIntoStore(target, latestUpdateState, transceiverUpdate);
2019
+ });
2020
+ }
2021
+ });
2022
+ }
2023
+ updateCore(mutableState, latestUpdateState, target) {
2024
+ const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
2025
+ subscribeToState(target, latestUpdateState, subscriptionKey, ({ newValue, oldValue }) => {
2026
+ const timelineId = target.timelineTopics.getRelatedKey(latestUpdateState.key);
2027
+ if (timelineId) {
2028
+ const timelineData = target.timelines.get(timelineId);
2029
+ if (timelineData?.timeTraveling) {
2030
+ const unsubscribe$1 = subscribeToTimeline(target, {
2031
+ key: timelineId,
2032
+ type: `timeline`
2033
+ }, subscriptionKey, (update) => {
2034
+ unsubscribe$1();
2035
+ setIntoStore(target, mutableState, (transceiver) => {
2036
+ if (update === `redo` && newValue) transceiver.do(newValue);
2037
+ else if (update === `undo` && oldValue) transceiver.undo(oldValue);
2038
+ return transceiver;
2039
+ });
2040
+ });
2041
+ return;
2042
+ }
2043
+ }
2044
+ const unsubscribe = target.on.operationClose.subscribe(subscriptionKey, () => {
2045
+ unsubscribe();
2046
+ const mutable = getFromStore(target, mutableState);
2047
+ const updateNumber = newValue === null ? -1 : mutable.getUpdateNumber(newValue);
2048
+ const eventOffset = updateNumber - mutable.cacheUpdateNumber;
2049
+ if (newValue && eventOffset === 1) setIntoStore(target, mutableState, (transceiver) => (transceiver.do(newValue), transceiver));
2050
+ else target.logger.info(`❌`, `mutable_atom`, mutableState.key, `could not be updated. Expected update number ${mutable.cacheUpdateNumber + 1}, but got ${updateNumber}`);
2051
+ });
2052
+ });
2053
+ }
2054
+ mutableState;
2055
+ latestUpdateState;
2056
+ [Symbol.dispose];
2057
+ constructor(mutableState, store) {
2058
+ this.mutableState = mutableState;
2059
+ const target = newest(store);
2060
+ this.latestUpdateState = this.initializeState(mutableState, target);
2061
+ this.observeCore(mutableState, this.latestUpdateState, target);
2062
+ this.updateCore(mutableState, this.latestUpdateState, target);
2063
+ target.trackers.set(mutableState.key, this);
2064
+ this[Symbol.dispose] = () => {
2065
+ this.unsubscribeFromInnerValue();
2066
+ this.unsubscribeFromState();
2067
+ target.trackers.delete(mutableState.key);
2068
+ };
2069
+ }
2070
+ };
2071
+
2072
+ //#endregion
2073
+ //#region src/internal/mutable/create-mutable-atom.ts
2074
+ function createMutableAtom(store, options, family) {
2075
+ store.logger.info(`🔨`, `atom`, options.key, `creating in store "${store.config.name}"`);
2076
+ const target = newest(store);
2077
+ const existing = target.atoms.get(options.key);
2078
+ if (existing && existing.type === `mutable_atom`) {
2079
+ store.logger.error(`❌`, `atom`, options.key, `Tried to create atom, but it already exists in the store.`);
2080
+ return deposit(existing);
2081
+ }
2082
+ const subject = new Subject();
2083
+ const newAtom = {
2084
+ ...options,
2085
+ type: `mutable_atom`,
2086
+ install: (s) => {
2087
+ s.logger.info(`🛠️`, `atom`, options.key, `installing in store "${s.config.name}"`);
2088
+ return createMutableAtom(s, options, family);
2089
+ },
2090
+ subject
2091
+ };
2092
+ if (family) newAtom.family = family;
2093
+ const initialValue = options.default();
2094
+ target.atoms.set(newAtom.key, newAtom);
2095
+ markAtomAsDefault(store, options.key);
2096
+ cacheValue(target, options.key, initialValue, subject);
2097
+ const token = deposit(newAtom);
2098
+ if (options.effects) {
2099
+ let effectIndex = 0;
2100
+ const cleanupFunctions = [];
2101
+ for (const effect of options.effects) {
2102
+ const cleanup = effect({
2103
+ setSelf: (next) => {
2104
+ setIntoStore(store, token, next);
2105
+ },
2106
+ onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
2107
+ });
2108
+ if (cleanup) cleanupFunctions.push(cleanup);
2109
+ ++effectIndex;
2110
+ }
2111
+ newAtom.cleanup = () => {
2112
+ for (const cleanup of cleanupFunctions) cleanup();
2113
+ };
2114
+ }
2115
+ new Tracker(token, store);
2116
+ if (!family) selectJson(token, options, store);
2117
+ return token;
2118
+ }
2119
+
2120
+ //#endregion
2121
+ //#region src/internal/mutable/tracker-family.ts
2122
+ var FamilyTracker = class {
2123
+ trackers = new Map();
2124
+ latestUpdateAtoms;
2125
+ mutableAtoms;
2126
+ constructor(mutableAtoms, store) {
2127
+ const updateAtoms = createRegularAtomFamily(store, {
2128
+ key: `*${mutableAtoms.key}`,
2129
+ default: null
2130
+ }, [`mutable`, `updates`]);
2131
+ this.latestUpdateAtoms = withdraw(store, updateAtoms);
2132
+ this.mutableAtoms = mutableAtoms;
2133
+ this.mutableAtoms.subject.subscribe(`store=${store.config.name}::tracker-atom-family`, (event) => {
2134
+ const { type, token } = event;
2135
+ if (token.family) {
2136
+ const key = parseJson(token.family.subKey);
2137
+ switch (type) {
2138
+ case `state_creation`:
2139
+ this.trackers.set(key, new Tracker(token, store));
2140
+ break;
2141
+ case `state_disposal`:
2142
+ {
2143
+ const tracker = this.trackers.get(key);
2144
+ if (tracker) {
2145
+ tracker[Symbol.dispose]();
2146
+ this.trackers.delete(key);
2147
+ }
2148
+ }
2149
+ break;
2150
+ }
2151
+ }
2152
+ });
2153
+ }
2154
+ };
2155
+
2156
+ //#endregion
2157
+ //#region src/internal/mutable/create-mutable-atom-family.ts
2158
+ function createMutableAtomFamily(store, options, internalRoles) {
2159
+ const familyToken = {
2160
+ key: options.key,
2161
+ type: `mutable_atom_family`
2162
+ };
2163
+ const existing = store.families.get(options.key);
2164
+ if (existing) store.logger.error(`❗`, `mutable_atom_family`, options.key, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
2165
+ const subject = new Subject();
2166
+ const familyFunction = (key) => {
2167
+ const subKey = stringifyJson(key);
2168
+ const family = {
2169
+ key: options.key,
2170
+ subKey
2171
+ };
2172
+ const fullKey = `${options.key}(${subKey})`;
2173
+ const target = newest(store);
2174
+ const individualOptions = {
2175
+ key: fullKey,
2176
+ default: () => options.default(key),
2177
+ toJson: options.toJson,
2178
+ fromJson: options.fromJson,
2179
+ mutable: true
2180
+ };
2181
+ if (options.effects) individualOptions.effects = options.effects(key);
2182
+ const token = createMutableAtom(target, individualOptions, family);
2183
+ subject.next({
2184
+ type: `state_creation`,
2185
+ token
2186
+ });
2187
+ return token;
2188
+ };
2189
+ const atomFamily$1 = Object.assign(familyFunction, familyToken, {
2190
+ subject,
2191
+ install: (s) => createMutableAtomFamily(s, options),
2192
+ toJson: options.toJson,
2193
+ fromJson: options.fromJson,
2194
+ internalRoles
2195
+ });
2196
+ store.families.set(options.key, atomFamily$1);
2197
+ selectJsonFamily(store, atomFamily$1, options);
2198
+ new FamilyTracker(atomFamily$1, store);
2199
+ return familyToken;
2200
+ }
2201
+
2202
+ //#endregion
2203
+ //#region src/internal/mutable/get-json-family.ts
2204
+ const getJsonFamily = (mutableAtomFamily, store) => {
2205
+ const target = newest(store);
2206
+ const key = `${mutableAtomFamily.key}:JSON`;
2207
+ const jsonFamily = target.families.get(key);
2208
+ return jsonFamily;
2209
+ };
2210
+
2211
+ //#endregion
2212
+ //#region src/internal/mutable/get-json-token.ts
2213
+ const getJsonToken = (store, mutableAtomToken) => {
2214
+ if (mutableAtomToken.family) {
2215
+ const target = newest(store);
2216
+ const jsonFamilyKey = `${mutableAtomToken.family.key}:JSON`;
2217
+ const jsonFamilyToken = {
2218
+ key: jsonFamilyKey,
2219
+ type: `selector_family`
2220
+ };
2221
+ const family = withdraw(target, jsonFamilyToken);
2222
+ const subKey = JSON.parse(mutableAtomToken.family.subKey);
2223
+ const jsonToken = findInStore(store, family, subKey);
2224
+ return jsonToken;
2225
+ }
2226
+ const token = {
2227
+ type: `selector`,
2228
+ key: `${mutableAtomToken.key}:JSON`
2229
+ };
2230
+ return token;
2231
+ };
2232
+
2233
+ //#endregion
2234
+ //#region src/internal/mutable/get-update-family.ts
2235
+ const getUpdateFamily = (mutableAtomFamily, store) => {
2236
+ const target = newest(store);
2237
+ const key = `*${mutableAtomFamily.key}`;
2238
+ const updateFamily = target.families.get(key);
2239
+ return updateFamily;
2240
+ };
2241
+
2242
+ //#endregion
2243
+ //#region src/internal/mutable/get-update-token.ts
2244
+ const getUpdateToken = (mutableAtomToken) => {
2245
+ const key = `*${mutableAtomToken.key}`;
2246
+ const updateToken = {
2247
+ type: `atom`,
2248
+ key
2249
+ };
2250
+ if (mutableAtomToken.family) updateToken.family = {
2251
+ key: `*${mutableAtomToken.family.key}`,
2252
+ subKey: mutableAtomToken.family.subKey
2253
+ };
2254
+ return updateToken;
2255
+ };
2256
+
2257
+ //#endregion
2258
+ //#region src/internal/mutable/transceiver.ts
2259
+ function isTransceiver(value) {
2260
+ return typeof value === `object` && value !== null && `do` in value && `undo` in value && `subscribe` in value;
2261
+ }
2262
+
2263
+ //#endregion
2264
+ //#region src/internal/set-state/copy-mutable-if-needed.ts
2265
+ function copyMutableIfNeeded(target, atom$1, origin) {
2266
+ const originValue = origin.valueMap.get(atom$1.key);
2267
+ const targetValue = target.valueMap.get(atom$1.key);
2268
+ if (originValue !== targetValue) return targetValue;
2269
+ if (originValue === void 0) return atom$1.default();
2270
+ origin.logger.info(`📃`, `atom`, atom$1.key, `copying`);
2271
+ const jsonValue = atom$1.toJson(originValue);
2272
+ const copiedValue = atom$1.fromJson(jsonValue);
2273
+ target.valueMap.set(atom$1.key, copiedValue);
2274
+ new Tracker(atom$1, origin);
2275
+ return copiedValue;
2276
+ }
2277
+
2278
+ //#endregion
2279
+ //#region src/internal/caching.ts
2280
+ function cacheValue(target, key, value, subject) {
2281
+ const currentValue = target.valueMap.get(key);
2282
+ if (currentValue instanceof Future) {
2283
+ const future = currentValue;
2284
+ future.use(value);
2285
+ }
2286
+ if (value instanceof Promise) {
2287
+ const future = new Future(value);
2288
+ target.valueMap.set(key, future);
2289
+ future.then((resolved) => {
2290
+ cacheValue(target, key, resolved, subject);
2291
+ subject.next({
2292
+ newValue: resolved,
2293
+ oldValue: future
2294
+ });
2295
+ }).catch((thrown) => {
2296
+ target.logger.error(`💥`, `state`, key, `rejected:`, thrown);
2297
+ });
2298
+ return future;
2299
+ }
2300
+ target.valueMap.set(key, value);
2301
+ return value;
2302
+ }
2303
+ const readCachedValue = (token, target) => {
2304
+ let value = target.valueMap.get(token.key);
2305
+ if (token.type === `mutable_atom` && isChildStore(target)) {
2306
+ const { parent } = target;
2307
+ const copiedValue = copyMutableIfNeeded(target, token, parent);
2308
+ value = copiedValue;
2309
+ }
2310
+ return value;
2311
+ };
2312
+ const evictCachedValue = (key, target) => {
2313
+ const currentValue = target.valueMap.get(key);
2314
+ if (currentValue instanceof Future) {
2315
+ const future = currentValue;
2316
+ const selector = target.selectors.get(key) ?? target.readonlySelectors.get(key);
2317
+ if (selector) future.use(selector.get());
2318
+ return;
2319
+ }
2320
+ if (target.operation.open) target.operation.prev.set(key, currentValue);
2321
+ target.valueMap.delete(key);
2322
+ target.logger.info(`🗑`, `state`, key, `evicted`);
2323
+ };
2324
+
2325
+ //#endregion
2326
+ //#region src/internal/atom/is-default.ts
2327
+ const isAtomDefault = (store, key) => {
2328
+ const core = newest(store);
2329
+ return core.atomsThatAreDefault.has(key);
2330
+ };
2331
+ const markAtomAsDefault = (store, key) => {
2332
+ const core = newest(store);
2333
+ core.atomsThatAreDefault = new Set(core.atomsThatAreDefault).add(key);
2334
+ };
2335
+ const markAtomAsNotDefault = (store, key) => {
2336
+ const core = newest(store);
2337
+ core.atomsThatAreDefault = new Set(newest(store).atomsThatAreDefault);
2338
+ core.atomsThatAreDefault.delete(key);
2339
+ };
2340
+
2341
+ //#endregion
2342
+ //#region src/internal/atom/create-regular-atom.ts
2343
+ function createRegularAtom(store, options, family) {
2344
+ store.logger.info(`🔨`, `atom`, options.key, `creating in store "${store.config.name}"`);
2345
+ const target = newest(store);
2346
+ const existing = target.atoms.get(options.key);
2347
+ if (existing && existing.type === `atom`) {
2348
+ store.logger.error(`❌`, `atom`, options.key, `Tried to create atom, but it already exists in the store.`);
2349
+ return deposit(existing);
2350
+ }
2351
+ const subject = new Subject();
2352
+ const newAtom = {
2353
+ ...options,
2354
+ type: `atom`,
2355
+ install: (s) => {
2356
+ s.logger.info(`🛠️`, `atom`, options.key, `installing in store "${s.config.name}"`);
2357
+ return createRegularAtom(s, options, family);
2358
+ },
2359
+ subject
2360
+ };
2361
+ if (family) newAtom.family = family;
2362
+ let initialValue = options.default;
2363
+ if (options.default instanceof Function) initialValue = options.default();
2364
+ target.atoms.set(newAtom.key, newAtom);
2365
+ markAtomAsDefault(store, options.key);
2366
+ cacheValue(target, options.key, initialValue, subject);
2367
+ const token = deposit(newAtom);
2368
+ if (options.effects) {
2369
+ let effectIndex = 0;
2370
+ const cleanupFunctions = [];
2371
+ for (const effect of options.effects) {
2372
+ const cleanup = effect({
2373
+ setSelf: (next) => {
2374
+ setIntoStore(store, token, next);
2375
+ },
2376
+ onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
2377
+ });
2378
+ if (cleanup) cleanupFunctions.push(cleanup);
2379
+ ++effectIndex;
2380
+ }
2381
+ newAtom.cleanup = () => {
2382
+ for (const cleanup of cleanupFunctions) cleanup();
2383
+ };
2384
+ }
2385
+ return token;
2386
+ }
2387
+
2388
+ //#endregion
2389
+ //#region src/internal/atom/create-standalone-atom.ts
2390
+ function createStandaloneAtom(store, options) {
2391
+ const isMutable = `mutable` in options;
2392
+ if (isMutable) {
2393
+ const state$1 = createMutableAtom(store, options, void 0);
2394
+ store.on.atomCreation.next(state$1);
2395
+ return state$1;
2396
+ }
2397
+ const state = createRegularAtom(store, options, void 0);
2398
+ store.on.atomCreation.next(state);
2399
+ return state;
2400
+ }
2401
+
2402
+ //#endregion
2403
+ //#region src/internal/atom/dispose-atom.ts
2404
+ function disposeAtom(store, atomToken) {
2405
+ const target = newest(store);
2406
+ const { key, family } = atomToken;
2407
+ const atom$1 = withdraw(target, atomToken);
2408
+ if (!family) store.logger.error(`❌`, `atom`, key, `Standalone atoms cannot be disposed.`);
2409
+ else {
2410
+ atom$1.cleanup?.();
2411
+ const lastValue = store.valueMap.get(atom$1.key);
2412
+ const atomFamily$1 = withdraw(store, {
2413
+ key: family.key,
2414
+ type: `atom_family`
2415
+ });
2416
+ const disposal = {
2417
+ type: `state_disposal`,
2418
+ subType: `atom`,
2419
+ token: atomToken,
2420
+ value: lastValue
2421
+ };
2422
+ atomFamily$1.subject.next(disposal);
2423
+ const isChild = isChildStore(target);
2424
+ target.atoms.delete(key);
2425
+ target.valueMap.delete(key);
2426
+ target.selectorAtoms.delete(key);
2427
+ target.atomsThatAreDefault.delete(key);
2428
+ store.timelineTopics.delete(key);
2429
+ if (atomToken.type === `mutable_atom`) {
2430
+ const updateToken = getUpdateToken(atomToken);
2431
+ disposeAtom(store, updateToken);
2432
+ store.trackers.delete(key);
2433
+ }
2434
+ store.logger.info(`🔥`, `atom`, key, `deleted`);
2435
+ if (isChild && target.transactionMeta.phase === `building`) {
2436
+ const mostRecentUpdate = target.transactionMeta.update.updates.at(-1);
2437
+ const wasMoleculeDisposal = mostRecentUpdate?.type === `molecule_disposal`;
2438
+ const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k === atom$1.family?.key);
2439
+ if (!updateAlreadyCaptured) target.transactionMeta.update.updates.push(disposal);
2440
+ } else store.on.atomDisposal.next(atomToken);
2441
+ }
2442
+ }
2443
+
2444
+ //#endregion
2445
+ //#region src/internal/install-into-store.ts
2446
+ /**
2447
+ * @public
2448
+ * Install the given tokens into the target store
2449
+ * @param tokens - States, families, transactions, and timelines to install into the target store
2450
+ * @param target - The store to install the tokens into
2451
+ * @param source - The store to install the tokens from
2452
+ *
2453
+ */
2454
+ function installIntoStore(tokens, target, source) {
2455
+ const sourceNewest = newest(source);
2456
+ if (isChildStore(sourceNewest)) {
2457
+ source.logger.error(`❌`, `transaction`, sourceNewest.transactionMeta.update.key, `could not install the following tokens into store "${target.config.name} from "${source.config.name}":`, tokens, `${sourceNewest.config.name} is undergoing a transaction.`);
2458
+ return;
2459
+ }
2460
+ const targetNewest = newest(target);
2461
+ if (isChildStore(targetNewest)) {
2462
+ target.logger.error(`❌`, `transaction`, targetNewest.transactionMeta.update.key, `could not install the following tokens into store "${target.config.name} from "${source.config.name}":`, tokens, `${targetNewest.config.name} is undergoing a transaction.`);
2463
+ return;
2464
+ }
2465
+ for (const token of tokens) {
2466
+ const resource = withdraw(source, token);
2467
+ resource.install(target);
2468
+ }
2469
+ }
2470
+
2471
+ //#endregion
2472
+ //#region src/internal/join/join-internal.ts
2473
+ var Join = class {
2474
+ toolkit;
2475
+ options;
2476
+ defaultContent;
2477
+ molecules = new Map();
2478
+ relations;
2479
+ states;
2480
+ core;
2481
+ transact(toolkit, run) {
2482
+ const originalToolkit = this.toolkit;
2483
+ this.toolkit = toolkit;
2484
+ run(this);
2485
+ this.toolkit = originalToolkit;
2486
+ }
2487
+ store;
2488
+ realm;
2489
+ [Symbol.dispose]() {}
2490
+ constructor(options, defaultContent, store = IMPLICIT.STORE) {
2491
+ this.store = store;
2492
+ this.realm = new Anarchy(store);
2493
+ this.options = options;
2494
+ this.defaultContent = defaultContent;
2495
+ this.store.miscResources.set(`join:${options.key}`, this);
2496
+ this.realm.allocate(`root`, options.key);
2497
+ this.toolkit = {
2498
+ get: (...ps) => getFromStore(store, ...ps),
2499
+ set: (...ps) => {
2500
+ setIntoStore(store, ...ps);
2501
+ },
2502
+ find: (...ps) => findInStore(store, ...ps),
2503
+ json: (token) => getJsonToken(store, token)
2504
+ };
2505
+ const aSide = options.between[0];
2506
+ const bSide = options.between[1];
2507
+ const relatedKeysAtoms = createMutableAtomFamily(store, {
2508
+ key: `${options.key}/relatedKeys`,
2509
+ default: () => new SetRTX(),
2510
+ mutable: true,
2511
+ fromJson: (json) => SetRTX.fromJSON(json),
2512
+ toJson: (set) => set.toJSON()
2513
+ }, [`join`, `relations`]);
2514
+ this.core = { relatedKeysAtoms };
2515
+ const getRelatedKeys = ({ get }, key) => get(relatedKeysAtoms, key);
2516
+ const addRelation = ({ set }, a, b) => {
2517
+ if (!this.store.molecules.has(stringifyJson(a))) this.realm.allocate(options.key, a);
2518
+ set(relatedKeysAtoms, a, (aKeys) => aKeys.add(b));
2519
+ set(relatedKeysAtoms, b, (bKeys) => bKeys.add(a));
2520
+ };
2521
+ const deleteRelation = ({ set }, a, b) => {
2522
+ set(relatedKeysAtoms, a, (aKeys) => {
2523
+ aKeys.delete(b);
2524
+ return aKeys;
2525
+ });
2526
+ set(relatedKeysAtoms, b, (bKeys) => {
2527
+ bKeys.delete(a);
2528
+ return bKeys;
2529
+ });
2530
+ };
2531
+ const replaceRelationsSafely = (toolkit, a, newRelationsOfA) => {
2532
+ const { find, get, set } = toolkit;
2533
+ const relationsOfAState = find(relatedKeysAtoms, a);
2534
+ const currentRelationsOfA = get(relationsOfAState);
2535
+ for (const currentRelationB of currentRelationsOfA) {
2536
+ const remainsRelated = newRelationsOfA.includes(currentRelationB);
2537
+ if (remainsRelated) continue;
2538
+ set(relatedKeysAtoms, currentRelationB, (relationsOfB) => {
2539
+ relationsOfB.delete(a);
2540
+ return relationsOfB;
2541
+ });
2542
+ }
2543
+ set(relationsOfAState, (relationsOfA) => {
2544
+ relationsOfA.transaction((nextRelationsOfA) => {
2545
+ nextRelationsOfA.clear();
2546
+ for (const newRelationB of newRelationsOfA) {
2547
+ const relationsOfB = getRelatedKeys(toolkit, newRelationB);
2548
+ const newRelationBIsAlreadyRelated = relationsOfB.has(a);
2549
+ if (this.relations.cardinality === `1:n`) {
2550
+ const previousOwnersToDispose = [];
2551
+ for (const previousOwner of relationsOfB) {
2552
+ if (previousOwner === a) continue;
2553
+ const previousOwnerRelations = getRelatedKeys(toolkit, previousOwner);
2554
+ previousOwnerRelations.delete(newRelationB);
2555
+ if (previousOwnerRelations.size === 0) previousOwnersToDispose.push(previousOwner);
2556
+ }
2557
+ if (!newRelationBIsAlreadyRelated && relationsOfB.size > 0) relationsOfB.clear();
2558
+ for (const previousOwner of previousOwnersToDispose) {
2559
+ const sorted = [newRelationB, previousOwner].sort();
2560
+ const compositeKey = `"${sorted[0]}:${sorted[1]}"`;
2561
+ this.molecules.delete(compositeKey);
2562
+ }
2563
+ }
2564
+ if (!newRelationBIsAlreadyRelated) relationsOfB.add(a);
2565
+ nextRelationsOfA.add(newRelationB);
2566
+ }
2567
+ return true;
2568
+ });
2569
+ return relationsOfA;
2570
+ });
2571
+ };
2572
+ const replaceRelationsUnsafely = (toolkit, a, newRelationsOfA) => {
2573
+ const { set } = toolkit;
2574
+ set(relatedKeysAtoms, a, (relationsOfA) => {
2575
+ relationsOfA.transaction((nextRelationsOfA) => {
2576
+ for (const newRelationB of newRelationsOfA) nextRelationsOfA.add(newRelationB);
2577
+ return true;
2578
+ });
2579
+ return relationsOfA;
2580
+ });
2581
+ for (const newRelationB of newRelationsOfA) set(relatedKeysAtoms, newRelationB, (newRelationsB) => {
2582
+ newRelationsB.add(a);
2583
+ return newRelationsB;
2584
+ });
2585
+ return true;
2586
+ };
2587
+ const has = (toolkit, a, b) => {
2588
+ const aKeys = getRelatedKeys(toolkit, a);
2589
+ return b ? aKeys.has(b) : aKeys.size > 0;
2590
+ };
2591
+ const baseExternalStoreConfiguration = {
2592
+ getRelatedKeys: (key) => getRelatedKeys(this.toolkit, key),
2593
+ addRelation: (a, b) => {
2594
+ this.store.moleculeJoins.set(a, options.key);
2595
+ this.store.moleculeJoins.set(b, options.key);
2596
+ addRelation(this.toolkit, a, b);
2597
+ },
2598
+ deleteRelation: (a, b) => {
2599
+ deleteRelation(this.toolkit, a, b);
2600
+ },
2601
+ replaceRelationsSafely: (a, bs) => {
2602
+ replaceRelationsSafely(this.toolkit, a, bs);
2603
+ },
2604
+ replaceRelationsUnsafely: (a, bs) => {
2605
+ replaceRelationsUnsafely(this.toolkit, a, bs);
2606
+ },
2607
+ has: (a, b) => has(this.toolkit, a, b)
2608
+ };
2609
+ let externalStore;
2610
+ let contentAtoms;
2611
+ if (defaultContent) {
2612
+ contentAtoms = createRegularAtomFamily(store, {
2613
+ key: `${options.key}/content`,
2614
+ default: defaultContent
2615
+ }, [`join`, `content`]);
2616
+ const getContent = ({ get }, key) => get(contentAtoms, key);
2617
+ const setContent = ({ set }, key, content) => {
2618
+ set(contentAtoms, key, content);
2619
+ };
2620
+ const externalStoreWithContentConfiguration = {
2621
+ getContent: (contentKey) => {
2622
+ const content = getContent(this.toolkit, contentKey);
2623
+ return content;
2624
+ },
2625
+ setContent: (contentKey, content) => {
2626
+ setContent(this.toolkit, contentKey, content);
2627
+ },
2628
+ deleteContent: (contentKey) => {
2629
+ this.realm.deallocate(contentKey);
2630
+ }
2631
+ };
2632
+ externalStore = Object.assign(baseExternalStoreConfiguration, externalStoreWithContentConfiguration);
2633
+ } else externalStore = baseExternalStoreConfiguration;
2634
+ const relations = new Junction(options, {
2635
+ externalStore,
2636
+ isAType: options.isAType,
2637
+ isBType: options.isBType,
2638
+ makeContentKey: (...args) => {
2639
+ const [a, b] = args;
2640
+ const sorted = args.sort();
2641
+ const compositeKey = `${sorted[0]}:${sorted[1]}`;
2642
+ const aMolecule = store.molecules.get(stringifyJson(a));
2643
+ const bMolecule = store.molecules.get(stringifyJson(b));
2644
+ if (!aMolecule) this.realm.allocate(options.key, a);
2645
+ if (!bMolecule) this.realm.allocate(options.key, b);
2646
+ this.realm.allocate(a, compositeKey, `all`);
2647
+ this.realm.claim(b, compositeKey);
2648
+ this.store.moleculeJoins.set(compositeKey, options.key);
2649
+ return compositeKey;
2650
+ }
2651
+ });
2652
+ const createSingleKeySelectorFamily = () => createReadonlySelectorFamily(store, {
2653
+ key: `${options.key}/singleRelatedKey`,
2654
+ get: (key) => ({ get }) => {
2655
+ const relatedKeys = get(relatedKeysAtoms, key);
2656
+ for (const relatedKey of relatedKeys) return relatedKey;
2657
+ return null;
2658
+ }
2659
+ }, [`join`, `keys`]);
2660
+ const getMultipleKeySelectorFamily = () => {
2661
+ return createReadonlySelectorFamily(store, {
2662
+ key: `${options.key}/multipleRelatedKeys`,
2663
+ get: (key) => ({ get }) => {
2664
+ const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
2665
+ const json = get(jsonFamily, key);
2666
+ return json.members;
2667
+ }
2668
+ }, [`join`, `keys`]);
2669
+ };
2670
+ const createSingleEntrySelectorFamily = () => createReadonlySelectorFamily(store, {
2671
+ key: `${options.key}/singleRelatedEntry`,
2672
+ get: (x) => ({ get }) => {
2673
+ const relatedKeys = get(relatedKeysAtoms, x);
2674
+ for (const y of relatedKeys) {
2675
+ let a = relations.isAType?.(x) ? x : void 0;
2676
+ let b = a === void 0 ? x : void 0;
2677
+ a ??= y;
2678
+ b ??= y;
2679
+ const contentKey = relations.makeContentKey(a, b);
2680
+ const content = get(contentAtoms, contentKey);
2681
+ return [y, content];
2682
+ }
2683
+ return null;
2684
+ }
2685
+ }, [`join`, `entries`]);
2686
+ const getMultipleEntrySelectorFamily = () => createReadonlySelectorFamily(store, {
2687
+ key: `${options.key}/multipleRelatedEntries`,
2688
+ get: (x) => ({ get }) => {
2689
+ const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
2690
+ const json = get(jsonFamily, x);
2691
+ return json.members.map((y) => {
2692
+ let a = relations.isAType?.(x) ? x : void 0;
2693
+ let b = a === void 0 ? x : void 0;
2694
+ a ??= y;
2695
+ b ??= y;
2696
+ const contentKey = relations.makeContentKey(a, b);
2697
+ const content = get(contentAtoms, contentKey);
2698
+ return [y, content];
2699
+ });
2700
+ }
2701
+ }, [`join`, `entries`]);
2702
+ switch (options.cardinality) {
2703
+ case `1:1`: {
2704
+ const singleRelatedKeySelectors = createSingleKeySelectorFamily();
2705
+ const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
2706
+ const stateKeyB = `${bSide}KeyOf${capitalize(aSide)}`;
2707
+ const baseStates = {
2708
+ [stateKeyA]: singleRelatedKeySelectors,
2709
+ [stateKeyB]: singleRelatedKeySelectors
2710
+ };
2711
+ let states;
2712
+ if (defaultContent) {
2713
+ const singleEntrySelectors = createSingleEntrySelectorFamily();
2714
+ const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}`;
2715
+ const entriesStateKeyB = `${bSide}EntryOf${capitalize(aSide)}`;
2716
+ const contentStates = {
2717
+ [entriesStateKeyA]: singleEntrySelectors,
2718
+ [entriesStateKeyB]: singleEntrySelectors
2719
+ };
2720
+ states = Object.assign(baseStates, contentStates);
2721
+ } else states = baseStates;
2722
+ this.relations = relations;
2723
+ this.states = states;
2724
+ break;
2725
+ }
2726
+ case `1:n`: {
2727
+ const singleRelatedKeySelectors = createSingleKeySelectorFamily();
2728
+ const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
2729
+ const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
2730
+ const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
2731
+ const baseStates = {
2732
+ [stateKeyA]: singleRelatedKeySelectors,
2733
+ [stateKeyB]: multipleRelatedKeysSelectors
2734
+ };
2735
+ let states;
2736
+ if (defaultContent) {
2737
+ const singleRelatedEntrySelectors = createSingleEntrySelectorFamily();
2738
+ const multipleRelatedEntriesSelectors = getMultipleEntrySelectorFamily();
2739
+ const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}`;
2740
+ const entriesStateKeyB = `${bSide}EntriesOf${capitalize(aSide)}`;
2741
+ const contentStates = {
2742
+ [entriesStateKeyA]: singleRelatedEntrySelectors,
2743
+ [entriesStateKeyB]: multipleRelatedEntriesSelectors
2744
+ };
2745
+ states = Object.assign(baseStates, contentStates);
2746
+ } else states = baseStates;
2747
+ this.relations = relations;
2748
+ this.states = states;
2749
+ break;
2750
+ }
2751
+ case `n:n`: {
2752
+ const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
2753
+ const stateKeyA = `${aSide}KeysOf${capitalize(bSide)}`;
2754
+ const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
2755
+ const baseStates = {
2756
+ [stateKeyA]: multipleRelatedKeysSelectors,
2757
+ [stateKeyB]: multipleRelatedKeysSelectors
2758
+ };
2759
+ let states;
2760
+ if (defaultContent) {
2761
+ const multipleRelatedEntriesSelectors = getMultipleEntrySelectorFamily();
2762
+ const entriesStateKeyA = `${aSide}EntriesOf${capitalize(bSide)}`;
2763
+ const entriesStateKeyB = `${bSide}EntriesOf${capitalize(aSide)}`;
2764
+ const contentStates = {
2765
+ [entriesStateKeyA]: multipleRelatedEntriesSelectors,
2766
+ [entriesStateKeyB]: multipleRelatedEntriesSelectors
2767
+ };
2768
+ states = Object.assign(baseStates, contentStates);
2769
+ } else states = baseStates;
2770
+ this.relations = relations;
2771
+ this.states = states;
2772
+ }
2773
+ }
2774
+ }
2775
+ };
2776
+
2777
+ //#endregion
2778
+ //#region src/internal/join/get-join.ts
2779
+ function getJoin(token, store) {
2780
+ let myJoin = store.joins.get(token.key);
2781
+ if (myJoin === void 0) {
2782
+ const rootJoinMap = IMPLICIT.STORE.joins;
2783
+ const rootJoin = rootJoinMap.get(token.key);
2784
+ if (rootJoin === void 0) throw new Error(`Join "${token.key}" not found in store "${store.config.name}"`);
2785
+ myJoin = new Join(rootJoin.options, rootJoin.defaultContent, store);
2786
+ store.joins.set(token.key, myJoin);
2787
+ }
2788
+ return myJoin;
2789
+ }
2790
+
2791
+ //#endregion
2792
+ //#region src/internal/join/edit-relations-in-store.ts
2793
+ function editRelationsInStore(token, change, store) {
2794
+ const myJoin = getJoin(token, store);
2795
+ const target = newest(store);
2796
+ if (isChildStore(target)) {
2797
+ const { toolkit } = target.transactionMeta;
2798
+ myJoin.transact(toolkit, ({ relations }) => {
2799
+ change(relations);
2800
+ });
2801
+ } else change(myJoin.relations);
2802
+ }
2803
+
2804
+ //#endregion
2805
+ //#region src/internal/join/find-relations-in-store.ts
2806
+ function findRelationsInStore(token, key, store) {
2807
+ const myJoin = getJoin(token, store);
2808
+ let relations;
2809
+ switch (token.cardinality) {
2810
+ case `1:1`: {
2811
+ const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
2812
+ const keyBA = `${token.b}KeyOf${capitalize(token.a)}`;
2813
+ relations = {
2814
+ get [keyAB]() {
2815
+ const familyAB = myJoin.states[keyAB];
2816
+ const state = findInStore(store, familyAB, key);
2817
+ return state;
2818
+ },
2819
+ get [keyBA]() {
2820
+ const familyBA = myJoin.states[keyBA];
2821
+ const state = findInStore(store, familyBA, key);
2822
+ return state;
2823
+ }
2824
+ };
2825
+ const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
2826
+ if (entryAB in myJoin.states) {
2827
+ const entryBA = `${token.b}EntryOf${capitalize(token.a)}`;
2828
+ Object.assign(relations, {
2829
+ get [entryAB]() {
2830
+ const familyAB = myJoin.states[entryAB];
2831
+ const state = findInStore(store, familyAB, key);
2832
+ return state;
2833
+ },
2834
+ get [entryBA]() {
2835
+ const familyBA = myJoin.states[entryBA];
2836
+ const state = findInStore(store, familyBA, key);
2837
+ return state;
2838
+ }
2839
+ });
2840
+ }
2841
+ break;
2842
+ }
2843
+ case `1:n`: {
2844
+ const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
2845
+ const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
2846
+ relations = {
2847
+ get [keyAB]() {
2848
+ const familyAB = myJoin.states[keyAB];
2849
+ const state = findInStore(store, familyAB, key);
2850
+ return state;
2851
+ },
2852
+ get [keysBA]() {
2853
+ const familyBA = myJoin.states[keysBA];
2854
+ const state = findInStore(store, familyBA, key);
2855
+ return state;
2856
+ }
2857
+ };
2858
+ const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
2859
+ if (entryAB in myJoin.states) {
2860
+ const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
2861
+ Object.assign(relations, {
2862
+ get [entryAB]() {
2863
+ const familyAB = myJoin.states[entryAB];
2864
+ const state = findInStore(store, familyAB, key);
2865
+ return state;
2866
+ },
2867
+ get [entriesBA]() {
2868
+ const familyBA = myJoin.states[entriesBA];
2869
+ const state = findInStore(store, familyBA, key);
2870
+ return state;
2871
+ }
2872
+ });
2873
+ }
2874
+ break;
2875
+ }
2876
+ case `n:n`: {
2877
+ const keysAB = `${token.a}KeysOf${capitalize(token.b)}`;
2878
+ const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
2879
+ relations = {
2880
+ get [keysAB]() {
2881
+ const familyAB = myJoin.states[keysAB];
2882
+ const state = findInStore(store, familyAB, key);
2883
+ return state;
2884
+ },
2885
+ get [keysBA]() {
2886
+ const familyBA = myJoin.states[keysBA];
2887
+ const state = findInStore(store, familyBA, key);
2888
+ return state;
2889
+ }
2890
+ };
2891
+ const entriesAB = `${token.a}EntriesOf${capitalize(token.b)}`;
2892
+ if (entriesAB in myJoin.states) {
2893
+ const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
2894
+ Object.assign(relations, {
2895
+ get [entriesAB]() {
2896
+ const familyAB = myJoin.states[entriesAB];
2897
+ const state = findInStore(store, familyAB, key);
2898
+ return state;
2899
+ },
2900
+ get [entriesBA]() {
2901
+ const familyBA = myJoin.states[entriesBA];
2902
+ const state = findInStore(store, familyBA, key);
2903
+ return state;
2904
+ }
2905
+ });
2906
+ }
2907
+ }
2908
+ }
2909
+ return relations;
2910
+ }
2911
+
2912
+ //#endregion
2913
+ //#region src/internal/join/get-internal-relations-from-store.ts
2914
+ function getInternalRelationsFromStore(token, store) {
2915
+ const myJoin = getJoin(token, store);
2916
+ const family = myJoin.core.relatedKeysAtoms;
2917
+ return family;
2918
+ }
2919
+
2920
+ //#endregion
2921
+ //#region src/internal/reserved-keys.ts
2922
+ function isReservedIntrospectionKey(value) {
2923
+ return value.startsWith(`🔍 `);
2924
+ }
2925
+
2926
+ //#endregion
2927
+ //#region src/internal/timeline/create-timeline.ts
2928
+ function createTimeline(store, options, data) {
2929
+ const tl = {
2930
+ type: `timeline`,
2931
+ key: options.key,
2932
+ at: 0,
2933
+ timeTraveling: null,
2934
+ selectorTime: null,
2935
+ transactionKey: null,
2936
+ ...data,
2937
+ history: data?.history.map((update) => ({ ...update })) ?? [],
2938
+ install: (s) => createTimeline(s, options, tl),
2939
+ subject: new Subject(),
2940
+ subscriptions: new Map()
2941
+ };
2942
+ if (options.shouldCapture) tl.shouldCapture = options.shouldCapture;
2943
+ const timelineKey = options.key;
2944
+ const target = newest(store);
2945
+ for (const initialTopic of options.scope) switch (initialTopic.type) {
2946
+ case `atom`:
2947
+ case `mutable_atom`:
2948
+ {
2949
+ const atomToken = initialTopic;
2950
+ const atomKey = atomToken.key;
2951
+ let existingTimelineKey = target.timelineTopics.getRelatedKey(atomKey);
2952
+ if (`family` in atomToken) {
2953
+ const familyKey = atomToken.family.key;
2954
+ existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
2955
+ if (existingTimelineKey) {
2956
+ store.logger.error(`❌`, `timeline`, options.key, `Failed to add atom "${atomKey}" because its family "${familyKey}" already belongs to timeline "${existingTimelineKey}"`);
2957
+ continue;
2958
+ }
2959
+ }
2960
+ if (existingTimelineKey) {
2961
+ store.logger.error(`❌`, `timeline`, options.key, `Failed to add atom "${atomKey}" because it already belongs to timeline "${existingTimelineKey}"`);
2962
+ continue;
2963
+ }
2964
+ addAtomToTimeline(store, atomToken, tl);
2965
+ }
2966
+ break;
2967
+ case `atom_family`:
2968
+ case `mutable_atom_family`:
2969
+ {
2970
+ const familyToken = initialTopic;
2971
+ const familyKey = familyToken.key;
2972
+ const existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
2973
+ if (existingTimelineKey) {
2974
+ store.logger.error(`❌`, `timeline`, options.key, `Failed to add atom family "${familyKey}" because it already belongs to timeline "${existingTimelineKey}"`);
2975
+ continue;
2976
+ }
2977
+ addAtomFamilyToTimeline(store, familyToken, tl);
2978
+ }
2979
+ break;
2980
+ }
2981
+ store.timelines.set(options.key, tl);
2982
+ const token = {
2983
+ key: timelineKey,
2984
+ type: `timeline`
2985
+ };
2986
+ store.on.timelineCreation.next(token);
2987
+ return token;
2988
+ }
2989
+ function addAtomToTimeline(store, atomToken, tl) {
2990
+ let maybeAtom = withdraw(store, atomToken);
2991
+ if (maybeAtom.type === `mutable_atom`) {
2992
+ const updateToken = getUpdateToken(maybeAtom);
2993
+ maybeAtom = withdraw(store, updateToken);
2994
+ }
2995
+ const atom$1 = maybeAtom;
2996
+ store.timelineTopics.set({
2997
+ topicKey: atom$1.key,
2998
+ timelineKey: tl.key
2999
+ }, { topicType: `atom` });
3000
+ tl.subscriptions.set(atom$1.key, atom$1.subject.subscribe(`timeline`, function timelineCapturesAtomUpdate(update) {
3001
+ const target = newest(store);
3002
+ const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
3003
+ const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
3004
+ const txUpdateInProgress = target.on.transactionApplying.state?.update;
3005
+ store.logger.info(`⏳`, `timeline`, tl.key, `atom`, atomToken.key, `went`, update.oldValue, `->`, update.newValue, txUpdateInProgress ? `in transaction "${txUpdateInProgress.key}"` : currentSelectorKey ? `in selector "${currentSelectorKey}"` : ``);
3006
+ if (tl.timeTraveling === null) if (txUpdateInProgress) joinTransaction(store, tl, txUpdateInProgress);
3007
+ else if (currentSelectorKey && currentSelectorTime) {
3008
+ let latestUpdate = tl.history.at(-1);
3009
+ if (currentSelectorTime !== tl.selectorTime) {
3010
+ latestUpdate = {
3011
+ type: `selector_update`,
3012
+ timestamp: currentSelectorTime,
3013
+ key: currentSelectorKey,
3014
+ atomUpdates: []
3015
+ };
3016
+ latestUpdate.atomUpdates.push({
3017
+ key: atom$1.key,
3018
+ type: `atom_update`,
3019
+ ...update
3020
+ });
3021
+ if (tl.at !== tl.history.length) tl.history.splice(tl.at);
3022
+ tl.history.push(latestUpdate);
3023
+ store.logger.info(`⌛`, `timeline`, tl.key, `got a selector_update "${currentSelectorKey}" with`, latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key));
3024
+ tl.at = tl.history.length;
3025
+ tl.selectorTime = currentSelectorTime;
3026
+ } else if (latestUpdate?.type === `selector_update`) {
3027
+ latestUpdate.atomUpdates.push({
3028
+ key: atom$1.key,
3029
+ type: `atom_update`,
3030
+ ...update
3031
+ });
3032
+ store.logger.info(`⌛`, `timeline`, tl.key, `set selector_update "${currentSelectorKey}" to`, latestUpdate?.atomUpdates.map((atomUpdate) => atomUpdate.key));
3033
+ }
3034
+ if (latestUpdate) {
3035
+ const willCaptureSelectorUpdate = tl.shouldCapture?.(latestUpdate, tl) ?? true;
3036
+ if (willCaptureSelectorUpdate) tl.subject.next(latestUpdate);
3037
+ else {
3038
+ tl.history.pop();
3039
+ tl.at = tl.history.length;
3040
+ }
3041
+ }
3042
+ } else {
3043
+ const timestamp = Date.now();
3044
+ tl.selectorTime = null;
3045
+ if (tl.at !== tl.history.length) tl.history.splice(tl.at);
3046
+ const atomUpdate = {
3047
+ type: `atom_update`,
3048
+ timestamp,
3049
+ key: atom$1.key,
3050
+ oldValue: update.oldValue,
3051
+ newValue: update.newValue
3052
+ };
3053
+ if (atom$1.family) atomUpdate.family = atom$1.family;
3054
+ const willCapture = tl.shouldCapture?.(atomUpdate, tl) ?? true;
3055
+ store.logger.info(`⌛`, `timeline`, tl.key, `got an atom_update to "${atom$1.key}"`);
3056
+ if (willCapture) {
3057
+ tl.history.push(atomUpdate);
3058
+ tl.at = tl.history.length;
3059
+ tl.subject.next(atomUpdate);
3060
+ }
3061
+ }
3062
+ }));
3063
+ }
3064
+ function addAtomFamilyToTimeline(store, atomFamilyToken, tl) {
3065
+ const family = withdraw(store, atomFamilyToken);
3066
+ store.timelineTopics.set({
3067
+ topicKey: family.key,
3068
+ timelineKey: tl.key
3069
+ }, { topicType: `atom_family` });
3070
+ tl.subscriptions.set(family.key, family.subject.subscribe(`timeline`, function timelineCapturesStateLifecycleEvent(creationOrDisposal) {
3071
+ handleStateLifecycleEvent(store, creationOrDisposal, tl);
3072
+ }));
3073
+ for (const atom$1 of store.atoms.values()) if (atom$1.family?.key === family.key) addAtomToTimeline(store, atom$1, tl);
3074
+ }
3075
+ function joinTransaction(store, tl, txUpdateInProgress) {
3076
+ const currentTxKey = txUpdateInProgress.key;
3077
+ const currentTxInstanceId = txUpdateInProgress.id;
3078
+ const currentTxToken = {
3079
+ key: currentTxKey,
3080
+ type: `transaction`
3081
+ };
3082
+ const currentTransaction = withdraw(store, currentTxToken);
3083
+ if (currentTxKey && tl.transactionKey === null) {
3084
+ tl.transactionKey = currentTxKey;
3085
+ const unsubscribe = currentTransaction.subject.subscribe(`timeline:${tl.key}`, (transactionUpdate) => {
3086
+ unsubscribe();
3087
+ tl.transactionKey = null;
3088
+ if (tl.timeTraveling === null && currentTxInstanceId) {
3089
+ if (tl.at !== tl.history.length) tl.history.splice(tl.at);
3090
+ const timelineTopics = store.timelineTopics.getRelatedKeys(tl.key);
3091
+ const updates = filterTransactionUpdates(transactionUpdate.updates, timelineTopics);
3092
+ const timelineTransactionUpdate = {
3093
+ timestamp: Date.now(),
3094
+ ...transactionUpdate,
3095
+ updates
3096
+ };
3097
+ const willCapture = tl.shouldCapture?.(timelineTransactionUpdate, tl) ?? true;
3098
+ if (willCapture) {
3099
+ tl.history.push(timelineTransactionUpdate);
3100
+ tl.at = tl.history.length;
3101
+ tl.subject.next(timelineTransactionUpdate);
3102
+ }
3103
+ }
3104
+ });
3105
+ }
3106
+ }
3107
+ function filterTransactionUpdates(updates, timelineTopics) {
3108
+ return updates.filter((updateFromTx) => {
3109
+ if (updateFromTx.type === `transaction_update`) return true;
3110
+ let key;
3111
+ let familyKey;
3112
+ switch (updateFromTx.type) {
3113
+ case `state_creation`:
3114
+ case `state_disposal`:
3115
+ key = updateFromTx.token.key;
3116
+ familyKey = updateFromTx.token.family?.key;
3117
+ break;
3118
+ case `molecule_creation`:
3119
+ case `molecule_disposal`:
3120
+ case `molecule_transfer`: return true;
3121
+ case `atom_update`:
3122
+ case `selector_update`:
3123
+ key = updateFromTx.key;
3124
+ familyKey = updateFromTx.family?.key;
3125
+ break;
3126
+ }
3127
+ timelineTopics.has(key);
3128
+ if (familyKey && timelineTopics.has(familyKey)) return true;
3129
+ return timelineTopics.has(key);
3130
+ }).map((updateFromTx) => {
3131
+ if (`updates` in updateFromTx) return {
3132
+ ...updateFromTx,
3133
+ updates: filterTransactionUpdates(updateFromTx.updates, timelineTopics)
3134
+ };
3135
+ return updateFromTx;
3136
+ });
3137
+ }
3138
+ function handleStateLifecycleEvent(store, event, tl) {
3139
+ const timestamp = Date.now();
3140
+ const timelineEvent = Object.assign(event, { timestamp });
3141
+ if (!tl.timeTraveling) {
3142
+ const target = newest(store);
3143
+ if (isChildStore(target)) {} else {
3144
+ const txUpdateInProgress = target.on.transactionApplying.state;
3145
+ if (txUpdateInProgress) joinTransaction(store, tl, txUpdateInProgress.update);
3146
+ else {
3147
+ tl.history.push(timelineEvent);
3148
+ tl.at = tl.history.length;
3149
+ tl.subject.next(timelineEvent);
3150
+ }
3151
+ }
3152
+ }
3153
+ switch (event.type) {
3154
+ case `state_creation`:
3155
+ addAtomToTimeline(store, event.token, tl);
3156
+ break;
3157
+ case `state_disposal`:
3158
+ tl.subscriptions.get(event.token.key)?.();
3159
+ tl.subscriptions.delete(event.token.key);
3160
+ break;
3161
+ }
3162
+ }
3163
+
3164
+ //#endregion
3165
+ //#region src/internal/timeline/time-travel.ts
3166
+ const timeTravel = (store, action, token) => {
3167
+ store.logger.info(action === `redo` ? `⏩` : `⏪`, `timeline`, token.key, action);
3168
+ const timelineData = store.timelines.get(token.key);
3169
+ if (!timelineData) {
3170
+ store.logger.error(`🐞`, `timeline`, token.key, `Failed to ${action}. This timeline has not been initialized.`);
3171
+ return;
3172
+ }
3173
+ if (action === `redo` && timelineData.at === timelineData.history.length || action === `undo` && timelineData.at === 0) {
3174
+ store.logger.warn(`💁`, `timeline`, token.key, `Failed to ${action} at the ${action === `redo` ? `end` : `beginning`} of timeline "${token.key}". There is nothing to ${action}.`);
3175
+ return;
3176
+ }
3177
+ timelineData.timeTraveling = action === `redo` ? `into_future` : `into_past`;
3178
+ if (action === `undo`) --timelineData.at;
3179
+ const update = timelineData.history[timelineData.at];
3180
+ const applying = action === `redo` ? `newValue` : `oldValue`;
3181
+ switch (update.type) {
3182
+ case `atom_update`: {
3183
+ ingestAtomUpdate(applying, update, store);
3184
+ break;
3185
+ }
3186
+ case `selector_update`: {
3187
+ ingestSelectorUpdate(applying, update, store);
3188
+ break;
3189
+ }
3190
+ case `transaction_update`: {
3191
+ ingestTransactionUpdate(applying, update, store);
3192
+ break;
3193
+ }
3194
+ case `state_creation`: {
3195
+ ingestCreationEvent(update, applying, store);
3196
+ break;
3197
+ }
3198
+ case `state_disposal`: {
3199
+ ingestDisposalEvent(update, applying, store);
3200
+ break;
3201
+ }
3202
+ case `molecule_creation`:
3203
+ case `molecule_disposal`:
3204
+ }
3205
+ if (action === `redo`) ++timelineData.at;
3206
+ timelineData.subject.next(action);
3207
+ timelineData.timeTraveling = null;
3208
+ store.logger.info(`⏹️`, `timeline`, token.key, `"${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`);
3209
+ };
3210
+
3211
+ //#endregion
3212
+ export { CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, Join, Junction, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, allocateIntoStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, capitalize, claimWithinStore, clearStore, closeOperation, counterfeit, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, createWritableSelectorFamily, deallocateFromStore, deposit, disposeAtom, disposeFromStore, disposeSelector, editRelationsInStore, evictCachedValue, findInStore, findRelationsInStore, fuseWithinStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getInternalRelationsFromStore, getJoin, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getTrace, getUpdateFamily, getUpdateToken, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, installIntoStore, isAtomDefault, isAtomKey, isChildStore, isDone, isReadonlySelectorKey, isReservedIntrospectionKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeRootMoleculeInStore, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, prettyPrintTokenType, readCachedValue, readOrComputeValue, recallState, registerSelector, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw };
3213
+ //# sourceMappingURL=index.js.map