atom.io 0.32.3 → 0.33.0

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 +497 -377
  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 +70 -122
  66. package/{data/src → src/data}/struct.ts +1 -0
  67. package/{eslint-plugin/src → src/eslint-plugin}/index.ts +3 -1
  68. package/{eslint-plugin/src → src/eslint-plugin}/rules/explicit-state-types.ts +6 -1
  69. package/{eslint-plugin/src → src/eslint-plugin}/rules/synchronous-selector-dependencies.ts +14 -1
  70. package/{internal/src → src/internal}/families/create-writable-selector-family.ts +4 -2
  71. package/{internal/src → src/internal}/families/index.ts +2 -0
  72. package/{internal/src → src/internal}/index.ts +1 -0
  73. package/{internal/src → src/internal}/join/find-relations-in-store.ts +12 -0
  74. package/{internal/src → src/internal}/junction.ts +3 -2
  75. package/{internal/src → src/internal}/lazy-map.ts +1 -1
  76. package/{internal/src → src/internal}/mutable/tracker-family.ts +2 -5
  77. package/{internal/src → src/internal}/mutable/tracker.ts +15 -9
  78. package/{internal/src → src/internal}/selector/register-selector.ts +2 -1
  79. package/{internal/src → src/internal}/store/store.ts +68 -53
  80. package/{internal/src → src/internal}/subject.ts +1 -1
  81. package/{internal/src → src/internal}/transaction/build-transaction.ts +2 -1
  82. package/{introspection/src → src/introspection}/auditor.ts +1 -1
  83. package/{introspection/src → src/introspection}/differ.ts +12 -1
  84. package/{introspection/src → src/introspection}/refinery.ts +18 -3
  85. package/{json/src → src/json}/entries.ts +1 -1
  86. package/{json/src → src/json}/select-json-family.ts +1 -1
  87. package/src/{realm.ts → main/realm.ts} +1 -1
  88. package/src/{silo.ts → main/silo.ts} +1 -1
  89. package/src/{transaction.ts → main/transaction.ts} +1 -1
  90. package/{react/src → src/react}/store-context.tsx +3 -1
  91. package/{react/src → src/react}/use-i.ts +3 -5
  92. package/{react-devtools/src → src/react-devtools}/AtomIODevtools.tsx +1 -1
  93. package/{react-devtools/src → src/react-devtools}/Button.tsx +3 -1
  94. package/{react-devtools/src → src/react-devtools}/Updates.tsx +5 -1
  95. package/src/react-devtools/devtools.css +308 -0
  96. package/{react-devtools/src → src/react-devtools}/json-editor/developer-interface.tsx +2 -2
  97. package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/utilities/cast-json.ts +2 -2
  98. package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/utilities/object-properties.ts +3 -3
  99. package/{react-devtools/src → src/react-devtools}/json-editor/json-editor-internal.tsx +4 -2
  100. package/{react-devtools/src → src/react-devtools}/store.ts +3 -2
  101. package/{realtime/src → src/realtime}/shared-room-store.ts +28 -5
  102. package/src/realtime-client/realtime-client-stores/client-main-store.ts +23 -0
  103. package/src/realtime-client/realtime-client-stores/client-sync-store.ts +15 -0
  104. package/{realtime-react/src → src/realtime-react}/index.ts +1 -0
  105. package/{realtime-react/src → src/realtime-react}/on-mount.ts +1 -1
  106. package/{realtime-react/src → src/realtime-react}/realtime-context.tsx +5 -4
  107. package/{realtime-react/src → src/realtime-react}/use-single-effect.ts +3 -2
  108. package/{realtime-server/src → src/realtime-server}/ipc-sockets/child-socket.ts +1 -1
  109. package/{realtime-server/src → src/realtime-server}/realtime-server-stores/server-room-external-actions.ts +20 -19
  110. package/{realtime-server/src → src/realtime-server}/realtime-server-stores/server-room-external-store.ts +12 -7
  111. package/{realtime-server/src → src/realtime-server}/realtime-server-stores/server-sync-store.ts +13 -4
  112. package/{realtime-server/src → src/realtime-server}/realtime-server-stores/server-user-store.ts +26 -8
  113. package/{transceivers/set-rtx/src → src/transceivers/set-rtx}/set-rtx.ts +2 -2
  114. package/data/dist/index.d.ts +0 -31
  115. package/data/dist/index.js +0 -69
  116. package/data/package.json +0 -13
  117. package/dist/chunk-2XDFCXGB.js +0 -109
  118. package/dist/chunk-35NB2XZU.js +0 -4501
  119. package/dist/chunk-4LWKCEW3.js +0 -14
  120. package/dist/chunk-EF4S7H42.js +0 -526
  121. package/dist/chunk-LTLDKXDN.js +0 -153
  122. package/dist/chunk-MENOYVPP.js +0 -83
  123. package/dist/chunk-RGUNRT72.js +0 -634
  124. package/dist/chunk-TS76LQVD.js +0 -1035
  125. package/dist/chunk-XWL6SNVU.js +0 -7
  126. package/dist/index.d.ts +0 -701
  127. package/dist/index.js +0 -2
  128. package/eslint-plugin/dist/index.d.ts +0 -64
  129. package/eslint-plugin/dist/index.js +0 -238
  130. package/eslint-plugin/package.json +0 -13
  131. package/internal/dist/index.js +0 -2
  132. package/internal/package.json +0 -13
  133. package/introspection/dist/index.d.ts +0 -149
  134. package/introspection/dist/index.js +0 -3
  135. package/introspection/package.json +0 -13
  136. package/json/dist/index.js +0 -2
  137. package/json/package.json +0 -13
  138. package/react/dist/index.js +0 -3
  139. package/react/package.json +0 -13
  140. package/react-devtools/dist/index.css +0 -309
  141. package/react-devtools/dist/index.d.ts +0 -160
  142. package/react-devtools/dist/index.js +0 -1481
  143. package/react-devtools/package.json +0 -13
  144. package/react-devtools/src/devtools.scss +0 -309
  145. package/realtime/dist/index.d.ts +0 -51
  146. package/realtime/dist/index.js +0 -3
  147. package/realtime/package.json +0 -13
  148. package/realtime-client/dist/index.d.ts +0 -41
  149. package/realtime-client/dist/index.js +0 -4
  150. package/realtime-client/package.json +0 -13
  151. package/realtime-client/src/realtime-client-stores/client-main-store.ts +0 -20
  152. package/realtime-client/src/realtime-client-stores/client-sync-store.ts +0 -15
  153. package/realtime-react/dist/index.d.ts +0 -39
  154. package/realtime-react/dist/index.js +0 -6
  155. package/realtime-react/package.json +0 -13
  156. package/realtime-server/dist/index.d.ts +0 -139
  157. package/realtime-server/dist/index.js +0 -4
  158. package/realtime-server/package.json +0 -13
  159. package/realtime-testing/dist/index.d.ts +0 -59
  160. package/realtime-testing/dist/index.js +0 -198
  161. package/realtime-testing/package.json +0 -13
  162. package/transceivers/set-rtx/dist/index.d.ts +0 -41
  163. package/transceivers/set-rtx/dist/index.js +0 -2
  164. package/transceivers/set-rtx/package.json +0 -13
  165. package/web/dist/index.d.ts +0 -9
  166. package/web/dist/index.js +0 -2
  167. package/web/package.json +0 -13
  168. /package/{data/src → src/data}/dict.ts +0 -0
  169. /package/{data/src → src/data}/index.ts +0 -0
  170. /package/{data/src → src/data}/struct-family.ts +0 -0
  171. /package/{eslint-plugin/src → src/eslint-plugin}/rules/index.ts +0 -0
  172. /package/{eslint-plugin/src → src/eslint-plugin}/walk.ts +0 -0
  173. /package/{internal/src → src/internal}/arbitrary.ts +0 -0
  174. /package/{internal/src → src/internal}/atom/create-regular-atom.ts +0 -0
  175. /package/{internal/src → src/internal}/atom/create-standalone-atom.ts +0 -0
  176. /package/{internal/src → src/internal}/atom/dispose-atom.ts +0 -0
  177. /package/{internal/src → src/internal}/atom/index.ts +0 -0
  178. /package/{internal/src → src/internal}/atom/is-default.ts +0 -0
  179. /package/{internal/src → src/internal}/caching.ts +0 -0
  180. /package/{internal/src → src/internal}/capitalize.ts +0 -0
  181. /package/{internal/src → src/internal}/families/create-atom-family.ts +0 -0
  182. /package/{internal/src → src/internal}/families/create-readonly-selector-family.ts +0 -0
  183. /package/{internal/src → src/internal}/families/create-regular-atom-family.ts +0 -0
  184. /package/{internal/src → src/internal}/families/create-selector-family.ts +0 -0
  185. /package/{internal/src → src/internal}/families/dispose-from-store.ts +0 -0
  186. /package/{internal/src → src/internal}/families/find-in-store.ts +0 -0
  187. /package/{internal/src → src/internal}/families/get-family-of-token.ts +0 -0
  188. /package/{internal/src → src/internal}/families/init-family-member.ts +0 -0
  189. /package/{internal/src → src/internal}/families/seek-in-store.ts +0 -0
  190. /package/{internal/src → src/internal}/future.ts +0 -0
  191. /package/{internal/src → src/internal}/get-environment-data.ts +0 -0
  192. /package/{internal/src → src/internal}/get-state/get-from-store.ts +0 -0
  193. /package/{internal/src → src/internal}/get-state/index.ts +0 -0
  194. /package/{internal/src → src/internal}/get-state/read-or-compute-value.ts +0 -0
  195. /package/{internal/src → src/internal}/get-trace.ts +0 -0
  196. /package/{internal/src → src/internal}/ingest-updates/index.ts +0 -0
  197. /package/{internal/src → src/internal}/ingest-updates/ingest-atom-update.ts +0 -0
  198. /package/{internal/src → src/internal}/ingest-updates/ingest-creation-disposal.ts +0 -0
  199. /package/{internal/src → src/internal}/ingest-updates/ingest-selector-update.ts +0 -0
  200. /package/{internal/src → src/internal}/ingest-updates/ingest-transaction-update.ts +0 -0
  201. /package/{internal/src → src/internal}/install-into-store.ts +0 -0
  202. /package/{internal/src → src/internal}/join/edit-relations-in-store.ts +0 -0
  203. /package/{internal/src → src/internal}/join/get-internal-relations-from-store.ts +0 -0
  204. /package/{internal/src → src/internal}/join/get-join.ts +0 -0
  205. /package/{internal/src → src/internal}/join/index.ts +0 -0
  206. /package/{internal/src → src/internal}/join/join-internal.ts +0 -0
  207. /package/{internal/src → src/internal}/keys.ts +0 -0
  208. /package/{internal/src → src/internal}/lineage.ts +0 -0
  209. /package/{internal/src → src/internal}/molecule.ts +0 -0
  210. /package/{internal/src → src/internal}/mutable/create-mutable-atom-family.ts +0 -0
  211. /package/{internal/src → src/internal}/mutable/create-mutable-atom.ts +0 -0
  212. /package/{internal/src → src/internal}/mutable/get-json-family.ts +0 -0
  213. /package/{internal/src → src/internal}/mutable/get-json-token.ts +0 -0
  214. /package/{internal/src → src/internal}/mutable/get-update-family.ts +0 -0
  215. /package/{internal/src → src/internal}/mutable/get-update-token.ts +0 -0
  216. /package/{internal/src → src/internal}/mutable/index.ts +0 -0
  217. /package/{internal/src → src/internal}/mutable/transceiver.ts +0 -0
  218. /package/{internal/src → src/internal}/not-found-error.ts +0 -0
  219. /package/{internal/src → src/internal}/operation.ts +0 -0
  220. /package/{internal/src → src/internal}/pretty-print.ts +0 -0
  221. /package/{internal/src → src/internal}/reserved-keys.ts +0 -0
  222. /package/{internal/src → src/internal}/selector/create-readonly-selector.ts +0 -0
  223. /package/{internal/src → src/internal}/selector/create-standalone-selector.ts +0 -0
  224. /package/{internal/src → src/internal}/selector/create-writable-selector.ts +0 -0
  225. /package/{internal/src → src/internal}/selector/dispose-selector.ts +0 -0
  226. /package/{internal/src → src/internal}/selector/get-selector-dependency-keys.ts +0 -0
  227. /package/{internal/src → src/internal}/selector/index.ts +0 -0
  228. /package/{internal/src → src/internal}/selector/trace-selector-atoms.ts +0 -0
  229. /package/{internal/src → src/internal}/selector/update-selector-atoms.ts +0 -0
  230. /package/{internal/src → src/internal}/set-state/become.ts +0 -0
  231. /package/{internal/src → src/internal}/set-state/copy-mutable-if-needed.ts +0 -0
  232. /package/{internal/src → src/internal}/set-state/emit-update.ts +0 -0
  233. /package/{internal/src → src/internal}/set-state/evict-downstream.ts +0 -0
  234. /package/{internal/src → src/internal}/set-state/index.ts +0 -0
  235. /package/{internal/src → src/internal}/set-state/set-atom-or-selector.ts +0 -0
  236. /package/{internal/src → src/internal}/set-state/set-atom.ts +0 -0
  237. /package/{internal/src → src/internal}/set-state/set-into-store.ts +0 -0
  238. /package/{internal/src → src/internal}/store/circular-buffer.ts +0 -0
  239. /package/{internal/src → src/internal}/store/counterfeit.ts +0 -0
  240. /package/{internal/src → src/internal}/store/deposit.ts +0 -0
  241. /package/{internal/src → src/internal}/store/index.ts +0 -0
  242. /package/{internal/src → src/internal}/store/withdraw.ts +0 -0
  243. /package/{internal/src → src/internal}/subscribe/index.ts +0 -0
  244. /package/{internal/src → src/internal}/subscribe/recall-state.ts +0 -0
  245. /package/{internal/src → src/internal}/subscribe/subscribe-in-store.ts +0 -0
  246. /package/{internal/src → src/internal}/subscribe/subscribe-to-root-atoms.ts +0 -0
  247. /package/{internal/src → src/internal}/subscribe/subscribe-to-state.ts +0 -0
  248. /package/{internal/src → src/internal}/subscribe/subscribe-to-timeline.ts +0 -0
  249. /package/{internal/src → src/internal}/subscribe/subscribe-to-transaction.ts +0 -0
  250. /package/{internal/src → src/internal}/timeline/create-timeline.ts +0 -0
  251. /package/{internal/src → src/internal}/timeline/index.ts +0 -0
  252. /package/{internal/src → src/internal}/timeline/time-travel.ts +0 -0
  253. /package/{internal/src → src/internal}/transaction/abort-transaction.ts +0 -0
  254. /package/{internal/src → src/internal}/transaction/act-upon-store.ts +0 -0
  255. /package/{internal/src → src/internal}/transaction/apply-transaction.ts +0 -0
  256. /package/{internal/src → src/internal}/transaction/assign-transaction-to-continuity.ts +0 -0
  257. /package/{internal/src → src/internal}/transaction/create-transaction.ts +0 -0
  258. /package/{internal/src → src/internal}/transaction/get-epoch-number.ts +0 -0
  259. /package/{internal/src → src/internal}/transaction/index.ts +0 -0
  260. /package/{internal/src → src/internal}/transaction/is-root-store.ts +0 -0
  261. /package/{internal/src → src/internal}/transaction/set-epoch-number.ts +0 -0
  262. /package/{internal/src → src/internal}/utility-types.ts +0 -0
  263. /package/{introspection/src → src/introspection}/attach-atom-index.ts +0 -0
  264. /package/{introspection/src → src/introspection}/attach-introspection-states.ts +0 -0
  265. /package/{introspection/src → src/introspection}/attach-selector-index.ts +0 -0
  266. /package/{introspection/src → src/introspection}/attach-timeline-family.ts +0 -0
  267. /package/{introspection/src → src/introspection}/attach-timeline-index.ts +0 -0
  268. /package/{introspection/src → src/introspection}/attach-transaction-index.ts +0 -0
  269. /package/{introspection/src → src/introspection}/attach-transaction-logs.ts +0 -0
  270. /package/{introspection/src → src/introspection}/attach-type-selectors.ts +0 -0
  271. /package/{introspection/src → src/introspection}/index.ts +0 -0
  272. /package/{introspection/src → src/introspection}/sprawl.ts +0 -0
  273. /package/{json/src → src/json}/index.ts +0 -0
  274. /package/{json/src → src/json}/select-json.ts +0 -0
  275. /package/src/{atom.ts → main/atom.ts} +0 -0
  276. /package/src/{dispose-state.ts → main/dispose-state.ts} +0 -0
  277. /package/src/{find-state.ts → main/find-state.ts} +0 -0
  278. /package/src/{get-state.ts → main/get-state.ts} +0 -0
  279. /package/src/{index.ts → main/index.ts} +0 -0
  280. /package/src/{join.ts → main/join.ts} +0 -0
  281. /package/src/{logger.ts → main/logger.ts} +0 -0
  282. /package/src/{selector.ts → main/selector.ts} +0 -0
  283. /package/src/{set-state.ts → main/set-state.ts} +0 -0
  284. /package/src/{subscribe.ts → main/subscribe.ts} +0 -0
  285. /package/src/{timeline.ts → main/timeline.ts} +0 -0
  286. /package/src/{validators.ts → main/validators.ts} +0 -0
  287. /package/{react/src → src/react}/index.ts +0 -0
  288. /package/{react/src → src/react}/parse-state-overloads.ts +0 -0
  289. /package/{react/src → src/react}/use-json.ts +0 -0
  290. /package/{react/src → src/react}/use-o.ts +0 -0
  291. /package/{react/src → src/react}/use-tl.ts +0 -0
  292. /package/{react-devtools/src → src/react-devtools}/StateEditor.tsx +0 -0
  293. /package/{react-devtools/src → src/react-devtools}/StateIndex.tsx +0 -0
  294. /package/{react-devtools/src → src/react-devtools}/TimelineIndex.tsx +0 -0
  295. /package/{react-devtools/src → src/react-devtools}/TransactionIndex.tsx +0 -0
  296. /package/{react-devtools/src → src/react-devtools}/elastic-input/ElasticInput.tsx +0 -0
  297. /package/{react-devtools/src → src/react-devtools}/elastic-input/NumberInput.tsx +0 -0
  298. /package/{react-devtools/src → src/react-devtools}/elastic-input/TextInput.tsx +0 -0
  299. /package/{react-devtools/src → src/react-devtools}/elastic-input/index.ts +0 -0
  300. /package/{react-devtools/src → src/react-devtools}/error-boundary/DefaultFallback.tsx +0 -0
  301. /package/{react-devtools/src → src/react-devtools}/error-boundary/ReactErrorBoundary.tsx +0 -0
  302. /package/{react-devtools/src → src/react-devtools}/error-boundary/index.ts +0 -0
  303. /package/{react-devtools/src → src/react-devtools}/index.ts +0 -0
  304. /package/{react-devtools/src → src/react-devtools}/json-editor/default-components.tsx +0 -0
  305. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/array-editor.tsx +0 -0
  306. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/non-json.tsx +0 -0
  307. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/object-editor.tsx +0 -0
  308. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/primitive-editors.tsx +0 -0
  309. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/utilities/array-elements.ts +0 -0
  310. /package/{react-devtools/src → src/react-devtools}/json-editor/editors-by-type/utilities/cast-to-json.ts +0 -0
  311. /package/{react-devtools/src → src/react-devtools}/json-editor/index.ts +0 -0
  312. /package/{react-devtools/src → src/react-devtools}/json-editor/todo.md +0 -0
  313. /package/{realtime/src → src/realtime}/index.ts +0 -0
  314. /package/{realtime/src → src/realtime}/realtime-continuity.ts +0 -0
  315. /package/{realtime-client/src → src/realtime-client}/continuity/index.ts +0 -0
  316. /package/{realtime-client/src → src/realtime-client}/continuity/register-and-attempt-confirmed-update.ts +0 -0
  317. /package/{realtime-client/src → src/realtime-client}/continuity/use-conceal-state.ts +0 -0
  318. /package/{realtime-client/src → src/realtime-client}/continuity/use-reveal-state.ts +0 -0
  319. /package/{realtime-client/src → src/realtime-client}/index.ts +0 -0
  320. /package/{realtime-client/src → src/realtime-client}/pull-atom-family-member.ts +0 -0
  321. /package/{realtime-client/src → src/realtime-client}/pull-atom.ts +0 -0
  322. /package/{realtime-client/src → src/realtime-client}/pull-mutable-atom-family-member.ts +0 -0
  323. /package/{realtime-client/src → src/realtime-client}/pull-mutable-atom.ts +0 -0
  324. /package/{realtime-client/src → src/realtime-client}/pull-selector-family-member.ts +0 -0
  325. /package/{realtime-client/src → src/realtime-client}/pull-selector.ts +0 -0
  326. /package/{realtime-client/src → src/realtime-client}/push-state.ts +0 -0
  327. /package/{realtime-client/src → src/realtime-client}/realtime-client-stores/index.ts +0 -0
  328. /package/{realtime-client/src → src/realtime-client}/server-action.ts +0 -0
  329. /package/{realtime-client/src → src/realtime-client}/sync-continuity.ts +0 -0
  330. /package/{realtime-react/src → src/realtime-react}/use-pull-atom-family-member.ts +0 -0
  331. /package/{realtime-react/src → src/realtime-react}/use-pull-atom.ts +0 -0
  332. /package/{realtime-react/src → src/realtime-react}/use-pull-mutable-atom.ts +0 -0
  333. /package/{realtime-react/src → src/realtime-react}/use-pull-mutable-family-member.ts +0 -0
  334. /package/{realtime-react/src → src/realtime-react}/use-pull-selector-family-member.ts +0 -0
  335. /package/{realtime-react/src → src/realtime-react}/use-pull-selector.ts +0 -0
  336. /package/{realtime-react/src → src/realtime-react}/use-push.ts +0 -0
  337. /package/{realtime-react/src → src/realtime-react}/use-realtime-service.ts +0 -0
  338. /package/{realtime-react/src → src/realtime-react}/use-server-action.ts +0 -0
  339. /package/{realtime-react/src → src/realtime-react}/use-sync-continuity.ts +0 -0
  340. /package/{realtime-server/src → src/realtime-server}/README.md +0 -0
  341. /package/{realtime-server/src → src/realtime-server}/continuity/prepare-to-send-initial-payload.ts +0 -0
  342. /package/{realtime-server/src → src/realtime-server}/continuity/prepare-to-serve-transaction-request.ts +0 -0
  343. /package/{realtime-server/src → src/realtime-server}/continuity/prepare-to-sync-realtime-continuity.ts +0 -0
  344. /package/{realtime-server/src → src/realtime-server}/continuity/prepare-to-track-client-acknowledgement.ts +0 -0
  345. /package/{realtime-server/src → src/realtime-server}/continuity/subscribe-to-continuity-actions.ts +0 -0
  346. /package/{realtime-server/src → src/realtime-server}/continuity/subscribe-to-continuity-perpectives.ts +0 -0
  347. /package/{realtime-server/src → src/realtime-server}/index.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
@@ -1,4501 +0,0 @@
1
- // json/src/entries.ts
2
- function fromEntries(entries) {
3
- return Object.fromEntries(entries);
4
- }
5
- function toEntries(obj) {
6
- return Object.entries(obj);
7
- }
8
-
9
- // internal/src/arbitrary.ts
10
- function arbitrary(random = Math.random) {
11
- return random().toString(36).slice(2);
12
- }
13
-
14
- // internal/src/future.ts
15
- var Future = class extends Promise {
16
- fate;
17
- resolve;
18
- reject;
19
- done = false;
20
- constructor(executor) {
21
- let superResolve;
22
- let superReject;
23
- super((resolve, reject) => {
24
- superResolve = resolve;
25
- superReject = reject;
26
- });
27
- this.resolve = superResolve;
28
- this.reject = superReject;
29
- this.use(executor instanceof Promise ? executor : new Promise(executor));
30
- }
31
- pass(promise, value) {
32
- if (promise === this.fate) {
33
- this.resolve(value);
34
- this.done = true;
35
- }
36
- }
37
- fail(promise, reason) {
38
- if (promise === this.fate) {
39
- this.reject(reason);
40
- this.done = true;
41
- }
42
- }
43
- use(value) {
44
- if (value instanceof Promise) {
45
- const promise = value;
46
- this.fate = promise;
47
- promise.then(
48
- (resolved) => {
49
- this.pass(promise, resolved);
50
- },
51
- (reason) => {
52
- this.fail(promise, reason);
53
- }
54
- );
55
- } else {
56
- this.resolve(value);
57
- this.fate = void 0;
58
- }
59
- }
60
- };
61
-
62
- // internal/src/lineage.ts
63
- function newest(scion) {
64
- while (scion.child !== null) {
65
- scion = scion.child;
66
- }
67
- return scion;
68
- }
69
-
70
- // internal/src/store/circular-buffer.ts
71
- var CircularBuffer = class _CircularBuffer {
72
- _buffer;
73
- _index = 0;
74
- constructor(lengthOrArray) {
75
- let length;
76
- if (typeof lengthOrArray === `number`) {
77
- length = lengthOrArray;
78
- } else {
79
- length = lengthOrArray.length;
80
- }
81
- this._buffer = Array.from({ length });
82
- }
83
- get buffer() {
84
- return this._buffer;
85
- }
86
- get index() {
87
- return this._index;
88
- }
89
- add(item) {
90
- this._buffer[this._index] = item;
91
- this._index = (this._index + 1) % this._buffer.length;
92
- }
93
- copy() {
94
- const copy = new _CircularBuffer([...this._buffer]);
95
- copy._index = this._index;
96
- return copy;
97
- }
98
- };
99
-
100
- // internal/src/store/counterfeit.ts
101
- var FAMILY_MEMBER_TOKEN_TYPES = {
102
- atom_family: `atom`,
103
- mutable_atom_family: `mutable_atom`,
104
- selector_family: `selector`,
105
- readonly_selector_family: `readonly_selector`,
106
- molecule_family: `molecule`
107
- };
108
- function counterfeit(token, key) {
109
- const subKey = stringifyJson(key);
110
- const fullKey = `${token.key}(${subKey})`;
111
- const type = FAMILY_MEMBER_TOKEN_TYPES[token.type];
112
- const stateToken = {
113
- key: fullKey,
114
- type
115
- };
116
- Object.assign(stateToken, {
117
- family: {
118
- key: token.key,
119
- subKey
120
- }
121
- });
122
- Object.assign(stateToken, { counterfeit: true });
123
- return stateToken;
124
- }
125
-
126
- // internal/src/store/deposit.ts
127
- function deposit(state) {
128
- const token = {
129
- key: state.key,
130
- type: state.type
131
- };
132
- if (`family` in state) {
133
- token.family = state.family;
134
- }
135
- return token;
136
- }
137
-
138
- // src/atom.ts
139
- function atom(options) {
140
- return createStandaloneAtom(IMPLICIT.STORE, options);
141
- }
142
- function atomFamily(options) {
143
- return createAtomFamily(IMPLICIT.STORE, options);
144
- }
145
-
146
- // src/dispose-state.ts
147
- function disposeState(...[token, key]) {
148
- if (key) {
149
- disposeFromStore(IMPLICIT.STORE, token, key);
150
- } else {
151
- disposeFromStore(IMPLICIT.STORE, token);
152
- }
153
- }
154
-
155
- // src/find-state.ts
156
- function findState(token, key) {
157
- const state = findInStore(IMPLICIT.STORE, token, key);
158
- return state;
159
- }
160
-
161
- // src/get-state.ts
162
- function getState(...params) {
163
- if (params.length === 2) {
164
- return getFromStore(IMPLICIT.STORE, ...params);
165
- }
166
- return getFromStore(IMPLICIT.STORE, ...params);
167
- }
168
-
169
- // src/join.ts
170
- function join(options, defaultContent, store = IMPLICIT.STORE) {
171
- store.joins.set(options.key, new Join(options, defaultContent, store));
172
- const token = {
173
- key: options.key,
174
- type: `join`,
175
- a: options.between[0],
176
- b: options.between[1],
177
- cardinality: options.cardinality
178
- };
179
- return token;
180
- }
181
- function findRelations(token, key) {
182
- return findRelationsInStore(token, key, IMPLICIT.STORE);
183
- }
184
- function editRelations(token, change) {
185
- editRelationsInStore(token, change, IMPLICIT.STORE);
186
- }
187
- function getInternalRelations(token) {
188
- return getInternalRelationsFromStore(token, IMPLICIT.STORE);
189
- }
190
-
191
- // src/logger.ts
192
- var LOG_LEVELS = [`info`, `warn`, `error`];
193
- var simpleLog = (logLevel) => (icon, denomination, tokenKey, message, ...rest) => {
194
- console[logLevel](
195
- `${icon} ${denomination} "${tokenKey}" ${message}`,
196
- ...rest
197
- );
198
- };
199
- var simpleLogger = {
200
- error: simpleLog(`error`),
201
- info: simpleLog(`info`),
202
- warn: simpleLog(`warn`)
203
- };
204
- var AtomIOLogger = class {
205
- logLevel;
206
- filter;
207
- logger;
208
- constructor(logLevel, filter, logger = simpleLogger) {
209
- this.logLevel = logLevel;
210
- this.filter = filter;
211
- this.logger = logger;
212
- }
213
- error = (...args) => {
214
- if ((this.filter?.(...args) ?? true) && this.logLevel !== null) {
215
- this.logger.error(...args);
216
- }
217
- };
218
- info = (...args) => {
219
- if ((this.filter?.(...args) ?? true) && this.logLevel === `info`) {
220
- this.logger.info(...args);
221
- }
222
- };
223
- warn = (...args) => {
224
- if ((this.filter?.(...args) ?? true) && this.logLevel !== `error` && this.logLevel !== null) {
225
- this.logger.warn(...args);
226
- }
227
- };
228
- };
229
-
230
- // src/realm.ts
231
- var $claim = Symbol(`claim`);
232
- var Realm = class {
233
- store;
234
- constructor(store = IMPLICIT.STORE) {
235
- this.store = store;
236
- makeRootMoleculeInStore(`root`, store);
237
- }
238
- allocate(provenance, key, attachmentStyle) {
239
- return allocateIntoStore(
240
- this.store,
241
- provenance,
242
- key,
243
- attachmentStyle
244
- );
245
- }
246
- fuse(type, reagentA, reagentB) {
247
- return fuseWithinStore(this.store, type, reagentA, reagentB);
248
- }
249
- deallocate(claim) {
250
- deallocateFromStore(this.store, claim);
251
- }
252
- claim(newProvenance, claim, exclusive) {
253
- return claimWithinStore(this.store, newProvenance, claim, exclusive);
254
- }
255
- };
256
- var Anarchy = class {
257
- store;
258
- realm;
259
- constructor(store = IMPLICIT.STORE) {
260
- this.store = store;
261
- this.realm = new Realm(store);
262
- }
263
- allocate(provenance, key, attachmentStyle) {
264
- allocateIntoStore(
265
- this.store,
266
- provenance,
267
- key,
268
- attachmentStyle
269
- );
270
- }
271
- deallocate(key) {
272
- deallocateFromStore(this.store, key);
273
- }
274
- claim(newProvenance, key, exclusive) {
275
- claimWithinStore(this.store, newProvenance, key, exclusive);
276
- }
277
- };
278
- var T$ = `T$`;
279
-
280
- // src/selector.ts
281
- function selector(options) {
282
- return createStandaloneSelector(IMPLICIT.STORE, options);
283
- }
284
- function selectorFamily(options) {
285
- return createSelectorFamily(IMPLICIT.STORE, options);
286
- }
287
-
288
- // src/set-state.ts
289
- function setState(...params) {
290
- if (params.length === 2) {
291
- setIntoStore(IMPLICIT.STORE, ...params);
292
- } else {
293
- setIntoStore(IMPLICIT.STORE, ...params);
294
- }
295
- }
296
-
297
- // internal/src/transaction/is-root-store.ts
298
- function isRootStore(store) {
299
- return `epoch` in store.transactionMeta;
300
- }
301
- function isChildStore(store) {
302
- return `phase` in store.transactionMeta;
303
- }
304
-
305
- // internal/src/transaction/abort-transaction.ts
306
- var abortTransaction = (store) => {
307
- const target = newest(store);
308
- if (!isChildStore(target)) {
309
- store.logger.warn(
310
- `\u{1F41E}`,
311
- `transaction`,
312
- `???`,
313
- `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
314
- );
315
- return;
316
- }
317
- store.logger.info(
318
- `\u{1FA82}`,
319
- `transaction`,
320
- target.transactionMeta.update.key,
321
- `Aborting transaction`
322
- );
323
- target.parent.child = null;
324
- };
325
-
326
- // internal/src/capitalize.ts
327
- function capitalize(string) {
328
- return string[0].toUpperCase() + string.slice(1);
329
- }
330
-
331
- // internal/src/pretty-print.ts
332
- function prettyPrintTokenType(token) {
333
- return token.type.split(`_`).map(capitalize).join(` `);
334
- }
335
-
336
- // internal/src/not-found-error.ts
337
- var NotFoundError = class extends Error {
338
- constructor(token, store) {
339
- super(
340
- `${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${store.config.name}".`
341
- );
342
- }
343
- };
344
-
345
- // internal/src/transaction/act-upon-store.ts
346
- function actUponStore(store, token, id) {
347
- return (...parameters) => {
348
- const tx = withdraw(store, token);
349
- if (tx) {
350
- return tx.run(parameters, id);
351
- }
352
- throw new NotFoundError(token, store);
353
- };
354
- }
355
-
356
- // internal/src/set-state/become.ts
357
- var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(originalThing) : nextVersionOfThing;
358
-
359
- // internal/src/get-state/read-or-compute-value.ts
360
- var readOrComputeValue = (target, state) => {
361
- if (target.valueMap.has(state.key)) {
362
- target.logger.info(`\u{1F4D6}`, state.type, state.key, `reading cached value`);
363
- return readCachedValue(state, target);
364
- }
365
- switch (state.type) {
366
- case `selector`:
367
- case `readonly_selector`:
368
- target.logger.info(`\u{1F9EE}`, state.type, state.key, `computing value`);
369
- return state.get();
370
- case `atom`:
371
- case `mutable_atom`: {
372
- const def = state.default;
373
- let fallback;
374
- if (def instanceof Function) {
375
- fallback = def();
376
- } else {
377
- fallback = def;
378
- }
379
- target.logger.info(
380
- `\u{1F481}`,
381
- `atom`,
382
- state.key,
383
- `could not find cached value; using default`,
384
- fallback
385
- );
386
- return fallback;
387
- }
388
- }
389
- };
390
-
391
- // internal/src/operation.ts
392
- var openOperation = (store, token) => {
393
- if (store.operation.open) {
394
- const rejectionTime = performance.now();
395
- store.logger.info(
396
- `\u2757`,
397
- token.type,
398
- token.key,
399
- `deferring setState at T-${rejectionTime} until setState for "${store.operation.token.key}" is done`
400
- );
401
- return rejectionTime;
402
- }
403
- store.operation = {
404
- open: true,
405
- done: /* @__PURE__ */ new Set(),
406
- prev: /* @__PURE__ */ new Map(),
407
- time: Date.now(),
408
- token
409
- };
410
- store.logger.info(
411
- `\u2B55`,
412
- token.type,
413
- token.key,
414
- `operation start in store "${store.config.name}"${!isChildStore(store) ? `` : ` ${store.transactionMeta.phase} "${store.transactionMeta.update.key}"`}`
415
- );
416
- };
417
- var closeOperation = (store) => {
418
- if (store.operation.open) {
419
- store.logger.info(
420
- `\u{1F534}`,
421
- store.operation.token.type,
422
- store.operation.token.key,
423
- `operation done in store "${store.config.name}"`
424
- );
425
- }
426
- store.operation = { open: false };
427
- store.on.operationClose.next(store.operation);
428
- };
429
- var isDone = (store, key) => {
430
- if (!store.operation.open) {
431
- store.logger.error(
432
- `\u{1F41E}`,
433
- `unknown`,
434
- key,
435
- `isDone called outside of an operation. This is probably a bug in AtomIO.`
436
- );
437
- return true;
438
- }
439
- return store.operation.done.has(key);
440
- };
441
- var markDone = (store, key) => {
442
- if (!store.operation.open) {
443
- store.logger.error(
444
- `\u{1F41E}`,
445
- `unknown`,
446
- key,
447
- `markDone called outside of an operation. This is probably a bug in AtomIO.`
448
- );
449
- return;
450
- }
451
- store.operation.done.add(key);
452
- };
453
-
454
- // internal/src/set-state/emit-update.ts
455
- var emitUpdate = (store, state, update) => {
456
- switch (state.type) {
457
- case `mutable_atom`:
458
- store.logger.info(
459
- `\u{1F4E2}`,
460
- state.type,
461
- state.key,
462
- `is now (`,
463
- update.newValue,
464
- `) subscribers:`,
465
- state.subject.subscribers
466
- );
467
- break;
468
- case `atom`:
469
- case `selector`:
470
- case `readonly_selector`:
471
- store.logger.info(
472
- `\u{1F4E2}`,
473
- state.type,
474
- state.key,
475
- `went (`,
476
- update.oldValue,
477
- `->`,
478
- update.newValue,
479
- `) subscribers:`,
480
- state.subject.subscribers
481
- );
482
- }
483
- state.subject.next(update);
484
- };
485
-
486
- // internal/src/set-state/evict-downstream.ts
487
- var evictDownStream = (store, atom2) => {
488
- const target = newest(store);
489
- const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom2.key);
490
- target.logger.info(
491
- `\u{1F9F9}`,
492
- atom2.type,
493
- atom2.key,
494
- downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`,
495
- downstreamKeys ?? `to evict`
496
- );
497
- if (downstreamKeys) {
498
- if (target.operation.open) {
499
- target.logger.info(
500
- `\u{1F9F9}`,
501
- atom2.type,
502
- atom2.key,
503
- `[ ${[...target.operation.done].join(`, `)} ] already done`
504
- );
505
- }
506
- for (const key of downstreamKeys) {
507
- if (isDone(target, key)) {
508
- continue;
509
- }
510
- evictCachedValue(key, target);
511
- markDone(target, key);
512
- }
513
- }
514
- };
515
-
516
- // internal/src/set-state/set-atom.ts
517
- var setAtom = (target, atom2, next) => {
518
- const oldValue = readOrComputeValue(target, atom2);
519
- let newValue = oldValue;
520
- if (atom2.type === `mutable_atom` && isChildStore(target)) {
521
- const { parent } = target;
522
- const copiedValue = copyMutableIfNeeded(target, atom2, parent);
523
- newValue = copiedValue;
524
- }
525
- newValue = become(next)(newValue);
526
- target.logger.info(`\u{1F4DD}`, `atom`, atom2.key, `set to`, newValue);
527
- newValue = cacheValue(target, atom2.key, newValue, atom2.subject);
528
- if (isAtomDefault(target, atom2.key)) {
529
- markAtomAsNotDefault(target, atom2.key);
530
- }
531
- markDone(target, atom2.key);
532
- evictDownStream(target, atom2);
533
- const update = { oldValue, newValue };
534
- if (!isChildStore(target)) {
535
- emitUpdate(target, atom2, update);
536
- return;
537
- }
538
- if (target.on.transactionApplying.state === null) {
539
- const { key } = atom2;
540
- if (isTransceiver(update.newValue)) {
541
- return;
542
- }
543
- const atomUpdate = {
544
- type: `atom_update`,
545
- key,
546
- ...update
547
- };
548
- if (atom2.family) {
549
- atomUpdate.family = atom2.family;
550
- }
551
- target.transactionMeta.update.updates.push(atomUpdate);
552
- target.logger.info(
553
- `\u{1F4C1}`,
554
- `atom`,
555
- key,
556
- `stowed (`,
557
- update.oldValue,
558
- `->`,
559
- update.newValue,
560
- `)`
561
- );
562
- } else if (atom2.key.startsWith(`*`)) {
563
- const mutableKey = atom2.key.slice(1);
564
- const mutableAtom = target.atoms.get(mutableKey);
565
- let transceiver = target.valueMap.get(mutableKey);
566
- if (mutableAtom.type === `mutable_atom` && isChildStore(target)) {
567
- const { parent } = target;
568
- const copiedValue = copyMutableIfNeeded(target, mutableAtom, parent);
569
- transceiver = copiedValue;
570
- }
571
- const accepted = transceiver.do(update.newValue) === null;
572
- if (accepted) evictDownStream(target, mutableAtom);
573
- }
574
- };
575
-
576
- // internal/src/set-state/set-atom-or-selector.ts
577
- var setAtomOrSelector = (store, state, value) => {
578
- switch (state.type) {
579
- case `atom`:
580
- case `mutable_atom`:
581
- setAtom(store, state, value);
582
- break;
583
- case `selector`:
584
- state.set(value);
585
- break;
586
- }
587
- };
588
-
589
- // internal/src/subject.ts
590
- var Subject = class {
591
- Subscriber;
592
- subscribers = /* @__PURE__ */ new Map();
593
- subscribe(key, subscriber) {
594
- this.subscribers.set(key, subscriber);
595
- const unsubscribe = () => {
596
- this.unsubscribe(key);
597
- };
598
- return unsubscribe;
599
- }
600
- unsubscribe(key) {
601
- this.subscribers.delete(key);
602
- }
603
- next(value) {
604
- const subscribers = this.subscribers.values();
605
- for (const subscriber of subscribers) {
606
- subscriber(value);
607
- }
608
- }
609
- };
610
- var StatefulSubject = class extends Subject {
611
- state;
612
- constructor(initialState) {
613
- super();
614
- this.state = initialState;
615
- }
616
- next(value) {
617
- this.state = value;
618
- super.next(value);
619
- }
620
- };
621
-
622
- // internal/src/families/create-regular-atom-family.ts
623
- function createRegularAtomFamily(store, options, internalRoles) {
624
- const familyToken = {
625
- key: options.key,
626
- type: `atom_family`
627
- };
628
- const existing = store.families.get(options.key);
629
- if (existing) {
630
- store.logger.error(
631
- `\u2757`,
632
- `atom_family`,
633
- options.key,
634
- `Overwriting an existing ${prettyPrintTokenType(
635
- existing
636
- )} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`
637
- );
638
- }
639
- const subject = new Subject();
640
- const familyFunction = (key) => {
641
- const subKey = stringifyJson(key);
642
- const family = { key: options.key, subKey };
643
- const fullKey = `${options.key}(${subKey})`;
644
- const target = newest(store);
645
- const def = options.default;
646
- const individualOptions = {
647
- key: fullKey,
648
- default: def instanceof Function ? def(key) : def
649
- };
650
- if (options.effects) {
651
- individualOptions.effects = options.effects(key);
652
- }
653
- const token = createRegularAtom(target, individualOptions, family);
654
- subject.next({ type: `state_creation`, token });
655
- return token;
656
- };
657
- const atomFamily2 = Object.assign(familyFunction, familyToken, {
658
- subject,
659
- install: (s) => createRegularAtomFamily(s, options),
660
- internalRoles
661
- });
662
- store.families.set(options.key, atomFamily2);
663
- store.defaults.set(options.key, options.default);
664
- return familyToken;
665
- }
666
-
667
- // internal/src/families/create-atom-family.ts
668
- function createAtomFamily(store, options) {
669
- const isMutable = `mutable` in options;
670
- if (isMutable) {
671
- return createMutableAtomFamily(store, options);
672
- }
673
- return createRegularAtomFamily(store, options);
674
- }
675
-
676
- // internal/src/keys.ts
677
- var isAtomKey = (store, key) => newest(store).atoms.has(key);
678
- var isSelectorKey = (store, key) => newest(store).selectors.has(key);
679
- var isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
680
- var isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
681
-
682
- // internal/src/selector/get-selector-dependency-keys.ts
683
- var getSelectorDependencyKeys = (key, store) => {
684
- const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(store, source));
685
- return sources;
686
- };
687
-
688
- // internal/src/selector/trace-selector-atoms.ts
689
- var traceSelectorAtoms = (directDependencyKey, covered, store) => {
690
- const rootKeys = [];
691
- const indirectDependencyKeys = getSelectorDependencyKeys(
692
- directDependencyKey,
693
- store
694
- );
695
- while (indirectDependencyKeys.length > 0) {
696
- const indirectDependencyKey = indirectDependencyKeys.shift();
697
- if (covered.has(indirectDependencyKey)) {
698
- continue;
699
- }
700
- covered.add(indirectDependencyKey);
701
- if (!isAtomKey(store, indirectDependencyKey)) {
702
- indirectDependencyKeys.push(
703
- ...getSelectorDependencyKeys(indirectDependencyKey, store)
704
- );
705
- } else if (!rootKeys.includes(indirectDependencyKey)) {
706
- rootKeys.push(indirectDependencyKey);
707
- }
708
- }
709
- return rootKeys;
710
- };
711
- var traceAllSelectorAtoms = (selector2, store) => {
712
- const selectorKey = selector2.key;
713
- const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
714
- const covered = /* @__PURE__ */ new Set();
715
- return directDependencyKeys.flatMap(
716
- (depKey) => isAtomKey(store, depKey) ? depKey : traceSelectorAtoms(depKey, covered, store)
717
- );
718
- };
719
-
720
- // internal/src/selector/update-selector-atoms.ts
721
- var updateSelectorAtoms = (selectorKey, dependency, covered, store) => {
722
- const target = newest(store);
723
- if (dependency.type === `atom` || dependency.type === `mutable_atom`) {
724
- target.selectorAtoms.set({
725
- selectorKey,
726
- atomKey: dependency.key
727
- });
728
- store.logger.info(
729
- `\u{1F50D}`,
730
- `selector`,
731
- selectorKey,
732
- `discovers root atom "${dependency.key}"`
733
- );
734
- } else {
735
- const rootKeys = traceSelectorAtoms(dependency.key, covered, store);
736
- store.logger.info(
737
- `\u{1F50D}`,
738
- `selector`,
739
- selectorKey,
740
- `discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
741
- );
742
- for (const atomKey of rootKeys) {
743
- target.selectorAtoms = target.selectorAtoms.set({
744
- selectorKey,
745
- atomKey
746
- });
747
- }
748
- }
749
- covered.add(dependency.key);
750
- };
751
-
752
- // internal/src/selector/register-selector.ts
753
- var registerSelector = (selectorKey, covered, store) => ({
754
- get: (...params) => {
755
- const target = newest(store);
756
- let dependency;
757
- if (params.length === 2) {
758
- const [family, key] = params;
759
- dependency = findInStore(store, family, key);
760
- } else {
761
- [dependency] = params;
762
- }
763
- const dependencyState = withdraw(store, dependency);
764
- const dependencyValue = readOrComputeValue(store, dependencyState);
765
- store.logger.info(
766
- `\u{1F50C}`,
767
- `selector`,
768
- selectorKey,
769
- `registers dependency ( "${dependency.key}" =`,
770
- dependencyValue,
771
- `)`
772
- );
773
- target.selectorGraph.set(
774
- {
775
- upstreamSelectorKey: dependency.key,
776
- downstreamSelectorKey: selectorKey
777
- },
778
- {
779
- source: dependency.key
780
- }
781
- );
782
- updateSelectorAtoms(selectorKey, dependency, covered, store);
783
- return dependencyValue;
784
- },
785
- set: (...params) => {
786
- let token;
787
- let value;
788
- if (params.length === 2) {
789
- token = params[0];
790
- value = params[1];
791
- } else {
792
- const family = params[0];
793
- const key = params[1];
794
- value = params[2];
795
- token = findInStore(store, family, key);
796
- }
797
- const target = newest(store);
798
- const state = withdraw(target, token);
799
- setAtomOrSelector(target, state, value);
800
- },
801
- find: (token, key) => findInStore(store, token, key),
802
- json: (token) => getJsonToken(store, token)
803
- });
804
-
805
- // internal/src/selector/create-readonly-selector.ts
806
- var createReadonlySelector = (store, options, family) => {
807
- const target = newest(store);
808
- const subject = new Subject();
809
- const covered = /* @__PURE__ */ new Set();
810
- const { get, find, json } = registerSelector(options.key, covered, target);
811
- const getSelf = () => {
812
- const value = options.get({ get, find, json });
813
- cacheValue(newest(store), options.key, value, subject);
814
- covered.clear();
815
- return value;
816
- };
817
- const readonlySelector = {
818
- ...options,
819
- subject,
820
- install: (s) => createReadonlySelector(s, options, family),
821
- get: getSelf,
822
- type: `readonly_selector`,
823
- ...family && { family }
824
- };
825
- target.readonlySelectors.set(options.key, readonlySelector);
826
- const initialValue = getSelf();
827
- store.logger.info(
828
- `\u2728`,
829
- readonlySelector.type,
830
- readonlySelector.key,
831
- `=`,
832
- initialValue
833
- );
834
- const token = {
835
- key: options.key,
836
- type: `readonly_selector`
837
- };
838
- if (family) {
839
- token.family = family;
840
- }
841
- return token;
842
- };
843
-
844
- // internal/src/selector/create-writable-selector.ts
845
- var createWritableSelector = (store, options, family) => {
846
- const target = newest(store);
847
- const subject = new Subject();
848
- const covered = /* @__PURE__ */ new Set();
849
- const setterToolkit = registerSelector(options.key, covered, target);
850
- const { find, get, json } = setterToolkit;
851
- const getterToolkit = { find, get, json };
852
- const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
853
- const value = getFn(getterToolkit);
854
- cacheValue(innerTarget, options.key, value, subject);
855
- covered.clear();
856
- return value;
857
- };
858
- const setSelf = (next) => {
859
- const innerTarget = newest(store);
860
- const oldValue = getSelf(options.get, innerTarget);
861
- const newValue = become(next)(oldValue);
862
- store.logger.info(
863
- `\u{1F4DD}`,
864
- `selector`,
865
- options.key,
866
- `set (`,
867
- oldValue,
868
- `->`,
869
- newValue,
870
- `)`
871
- );
872
- cacheValue(innerTarget, options.key, newValue, subject);
873
- markDone(innerTarget, options.key);
874
- if (isRootStore(innerTarget)) {
875
- subject.next({ newValue, oldValue });
876
- }
877
- options.set(setterToolkit, newValue);
878
- };
879
- const mySelector = {
880
- ...options,
881
- subject,
882
- install: (s) => createWritableSelector(s, options, family),
883
- get: getSelf,
884
- set: setSelf,
885
- type: `selector`,
886
- ...family && { family }
887
- };
888
- target.selectors.set(options.key, mySelector);
889
- const initialValue = getSelf();
890
- store.logger.info(`\u2728`, mySelector.type, mySelector.key, `=`, initialValue);
891
- const token = {
892
- key: options.key,
893
- type: `selector`
894
- };
895
- if (family) {
896
- token.family = family;
897
- }
898
- return token;
899
- };
900
-
901
- // internal/src/selector/create-standalone-selector.ts
902
- function createStandaloneSelector(store, options) {
903
- const isWritable = `set` in options;
904
- if (isWritable) {
905
- const state2 = createWritableSelector(store, options, void 0);
906
- store.on.selectorCreation.next(state2);
907
- return state2;
908
- }
909
- const state = createReadonlySelector(store, options, void 0);
910
- store.on.selectorCreation.next(state);
911
- return state;
912
- }
913
-
914
- // internal/src/selector/dispose-selector.ts
915
- function disposeSelector(store, selectorToken) {
916
- const target = newest(store);
917
- const { key } = selectorToken;
918
- const selector2 = withdraw(target, selectorToken);
919
- if (!selector2.family) {
920
- store.logger.error(
921
- `\u274C`,
922
- `selector`,
923
- key,
924
- `Standalone selectors cannot be disposed.`
925
- );
926
- } else {
927
- const molecule = target.molecules.get(selector2.family.subKey);
928
- if (molecule) {
929
- target.moleculeData.delete(selector2.family.subKey, selector2.family.key);
930
- }
931
- let familyToken;
932
- switch (selectorToken.type) {
933
- case `selector`:
934
- {
935
- target.selectors.delete(key);
936
- familyToken = {
937
- key: selector2.family.key,
938
- type: `selector_family`
939
- };
940
- const family = withdraw(store, familyToken);
941
- family.subject.next({
942
- type: `state_disposal`,
943
- subType: `selector`,
944
- token: selectorToken
945
- });
946
- }
947
- break;
948
- case `readonly_selector`:
949
- {
950
- target.readonlySelectors.delete(key);
951
- familyToken = {
952
- key: selector2.family.key,
953
- type: `readonly_selector_family`
954
- };
955
- const family = withdraw(store, familyToken);
956
- family.subject.next({
957
- type: `state_disposal`,
958
- subType: `selector`,
959
- token: selectorToken
960
- });
961
- }
962
- break;
963
- }
964
- target.valueMap.delete(key);
965
- target.selectorAtoms.delete(key);
966
- target.selectorGraph.delete(key);
967
- store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
968
- if (isChildStore(target) && target.transactionMeta.phase === `building`) {
969
- target.transactionMeta.update.updates.push({
970
- type: `state_disposal`,
971
- subType: `selector`,
972
- token: selectorToken
973
- });
974
- } else {
975
- store.on.selectorDisposal.next(selectorToken);
976
- }
977
- }
978
- }
979
-
980
- // internal/src/families/create-readonly-selector-family.ts
981
- function createReadonlySelectorFamily(store, options, internalRoles) {
982
- const familyToken = {
983
- key: options.key,
984
- type: `readonly_selector_family`
985
- };
986
- const existing = store.families.get(options.key);
987
- if (existing) {
988
- store.logger.error(
989
- `\u2757`,
990
- `readonly_selector_family`,
991
- options.key,
992
- `Overwriting an existing ${prettyPrintTokenType(
993
- existing
994
- )} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`
995
- );
996
- }
997
- const subject = new Subject();
998
- const familyFunction = (key) => {
999
- const subKey = stringifyJson(key);
1000
- const family = { key: options.key, subKey };
1001
- const fullKey = `${options.key}(${subKey})`;
1002
- const target = newest(store);
1003
- const token = createReadonlySelector(
1004
- target,
1005
- {
1006
- key: fullKey,
1007
- get: options.get(key)
1008
- },
1009
- family
1010
- );
1011
- subject.next({ type: `state_creation`, token });
1012
- return token;
1013
- };
1014
- const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
1015
- internalRoles,
1016
- subject,
1017
- install: (s) => createReadonlySelectorFamily(s, options),
1018
- default: (key) => {
1019
- const getFn = options.get(key);
1020
- return getFn({
1021
- get: (...args) => getFromStore(store, ...args),
1022
- find: (...args) => findInStore(store, ...args),
1023
- json: (token) => getJsonToken(store, token)
1024
- });
1025
- }
1026
- });
1027
- store.families.set(options.key, readonlySelectorFamily);
1028
- return familyToken;
1029
- }
1030
-
1031
- // internal/src/families/create-writable-selector-family.ts
1032
- function createWritableSelectorFamily(store, options, internalRoles) {
1033
- const familyToken = {
1034
- key: options.key,
1035
- type: `selector_family`
1036
- };
1037
- const existing = store.families.get(options.key);
1038
- if (existing) {
1039
- store.logger.error(
1040
- `\u2757`,
1041
- `selector_family`,
1042
- options.key,
1043
- `Overwriting an existing ${prettyPrintTokenType(
1044
- existing
1045
- )} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`
1046
- );
1047
- }
1048
- const subject = new Subject();
1049
- const familyFunction = (key) => {
1050
- const subKey = stringifyJson(key);
1051
- const family = { key: options.key, subKey };
1052
- const fullKey = `${options.key}(${subKey})`;
1053
- const target = newest(store);
1054
- const token = createWritableSelector(
1055
- target,
1056
- {
1057
- key: fullKey,
1058
- get: options.get(key),
1059
- set: options.set(key)
1060
- },
1061
- family
1062
- );
1063
- subject.next({ type: `state_creation`, token });
1064
- return token;
1065
- };
1066
- const selectorFamily2 = Object.assign(familyFunction, familyToken, {
1067
- internalRoles,
1068
- subject,
1069
- install: (s) => createWritableSelectorFamily(s, options),
1070
- default: (key) => {
1071
- const getFn = options.get(key);
1072
- return getFn({
1073
- get: (...ps) => getFromStore(store, ...ps),
1074
- find: (token, k) => findInStore(store, token, k),
1075
- json: (token) => getJsonToken(store, token)
1076
- });
1077
- }
1078
- });
1079
- store.families.set(options.key, selectorFamily2);
1080
- return familyToken;
1081
- }
1082
-
1083
- // internal/src/families/create-selector-family.ts
1084
- function createSelectorFamily(store, options) {
1085
- const isWritable = `set` in options;
1086
- if (isWritable) {
1087
- return createWritableSelectorFamily(store, options);
1088
- }
1089
- return createReadonlySelectorFamily(store, options);
1090
- }
1091
-
1092
- // internal/src/families/init-family-member.ts
1093
- function initFamilyMemberInStore(store, token, key) {
1094
- const family = store.families.get(token.key);
1095
- if (family === void 0) {
1096
- throw new NotFoundError(token, store);
1097
- }
1098
- const state = family(key);
1099
- const target = newest(store);
1100
- if (state.family) {
1101
- if (isRootStore(target)) {
1102
- switch (state.type) {
1103
- case `atom`:
1104
- case `mutable_atom`:
1105
- store.on.atomCreation.next(state);
1106
- break;
1107
- case `selector`:
1108
- case `readonly_selector`:
1109
- store.on.selectorCreation.next(state);
1110
- break;
1111
- }
1112
- } else if (isChildStore(target) && target.on.transactionApplying.state === null) {
1113
- target.transactionMeta.update.updates.push({
1114
- type: `state_creation`,
1115
- token: state
1116
- });
1117
- }
1118
- }
1119
- return state;
1120
- }
1121
-
1122
- // internal/src/families/seek-in-store.ts
1123
- function seekInStore(store, token, key) {
1124
- const subKey = stringifyJson(key);
1125
- const fullKey = `${token.key}(${subKey})`;
1126
- const target = newest(store);
1127
- let state;
1128
- switch (token.type) {
1129
- case `atom_family`:
1130
- case `mutable_atom_family`:
1131
- state = target.atoms.get(fullKey);
1132
- break;
1133
- case `selector_family`:
1134
- state = target.selectors.get(fullKey);
1135
- break;
1136
- case `readonly_selector_family`:
1137
- state = target.readonlySelectors.get(fullKey);
1138
- break;
1139
- }
1140
- if (state) {
1141
- return deposit(state);
1142
- }
1143
- return state;
1144
- }
1145
-
1146
- // internal/src/families/find-in-store.ts
1147
- function findInStore(store, token, key) {
1148
- let state = seekInStore(store, token, key);
1149
- if (state) {
1150
- return state;
1151
- }
1152
- const stringKey = stringifyJson(key);
1153
- const molecule = store.molecules.get(stringKey);
1154
- if (!molecule && store.config.lifespan === `immortal`) {
1155
- const fakeToken = counterfeit(token, key);
1156
- store.logger.error(
1157
- `\u274C`,
1158
- fakeToken.type,
1159
- fakeToken.key,
1160
- `was not found in store "${store.config.name}"; returned a counterfeit token.`
1161
- );
1162
- return fakeToken;
1163
- }
1164
- state = initFamilyMemberInStore(store, token, key);
1165
- if (molecule) {
1166
- const target = newest(store);
1167
- target.moleculeData.set(stringKey, token.key);
1168
- }
1169
- return state;
1170
- }
1171
-
1172
- // internal/src/families/dispose-from-store.ts
1173
- function disposeFromStore(store, ...params) {
1174
- let token;
1175
- if (params.length === 1) {
1176
- token = params[0];
1177
- } else {
1178
- const family = params[0];
1179
- const key = params[1];
1180
- const maybeToken = findInStore(store, family, key);
1181
- token = maybeToken;
1182
- }
1183
- try {
1184
- withdraw(store, token);
1185
- } catch (thrown) {
1186
- store.logger.error(
1187
- `\u274C`,
1188
- token.type,
1189
- token.key,
1190
- `could not be disposed because it was not found in the store "${store.config.name}".`
1191
- );
1192
- return;
1193
- }
1194
- switch (token.type) {
1195
- case `atom`:
1196
- case `mutable_atom`:
1197
- disposeAtom(store, token);
1198
- break;
1199
- case `selector`:
1200
- case `readonly_selector`:
1201
- disposeSelector(store, token);
1202
- break;
1203
- }
1204
- }
1205
-
1206
- // internal/src/families/get-family-of-token.ts
1207
- function getFamilyOfToken(store, token) {
1208
- if (token.family) {
1209
- const family = store.families.get(token.family.key);
1210
- if (family) {
1211
- return family;
1212
- }
1213
- }
1214
- }
1215
-
1216
- // internal/src/set-state/set-into-store.ts
1217
- function setIntoStore(store, ...params) {
1218
- let token;
1219
- let family;
1220
- let key;
1221
- let value;
1222
- if (params.length === 2) {
1223
- token = params[0];
1224
- value = params[1];
1225
- family = getFamilyOfToken(store, token) ?? null;
1226
- if (family) {
1227
- key = token.family ? parseJson(token.family.subKey) : null;
1228
- token = findInStore(store, family, key);
1229
- }
1230
- } else {
1231
- family = params[0];
1232
- key = params[1];
1233
- value = params[2];
1234
- token = findInStore(store, family, key);
1235
- }
1236
- if (`counterfeit` in token && `family` in token) {
1237
- const subKey = token.family.subKey;
1238
- const disposal = store.disposalTraces.buffer.find(
1239
- (item) => item?.key === subKey
1240
- );
1241
- store.logger.error(
1242
- `\u274C`,
1243
- token.type,
1244
- token.key,
1245
- `could not be set because it was not found in the store "${store.config.name}".`,
1246
- disposal ? `This state was previously disposed:
1247
- ${disposal.trace}` : `No previous disposal trace was found.`
1248
- );
1249
- return;
1250
- }
1251
- const rejectionTime = openOperation(store, token);
1252
- if (rejectionTime) {
1253
- const unsubscribe = store.on.operationClose.subscribe(
1254
- `waiting to set "${token.key}" at T-${rejectionTime}`,
1255
- () => {
1256
- unsubscribe();
1257
- store.logger.info(
1258
- `\u{1F7E2}`,
1259
- token.type,
1260
- token.key,
1261
- `resuming deferred setState from T-${rejectionTime}`
1262
- );
1263
- setIntoStore(store, token, value);
1264
- }
1265
- );
1266
- return;
1267
- }
1268
- const state = withdraw(store, token);
1269
- setAtomOrSelector(store, state, value);
1270
- closeOperation(store);
1271
- }
1272
-
1273
- // internal/src/ingest-updates/ingest-atom-update.ts
1274
- function ingestAtomUpdate(applying, atomUpdate, store) {
1275
- const { key, newValue, oldValue } = atomUpdate;
1276
- const value = applying === `newValue` ? newValue : oldValue;
1277
- const token = { key, type: `atom` };
1278
- if (atomUpdate.family) {
1279
- Object.assign(token, { family: atomUpdate.family });
1280
- }
1281
- setIntoStore(store, token, value);
1282
- }
1283
-
1284
- // internal/src/get-trace.ts
1285
- function getTrace(error) {
1286
- const { stack } = error;
1287
- if (stack) {
1288
- return `
1289
- ` + stack.split(`
1290
- `)?.slice(1)?.join(`
1291
- `);
1292
- }
1293
- return ``;
1294
- }
1295
-
1296
- // internal/src/molecule.ts
1297
- function makeRootMoleculeInStore(key, store = IMPLICIT.STORE) {
1298
- const molecule = {
1299
- key,
1300
- stringKey: stringifyJson(key),
1301
- dependsOn: `any`
1302
- };
1303
- store.molecules.set(stringifyJson(key), molecule);
1304
- return key;
1305
- }
1306
- function allocateIntoStore(store, provenance, key, dependsOn = `any`) {
1307
- const origin = provenance;
1308
- const stringKey = stringifyJson(key);
1309
- const invalidKeys = [];
1310
- const target = newest(store);
1311
- if (Array.isArray(origin)) {
1312
- for (const formerClaim of origin) {
1313
- const claimString = stringifyJson(formerClaim);
1314
- const claim = target.molecules.get(claimString);
1315
- if (claim) {
1316
- store.moleculeGraph.set(claimString, stringKey, { source: claimString });
1317
- } else {
1318
- invalidKeys.push(claimString);
1319
- }
1320
- }
1321
- } else {
1322
- const claimString = stringifyJson(origin);
1323
- const claim = target.molecules.get(claimString);
1324
- if (claim) {
1325
- store.moleculeGraph.set(claimString, stringKey, { source: claimString });
1326
- } else {
1327
- invalidKeys.push(claimString);
1328
- }
1329
- }
1330
- if (invalidKeys.length === 0) {
1331
- target.molecules.set(stringKey, { key, stringKey, dependsOn });
1332
- }
1333
- const creationEvent = {
1334
- type: `molecule_creation`,
1335
- key,
1336
- provenance: origin
1337
- };
1338
- const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1339
- if (isTransaction) {
1340
- target.transactionMeta.update.updates.push(creationEvent);
1341
- } else {
1342
- target.on.moleculeCreation.next(creationEvent);
1343
- }
1344
- for (const claim of invalidKeys) {
1345
- const disposal = store.disposalTraces.buffer.find(
1346
- (item) => item?.key === claim
1347
- );
1348
- store.logger.error(
1349
- `\u274C`,
1350
- `molecule`,
1351
- key,
1352
- `allocation failed:`,
1353
- `Could not allocate to ${claim} in store "${store.config.name}".`,
1354
- disposal ? `
1355
- ${claim} was most recently disposed
1356
- ${disposal.trace}` : `No previous disposal trace for ${claim} was found.`
1357
- );
1358
- }
1359
- return key;
1360
- }
1361
- function fuseWithinStore(store, type, sideA, sideB) {
1362
- const compoundKey = `T$--${type}==${sideA}++${sideB}`;
1363
- const above = [sideA, sideB];
1364
- allocateIntoStore(
1365
- store,
1366
- above,
1367
- compoundKey,
1368
- `all`
1369
- );
1370
- return compoundKey;
1371
- }
1372
- function deallocateFromStore(store, claim) {
1373
- const stringKey = stringifyJson(claim);
1374
- const molecule = store.molecules.get(stringKey);
1375
- if (!molecule) {
1376
- const disposal = store.disposalTraces.buffer.find(
1377
- (item) => item?.key === stringKey
1378
- );
1379
- store.logger.error(
1380
- `\u274C`,
1381
- `molecule`,
1382
- claim,
1383
- `deallocation failed:`,
1384
- `Could not find allocation for ${stringKey} in store "${store.config.name}".`,
1385
- disposal ? `
1386
- This state was most recently deallocated
1387
- ${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`
1388
- );
1389
- return;
1390
- }
1391
- const joinKeys = store.moleculeJoins.getRelatedKeys(
1392
- molecule.key
1393
- );
1394
- if (joinKeys) {
1395
- for (const joinKey of joinKeys) {
1396
- const join2 = store.joins.get(joinKey);
1397
- if (join2) {
1398
- join2.relations.delete(molecule.key);
1399
- join2.molecules.delete(molecule.stringKey);
1400
- }
1401
- }
1402
- }
1403
- store.moleculeJoins.delete(molecule.stringKey);
1404
- const provenance = [];
1405
- const values = [];
1406
- const disposalEvent = {
1407
- type: `molecule_disposal`,
1408
- key: molecule.key,
1409
- values,
1410
- provenance
1411
- };
1412
- const target = newest(store);
1413
- target.molecules.delete(stringKey);
1414
- const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1415
- if (isTransaction) {
1416
- target.transactionMeta.update.updates.push(disposalEvent);
1417
- }
1418
- const relatedMolecules = store.moleculeGraph.getRelationEntries({
1419
- downstreamMoleculeKey: molecule.stringKey
1420
- });
1421
- if (relatedMolecules) {
1422
- for (const [relatedStringKey, { source }] of relatedMolecules) {
1423
- if (source === molecule.stringKey) {
1424
- const relatedKey = parseJson(relatedStringKey);
1425
- deallocateFromStore(store, relatedKey);
1426
- } else {
1427
- provenance.push(source);
1428
- }
1429
- }
1430
- }
1431
- const familyKeys = target.moleculeData.getRelatedKeys(molecule.stringKey);
1432
- if (familyKeys) {
1433
- for (const familyKey of familyKeys) {
1434
- const family = target.families.get(familyKey);
1435
- const token = findInStore(store, family, molecule.key);
1436
- values.push([family.key, token]);
1437
- disposeFromStore(store, token);
1438
- }
1439
- }
1440
- target.moleculeGraph.delete(molecule.stringKey);
1441
- target.moleculeJoins.delete(molecule.stringKey);
1442
- target.moleculeData.delete(molecule.stringKey);
1443
- if (!isTransaction) {
1444
- target.on.moleculeDisposal.next(disposalEvent);
1445
- }
1446
- target.molecules.delete(molecule.stringKey);
1447
- const trace = getTrace(new Error());
1448
- store.disposalTraces.add({ key: stringKey, trace });
1449
- }
1450
- function claimWithinStore(store, newProvenance, claim, exclusive) {
1451
- const stringKey = stringifyJson(claim);
1452
- const target = newest(store);
1453
- const molecule = target.molecules.get(stringKey);
1454
- if (!molecule) {
1455
- const disposal = store.disposalTraces.buffer.find(
1456
- (item) => item?.key === stringKey
1457
- );
1458
- store.logger.error(
1459
- `\u274C`,
1460
- `molecule`,
1461
- claim,
1462
- `claim failed:`,
1463
- `Could not allocate to ${stringKey} in store "${store.config.name}".`,
1464
- disposal ? `
1465
- ${stringKey} was most recently disposed
1466
- ${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`
1467
- );
1468
- return claim;
1469
- }
1470
- const newProvenanceKey = stringifyJson(newProvenance);
1471
- const newProvenanceMolecule = target.molecules.get(newProvenanceKey);
1472
- if (!newProvenanceMolecule) {
1473
- const disposal = store.disposalTraces.buffer.find(
1474
- (item) => item?.key === newProvenanceKey
1475
- );
1476
- store.logger.error(
1477
- `\u274C`,
1478
- `molecule`,
1479
- claim,
1480
- `claim failed:`,
1481
- `Could not allocate to ${newProvenanceKey} in store "${store.config.name}".`,
1482
- disposal ? `
1483
- ${newProvenanceKey} was most recently disposed
1484
- ${disposal.trace}` : `No previous disposal trace for ${newProvenanceKey} was found.`
1485
- );
1486
- return claim;
1487
- }
1488
- const priorProvenance = store.moleculeGraph.getRelationEntries({
1489
- downstreamMoleculeKey: molecule.stringKey
1490
- }).filter(([, { source }]) => source !== stringKey).map(([key]) => parseJson(key));
1491
- if (exclusive) {
1492
- target.moleculeGraph.delete(stringKey);
1493
- }
1494
- target.moleculeGraph.set(
1495
- {
1496
- upstreamMoleculeKey: newProvenanceMolecule.stringKey,
1497
- downstreamMoleculeKey: molecule.stringKey
1498
- },
1499
- {
1500
- source: newProvenanceMolecule.stringKey
1501
- }
1502
- );
1503
- const transferEvent = {
1504
- type: `molecule_transfer`,
1505
- key: molecule.key,
1506
- from: priorProvenance,
1507
- to: [newProvenanceMolecule.key]
1508
- };
1509
- const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1510
- if (isTransaction) {
1511
- target.transactionMeta.update.updates.push(transferEvent);
1512
- }
1513
- return claim;
1514
- }
1515
-
1516
- // internal/src/ingest-updates/ingest-creation-disposal.ts
1517
- function ingestCreationEvent(update, applying, store) {
1518
- switch (applying) {
1519
- case `newValue`: {
1520
- createInStore(update, store);
1521
- break;
1522
- }
1523
- case `oldValue`: {
1524
- disposeFromStore(store, update.token);
1525
- break;
1526
- }
1527
- }
1528
- }
1529
- function ingestDisposalEvent(update, applying, store) {
1530
- switch (applying) {
1531
- case `newValue`: {
1532
- disposeFromStore(store, update.token);
1533
- break;
1534
- }
1535
- case `oldValue`: {
1536
- createInStore(update, store);
1537
- if (update.subType === `atom`) {
1538
- store.valueMap.set(update.token.key, update.value);
1539
- }
1540
- break;
1541
- }
1542
- }
1543
- }
1544
- function createInStore(update, store) {
1545
- const { family: familyMeta } = update.token;
1546
- if (familyMeta) {
1547
- const family = store.families.get(familyMeta.key);
1548
- if (family) {
1549
- findInStore(store, family, parseJson(familyMeta.subKey));
1550
- }
1551
- }
1552
- }
1553
- function ingestMoleculeCreationEvent(update, applying, store) {
1554
- switch (applying) {
1555
- case `newValue`:
1556
- allocateIntoStore(store, update.provenance, update.key);
1557
- break;
1558
- case `oldValue`:
1559
- deallocateFromStore(store, update.key);
1560
- break;
1561
- }
1562
- }
1563
- function ingestMoleculeDisposalEvent(update, applying, store) {
1564
- switch (applying) {
1565
- case `newValue`:
1566
- deallocateFromStore(store, update.key);
1567
- break;
1568
- case `oldValue`:
1569
- {
1570
- const provenanceJson = update.provenance.map(parseJson);
1571
- allocateIntoStore(store, provenanceJson, update.key);
1572
- for (const [familyKey, value] of update.values) {
1573
- const family = store.families.get(familyKey);
1574
- if (family) {
1575
- findInStore(store, family, update.key);
1576
- const memberKey = `${familyKey}(${stringifyJson(update.key)})`;
1577
- store.valueMap.set(memberKey, value);
1578
- }
1579
- }
1580
- }
1581
- break;
1582
- }
1583
- }
1584
- function ingestMoleculeTransferEvent(update, applying, store) {
1585
- switch (applying) {
1586
- case `newValue`:
1587
- {
1588
- const provenance = update.to.length === 1 ? update.to[0] : update.to;
1589
- claimWithinStore(
1590
- store,
1591
- provenance,
1592
- update.key,
1593
- `exclusive`
1594
- );
1595
- }
1596
- break;
1597
- case `oldValue`:
1598
- {
1599
- const provenance = update.from.length === 1 ? update.from[0] : update.from;
1600
- claimWithinStore(
1601
- store,
1602
- provenance,
1603
- update.key,
1604
- `exclusive`
1605
- );
1606
- }
1607
- break;
1608
- }
1609
- }
1610
-
1611
- // internal/src/ingest-updates/ingest-selector-update.ts
1612
- function ingestSelectorUpdate(applying, selectorUpdate, store) {
1613
- const updates = applying === `newValue` ? selectorUpdate.atomUpdates : selectorUpdate.atomUpdates.toReversed();
1614
- for (const atomUpdate of updates) {
1615
- ingestAtomUpdate(applying, atomUpdate, store);
1616
- }
1617
- }
1618
-
1619
- // internal/src/ingest-updates/ingest-transaction-update.ts
1620
- function ingestTransactionUpdate(applying, transactionUpdate, store) {
1621
- const updates = applying === `newValue` ? transactionUpdate.updates : [...transactionUpdate.updates].reverse();
1622
- for (const updateFromTransaction of updates) {
1623
- switch (updateFromTransaction.type) {
1624
- case `atom_update`:
1625
- case `selector_update`:
1626
- ingestAtomUpdate(applying, updateFromTransaction, store);
1627
- break;
1628
- case `state_creation`:
1629
- ingestCreationEvent(updateFromTransaction, applying, store);
1630
- break;
1631
- case `state_disposal`:
1632
- ingestDisposalEvent(updateFromTransaction, applying, store);
1633
- break;
1634
- case `molecule_creation`:
1635
- ingestMoleculeCreationEvent(updateFromTransaction, applying, store);
1636
- break;
1637
- case `molecule_disposal`:
1638
- ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
1639
- break;
1640
- case `molecule_transfer`:
1641
- ingestMoleculeTransferEvent(updateFromTransaction, applying, store);
1642
- break;
1643
- case `transaction_update`:
1644
- ingestTransactionUpdate(applying, updateFromTransaction, store);
1645
- break;
1646
- }
1647
- }
1648
- }
1649
-
1650
- // internal/src/transaction/get-epoch-number.ts
1651
- function getContinuityKey(store, transactionKey) {
1652
- const continuity = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
1653
- return continuity;
1654
- }
1655
- function getEpochNumberOfContinuity(store, continuityKey) {
1656
- const epoch = store.transactionMeta.epoch.get(continuityKey);
1657
- return epoch;
1658
- }
1659
- function getEpochNumberOfAction(store, transactionKey) {
1660
- const isRoot = isRootStore(store);
1661
- if (!isRoot) {
1662
- return void 0;
1663
- }
1664
- const continuityKey = getContinuityKey(store, transactionKey);
1665
- if (continuityKey === void 0) {
1666
- return void 0;
1667
- }
1668
- return getEpochNumberOfContinuity(store, continuityKey);
1669
- }
1670
-
1671
- // internal/src/transaction/set-epoch-number.ts
1672
- function setEpochNumberOfContinuity(store, continuityKey, newEpoch) {
1673
- const isRoot = isRootStore(store);
1674
- if (isRoot && continuityKey) {
1675
- store.transactionMeta.epoch.set(continuityKey, newEpoch);
1676
- }
1677
- }
1678
- function setEpochNumberOfAction(store, transactionKey, newEpoch) {
1679
- const isRoot = isRootStore(store);
1680
- if (!isRoot) {
1681
- return;
1682
- }
1683
- const continuityKey = getContinuityKey(store, transactionKey);
1684
- if (continuityKey !== void 0) {
1685
- store.transactionMeta.epoch.set(continuityKey, newEpoch);
1686
- }
1687
- }
1688
-
1689
- // internal/src/transaction/apply-transaction.ts
1690
- var applyTransaction = (output, store) => {
1691
- const child = newest(store);
1692
- const { parent } = child;
1693
- if (parent === null || !isChildStore(child) || child.transactionMeta?.phase !== `building`) {
1694
- store.logger.warn(
1695
- `\u{1F41E}`,
1696
- `transaction`,
1697
- `???`,
1698
- `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
1699
- );
1700
- return;
1701
- }
1702
- child.transactionMeta.phase = `applying`;
1703
- child.transactionMeta.update.output = output;
1704
- parent.child = null;
1705
- parent.on.transactionApplying.next(child.transactionMeta);
1706
- const { updates } = child.transactionMeta.update;
1707
- store.logger.info(
1708
- `\u{1F6C4}`,
1709
- `transaction`,
1710
- child.transactionMeta.update.key,
1711
- `Applying transaction with ${updates.length} updates:`,
1712
- updates
1713
- );
1714
- ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
1715
- if (isRootStore(parent)) {
1716
- setEpochNumberOfAction(
1717
- parent,
1718
- child.transactionMeta.update.key,
1719
- child.transactionMeta.update.epoch
1720
- );
1721
- const myTransaction = withdraw(store, {
1722
- key: child.transactionMeta.update.key,
1723
- type: `transaction`
1724
- });
1725
- myTransaction?.subject.next(child.transactionMeta.update);
1726
- store.logger.info(
1727
- `\u{1F6EC}`,
1728
- `transaction`,
1729
- child.transactionMeta.update.key,
1730
- `Finished applying transaction.`
1731
- );
1732
- } else if (isChildStore(parent)) {
1733
- parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1734
- }
1735
- parent.on.transactionApplying.next(null);
1736
- };
1737
-
1738
- // internal/src/transaction/assign-transaction-to-continuity.ts
1739
- function assignTransactionToContinuity(store, continuityKey, transactionKey) {
1740
- const isRoot = isRootStore(store);
1741
- if (!isRoot) {
1742
- return;
1743
- }
1744
- const { epoch, actionContinuities } = store.transactionMeta;
1745
- actionContinuities.set(continuityKey, transactionKey);
1746
- if (!epoch.has(continuityKey)) {
1747
- epoch.set(continuityKey, -1);
1748
- }
1749
- }
1750
-
1751
- // internal/src/get-environment-data.ts
1752
- function getEnvironmentData(store) {
1753
- return {
1754
- store
1755
- };
1756
- }
1757
-
1758
- // internal/src/get-state/get-from-store.ts
1759
- function getFromStore(store, ...params) {
1760
- let token;
1761
- let family;
1762
- let key;
1763
- if (params.length === 1) {
1764
- token = params[0];
1765
- } else {
1766
- family = params[0];
1767
- key = params[1];
1768
- token = findInStore(store, family, key);
1769
- }
1770
- if (`counterfeit` in token && `family` in token) {
1771
- family = store.families.get(token.family.key);
1772
- const subKey = token.family.subKey;
1773
- const disposal = store.disposalTraces.buffer.find(
1774
- (item) => item?.key === subKey
1775
- );
1776
- store.logger.error(
1777
- `\u274C`,
1778
- token.type,
1779
- token.key,
1780
- `could not be retrieved because it was not found in the store "${store.config.name}".`,
1781
- disposal ? `This state was previously disposed:
1782
- ${disposal.trace}` : `No previous disposal trace was found.`
1783
- );
1784
- switch (family.type) {
1785
- case `atom_family`:
1786
- case `mutable_atom_family`:
1787
- return store.defaults.get(family.key);
1788
- case `selector_family`:
1789
- case `readonly_selector_family`: {
1790
- if (store.defaults.has(family.key)) {
1791
- return store.defaults.get(token.family.key);
1792
- }
1793
- const defaultValue = withdraw(store, family).default(subKey);
1794
- store.defaults.set(family.key, defaultValue);
1795
- return defaultValue;
1796
- }
1797
- }
1798
- }
1799
- return readOrComputeValue(store, withdraw(store, token));
1800
- }
1801
-
1802
- // internal/src/junction.ts
1803
- var Junction = class {
1804
- a;
1805
- b;
1806
- cardinality;
1807
- relations = /* @__PURE__ */ new Map();
1808
- contents = /* @__PURE__ */ new Map();
1809
- isAType;
1810
- isBType;
1811
- isContent;
1812
- makeContentKey = (a, b) => `${a}:${b}`;
1813
- warn;
1814
- getRelatedKeys(key) {
1815
- return this.relations.get(key);
1816
- }
1817
- addRelation(a, b) {
1818
- let aRelations = this.relations.get(a);
1819
- let bRelations = this.relations.get(b);
1820
- if (aRelations) {
1821
- aRelations.add(b);
1822
- } else {
1823
- aRelations = /* @__PURE__ */ new Set([b]);
1824
- this.relations.set(a, aRelations);
1825
- }
1826
- if (bRelations) {
1827
- bRelations.add(a);
1828
- } else {
1829
- bRelations = /* @__PURE__ */ new Set([a]);
1830
- this.relations.set(b, bRelations);
1831
- }
1832
- }
1833
- deleteRelation(a, b) {
1834
- const aRelations = this.relations.get(a);
1835
- if (aRelations) {
1836
- aRelations.delete(b);
1837
- if (aRelations.size === 0) {
1838
- this.relations.delete(a);
1839
- }
1840
- const bRelations = this.relations.get(b);
1841
- if (bRelations) {
1842
- bRelations.delete(a);
1843
- if (bRelations.size === 0) {
1844
- this.relations.delete(b);
1845
- }
1846
- }
1847
- }
1848
- }
1849
- replaceRelationsUnsafely(x, ys) {
1850
- this.relations.set(x, new Set(ys));
1851
- for (const y of ys) {
1852
- const yRelations = (/* @__PURE__ */ new Set()).add(x);
1853
- this.relations.set(y, yRelations);
1854
- }
1855
- }
1856
- replaceRelationsSafely(x, ys) {
1857
- const xRelationsPrev = this.relations.get(x);
1858
- let a = this.isAType?.(x) ? x : void 0;
1859
- let b = a === void 0 ? x : void 0;
1860
- if (xRelationsPrev) {
1861
- for (const y of xRelationsPrev) {
1862
- a ??= y;
1863
- b ??= y;
1864
- const yRelations = this.relations.get(y);
1865
- if (yRelations) {
1866
- if (yRelations.size === 1) {
1867
- this.relations.delete(y);
1868
- } else {
1869
- yRelations.delete(x);
1870
- }
1871
- this.contents.delete(this.makeContentKey(a, b));
1872
- }
1873
- }
1874
- }
1875
- this.relations.set(x, new Set(ys));
1876
- for (const y of ys) {
1877
- let yRelations = this.relations.get(y);
1878
- if (yRelations) {
1879
- yRelations.add(x);
1880
- } else {
1881
- yRelations = (/* @__PURE__ */ new Set()).add(x);
1882
- this.relations.set(y, yRelations);
1883
- }
1884
- }
1885
- }
1886
- getContentInternal(contentKey) {
1887
- return this.contents.get(contentKey);
1888
- }
1889
- setContent(contentKey, content) {
1890
- this.contents.set(contentKey, content);
1891
- }
1892
- deleteContent(contentKey) {
1893
- this.contents.delete(contentKey);
1894
- }
1895
- constructor(data, config) {
1896
- this.a = data.between[0];
1897
- this.b = data.between[1];
1898
- this.cardinality = data.cardinality;
1899
- if (!config?.externalStore) {
1900
- this.relations = new Map(
1901
- data.relations?.map(([x, ys]) => [x, new Set(ys)])
1902
- );
1903
- this.contents = new Map(data.contents);
1904
- }
1905
- this.isAType = config?.isAType ?? null;
1906
- this.isBType = config?.isBType ?? null;
1907
- this.isContent = config?.isContent ?? null;
1908
- if (config?.makeContentKey) {
1909
- this.makeContentKey = config.makeContentKey;
1910
- }
1911
- if (config?.externalStore) {
1912
- const externalStore = config.externalStore;
1913
- this.has = (a, b) => externalStore.has(a, b);
1914
- this.addRelation = (a, b) => {
1915
- externalStore.addRelation(a, b);
1916
- };
1917
- this.deleteRelation = (a, b) => {
1918
- externalStore.deleteRelation(a, b);
1919
- };
1920
- this.replaceRelationsSafely = (a, bs) => {
1921
- externalStore.replaceRelationsSafely(a, bs);
1922
- };
1923
- this.replaceRelationsUnsafely = (a, bs) => {
1924
- externalStore.replaceRelationsUnsafely(a, bs);
1925
- };
1926
- this.getRelatedKeys = (key) => externalStore.getRelatedKeys(
1927
- key
1928
- );
1929
- if (externalStore.getContent) {
1930
- this.getContentInternal = (contentKey) => {
1931
- return externalStore.getContent(contentKey);
1932
- };
1933
- this.setContent = (contentKey, content) => {
1934
- externalStore.setContent(contentKey, content);
1935
- };
1936
- this.deleteContent = (contentKey) => {
1937
- externalStore.deleteContent(contentKey);
1938
- };
1939
- }
1940
- for (const [x, ys] of data.relations ?? []) {
1941
- let a = this.isAType?.(x) ? x : void 0;
1942
- let b = a === void 0 ? x : void 0;
1943
- for (const y of ys) {
1944
- a ??= y;
1945
- b ??= y;
1946
- this.addRelation(a, b);
1947
- }
1948
- }
1949
- for (const [contentKey, content] of data.contents ?? []) {
1950
- this.setContent(contentKey, content);
1951
- }
1952
- }
1953
- if (config?.warn) {
1954
- this.warn = config.warn;
1955
- }
1956
- }
1957
- toJSON() {
1958
- return {
1959
- between: [this.a, this.b],
1960
- cardinality: this.cardinality,
1961
- relations: [...this.relations.entries()].map(
1962
- ([a, b]) => [a, [...b]]
1963
- ),
1964
- contents: [...this.contents.entries()]
1965
- };
1966
- }
1967
- set(...params) {
1968
- let a;
1969
- let b;
1970
- let content;
1971
- switch (params.length) {
1972
- case 1: {
1973
- const relation = params[0];
1974
- a = relation[this.a];
1975
- b = relation[this.b];
1976
- content = void 0;
1977
- break;
1978
- }
1979
- case 2: {
1980
- const zeroth = params[0];
1981
- if (typeof zeroth === `string`) {
1982
- [a, b] = params;
1983
- } else {
1984
- a = zeroth[this.a];
1985
- b = zeroth[this.b];
1986
- content = params[1];
1987
- }
1988
- break;
1989
- }
1990
- default: {
1991
- a = params[0];
1992
- b = params[1];
1993
- content = params[2];
1994
- break;
1995
- }
1996
- }
1997
- switch (this.cardinality) {
1998
- // biome-ignore lint/suspicious/noFallthroughSwitchClause: perfect here
1999
- case `1:1`: {
2000
- const bPrev = this.getRelatedKey(a);
2001
- if (bPrev && bPrev !== b) this.delete(a, bPrev);
2002
- }
2003
- case `1:n`:
2004
- {
2005
- const aPrev = this.getRelatedKey(b);
2006
- if (aPrev && aPrev !== a) this.delete(aPrev, b);
2007
- }
2008
- break;
2009
- }
2010
- if (content) {
2011
- const contentKey = this.makeContentKey(a, b);
2012
- this.setContent(contentKey, content);
2013
- }
2014
- this.addRelation(a, b);
2015
- return this;
2016
- }
2017
- delete(x, b) {
2018
- b = typeof b === `string` ? b : x[this.b];
2019
- const a = (
2020
- // @ts-expect-error we deduce that this.a may index x
2021
- typeof x === `string` ? x : x[this.a]
2022
- );
2023
- if (a === void 0 && typeof b === `string`) {
2024
- const bRelations = this.getRelatedKeys(b);
2025
- if (bRelations) {
2026
- for (const bRelation of bRelations) {
2027
- this.delete(bRelation, b);
2028
- }
2029
- }
2030
- }
2031
- if (typeof a === `string` && b === void 0) {
2032
- const aRelations = this.getRelatedKeys(a);
2033
- if (aRelations) {
2034
- for (const aRelation of aRelations) {
2035
- this.delete(a, aRelation);
2036
- }
2037
- }
2038
- }
2039
- if (typeof a === `string` && typeof b === `string`) {
2040
- this.deleteRelation(a, b);
2041
- const contentKey = this.makeContentKey(a, b);
2042
- this.deleteContent(contentKey);
2043
- }
2044
- return this;
2045
- }
2046
- getRelatedKey(key) {
2047
- const relations = this.getRelatedKeys(key);
2048
- if (relations) {
2049
- if (relations.size > 1) {
2050
- this.warn?.(
2051
- `${relations.size} related keys were found for key "${key}": (${[
2052
- ...relations
2053
- ].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`
2054
- );
2055
- }
2056
- let singleRelation;
2057
- for (const relation of relations) {
2058
- singleRelation = relation;
2059
- break;
2060
- }
2061
- return singleRelation;
2062
- }
2063
- }
2064
- replaceRelations(x, relations, config) {
2065
- const hasContent = !Array.isArray(relations);
2066
- const ys = hasContent ? Object.keys(relations) : relations;
2067
- if (config?.reckless) {
2068
- this.replaceRelationsUnsafely(x, ys);
2069
- } else {
2070
- this.replaceRelationsSafely(x, ys);
2071
- }
2072
- if (hasContent) {
2073
- for (const y of ys) {
2074
- const contentKey = this.makeContentKey(x, y);
2075
- const content = relations[y];
2076
- this.setContent(contentKey, content);
2077
- }
2078
- }
2079
- return this;
2080
- }
2081
- getContent(a, b) {
2082
- const contentKey = this.makeContentKey(a, b);
2083
- return this.getContentInternal(contentKey);
2084
- }
2085
- getRelationEntries(input) {
2086
- const a = input[this.a];
2087
- const b = input[this.b];
2088
- if (a !== void 0 && b === void 0) {
2089
- const aRelations = this.getRelatedKeys(a);
2090
- if (aRelations) {
2091
- return [...aRelations].map((aRelation) => {
2092
- return [aRelation, this.getContent(a, aRelation)];
2093
- });
2094
- }
2095
- }
2096
- if (a === void 0 && b !== void 0) {
2097
- const bRelations = this.getRelatedKeys(b);
2098
- if (bRelations) {
2099
- return [...bRelations].map((bRelation) => {
2100
- return [bRelation, this.getContent(bRelation, b)];
2101
- });
2102
- }
2103
- }
2104
- return [];
2105
- }
2106
- has(a, b) {
2107
- if (b) {
2108
- const setA = this.getRelatedKeys(a);
2109
- return setA?.has(b) ?? false;
2110
- }
2111
- return this.relations.has(a);
2112
- }
2113
- };
2114
-
2115
- // internal/src/lazy-map.ts
2116
- var LazyMap = class extends Map {
2117
- deleted = /* @__PURE__ */ new Set();
2118
- source;
2119
- constructor(source) {
2120
- super();
2121
- this.source = source;
2122
- }
2123
- get(key) {
2124
- const has = super.has(key);
2125
- if (has) {
2126
- return super.get(key);
2127
- }
2128
- if (!this.deleted.has(key) && this.source.has(key)) {
2129
- const value = this.source.get(key);
2130
- return value;
2131
- }
2132
- return void 0;
2133
- }
2134
- set(key, value) {
2135
- this.deleted.delete(key);
2136
- return super.set(key, value);
2137
- }
2138
- hasOwn(key) {
2139
- return super.has(key);
2140
- }
2141
- has(key) {
2142
- return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
2143
- }
2144
- delete(key) {
2145
- this.deleted.add(key);
2146
- return super.delete(key);
2147
- }
2148
- };
2149
-
2150
- // internal/src/transaction/build-transaction.ts
2151
- var buildTransaction = (store, key, params, id) => {
2152
- const parent = newest(store);
2153
- const childBase = {
2154
- parent,
2155
- child: null,
2156
- on: parent.on,
2157
- loggers: parent.loggers,
2158
- logger: parent.logger,
2159
- config: parent.config,
2160
- atoms: new LazyMap(parent.atoms),
2161
- atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
2162
- families: new LazyMap(parent.families),
2163
- joins: new LazyMap(parent.joins),
2164
- operation: { open: false },
2165
- readonlySelectors: new LazyMap(parent.readonlySelectors),
2166
- timelines: new LazyMap(parent.timelines),
2167
- timelineTopics: new Junction(parent.timelineTopics.toJSON()),
2168
- trackers: /* @__PURE__ */ new Map(),
2169
- transactions: new LazyMap(parent.transactions),
2170
- selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
2171
- selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
2172
- makeContentKey: (...keys) => keys.sort().join(`:`)
2173
- }),
2174
- selectors: new LazyMap(parent.selectors),
2175
- valueMap: new LazyMap(parent.valueMap),
2176
- defaults: parent.defaults,
2177
- disposalTraces: store.disposalTraces.copy(),
2178
- molecules: new LazyMap(parent.molecules),
2179
- moleculeGraph: new Junction(parent.moleculeGraph.toJSON(), {
2180
- makeContentKey: parent.moleculeGraph.makeContentKey
2181
- }),
2182
- moleculeData: new Junction(parent.moleculeData.toJSON(), {
2183
- makeContentKey: parent.moleculeData.makeContentKey
2184
- }),
2185
- moleculeJoins: new Junction(parent.moleculeJoins.toJSON(), {
2186
- makeContentKey: parent.moleculeJoins.makeContentKey
2187
- }),
2188
- miscResources: new LazyMap(parent.miscResources)
2189
- };
2190
- const epoch = getEpochNumberOfAction(store, key);
2191
- const transactionMeta = {
2192
- phase: `building`,
2193
- update: {
2194
- type: `transaction_update`,
2195
- key,
2196
- id,
2197
- epoch: epoch === void 0 ? Number.NaN : epoch + 1,
2198
- updates: [],
2199
- params,
2200
- output: void 0
2201
- },
2202
- toolkit: {
2203
- get: (...ps) => getFromStore(child, ...ps),
2204
- set: (...ps) => {
2205
- setIntoStore(child, ...ps);
2206
- },
2207
- run: (token, identifier = arbitrary()) => actUponStore(child, token, identifier),
2208
- find: (token, k) => findInStore(child, token, k),
2209
- json: (token) => getJsonToken(child, token),
2210
- dispose: (...ps) => {
2211
- disposeFromStore(child, ...ps);
2212
- },
2213
- env: () => getEnvironmentData(child)
2214
- }
2215
- };
2216
- const child = Object.assign(childBase, {
2217
- transactionMeta
2218
- });
2219
- parent.child = child;
2220
- store.logger.info(
2221
- `\u{1F6EB}`,
2222
- `transaction`,
2223
- key,
2224
- `Building transaction with params:`,
2225
- params
2226
- );
2227
- return child;
2228
- };
2229
-
2230
- // internal/src/transaction/create-transaction.ts
2231
- function createTransaction(store, options) {
2232
- const newTransaction = {
2233
- key: options.key,
2234
- type: `transaction`,
2235
- run: (params, id) => {
2236
- const childStore = buildTransaction(store, options.key, params, id);
2237
- try {
2238
- const target2 = newest(store);
2239
- const { toolkit } = childStore.transactionMeta;
2240
- const output = options.do(toolkit, ...params);
2241
- applyTransaction(output, target2);
2242
- return output;
2243
- } catch (thrown) {
2244
- abortTransaction(target);
2245
- store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
2246
- throw thrown;
2247
- }
2248
- },
2249
- install: (s) => createTransaction(s, options),
2250
- subject: new Subject()
2251
- };
2252
- const target = newest(store);
2253
- target.transactions.set(newTransaction.key, newTransaction);
2254
- const token = deposit(newTransaction);
2255
- store.on.transactionCreation.next(token);
2256
- return token;
2257
- }
2258
-
2259
- // internal/src/transaction/index.ts
2260
- var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
2261
-
2262
- // internal/src/install-into-store.ts
2263
- function installIntoStore(tokens, target, source) {
2264
- const sourceNewest = newest(source);
2265
- if (isChildStore(sourceNewest)) {
2266
- source.logger.error(
2267
- `\u274C`,
2268
- `transaction`,
2269
- sourceNewest.transactionMeta.update.key,
2270
- `could not install the following tokens into store "${target.config.name} from "${source.config.name}":`,
2271
- tokens,
2272
- `${sourceNewest.config.name} is undergoing a transaction.`
2273
- );
2274
- return;
2275
- }
2276
- const targetNewest = newest(target);
2277
- if (isChildStore(targetNewest)) {
2278
- target.logger.error(
2279
- `\u274C`,
2280
- `transaction`,
2281
- targetNewest.transactionMeta.update.key,
2282
- `could not install the following tokens into store "${target.config.name} from "${source.config.name}":`,
2283
- tokens,
2284
- `${targetNewest.config.name} is undergoing a transaction.`
2285
- );
2286
- return;
2287
- }
2288
- for (const token of tokens) {
2289
- const resource = withdraw(source, token);
2290
- resource.install(target);
2291
- }
2292
- }
2293
-
2294
- // src/silo.ts
2295
- var Silo = class {
2296
- store;
2297
- atom;
2298
- atomFamily;
2299
- selector;
2300
- selectorFamily;
2301
- transaction;
2302
- timeline;
2303
- findState;
2304
- getState;
2305
- setState;
2306
- disposeState;
2307
- subscribe;
2308
- undo;
2309
- redo;
2310
- runTransaction;
2311
- install;
2312
- constructor(config, fromStore = null) {
2313
- const s = this.store = new Store(config, fromStore);
2314
- this.atom = (options) => createStandaloneAtom(s, options);
2315
- this.atomFamily = (options) => createAtomFamily(s, options);
2316
- this.selector = (options) => createStandaloneSelector(s, options);
2317
- this.selectorFamily = (options) => createSelectorFamily(s, options);
2318
- this.transaction = (options) => createTransaction(s, options);
2319
- this.timeline = (options) => createTimeline(s, options);
2320
- this.findState = (...params) => findInStore(s, ...params);
2321
- this.getState = (...params) => getFromStore(s, ...params);
2322
- this.setState = (...params) => {
2323
- setIntoStore(s, ...params);
2324
- };
2325
- this.disposeState = (...params) => {
2326
- disposeFromStore(s, ...params);
2327
- };
2328
- this.subscribe = (...params) => subscribeInStore(s, ...params);
2329
- this.undo = (token) => {
2330
- timeTravel(s, `undo`, token);
2331
- };
2332
- this.redo = (token) => {
2333
- timeTravel(s, `redo`, token);
2334
- };
2335
- this.runTransaction = (token, id = arbitrary()) => actUponStore(s, token, id);
2336
- this.install = (tokens, source = IMPLICIT.STORE) => {
2337
- installIntoStore(tokens, s, source);
2338
- };
2339
- }
2340
- };
2341
-
2342
- // src/subscribe.ts
2343
- function subscribe(token, handleUpdate, key = arbitrary()) {
2344
- return subscribeInStore(IMPLICIT.STORE, token, handleUpdate, key);
2345
- }
2346
-
2347
- // src/timeline.ts
2348
- var timeline = (options) => {
2349
- return createTimeline(IMPLICIT.STORE, options);
2350
- };
2351
- var redo = (tl) => {
2352
- timeTravel(IMPLICIT.STORE, `redo`, tl);
2353
- };
2354
- var undo = (tl) => {
2355
- timeTravel(IMPLICIT.STORE, `undo`, tl);
2356
- };
2357
-
2358
- // src/transaction.ts
2359
- function transaction(options) {
2360
- return createTransaction(IMPLICIT.STORE, options);
2361
- }
2362
- function runTransaction(token, id = arbitrary()) {
2363
- return actUponStore(IMPLICIT.STORE, token, id);
2364
- }
2365
-
2366
- // src/validators.ts
2367
- function isToken(knownToken, unknownToken) {
2368
- return knownToken.key === unknownToken.key;
2369
- }
2370
- function belongsTo(family, unknownToken) {
2371
- return family.key === unknownToken.family?.key;
2372
- }
2373
-
2374
- // internal/src/store/store.ts
2375
- var Store = class {
2376
- parent = null;
2377
- child = null;
2378
- valueMap = /* @__PURE__ */ new Map();
2379
- defaults = /* @__PURE__ */ new Map();
2380
- atoms = /* @__PURE__ */ new Map();
2381
- selectors = /* @__PURE__ */ new Map();
2382
- readonlySelectors = /* @__PURE__ */ new Map();
2383
- atomsThatAreDefault = /* @__PURE__ */ new Set();
2384
- selectorAtoms = new Junction({
2385
- between: [`selectorKey`, `atomKey`],
2386
- cardinality: `n:n`
2387
- });
2388
- selectorGraph = new Junction(
2389
- {
2390
- between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
2391
- cardinality: `n:n`
2392
- },
2393
- {
2394
- makeContentKey: (...keys) => keys.sort().join(`:`)
2395
- }
2396
- );
2397
- trackers = /* @__PURE__ */ new Map();
2398
- families = /* @__PURE__ */ new Map();
2399
- joins = /* @__PURE__ */ new Map();
2400
- transactions = /* @__PURE__ */ new Map();
2401
- transactionMeta = {
2402
- epoch: /* @__PURE__ */ new Map(),
2403
- actionContinuities: new Junction({
2404
- between: [`continuity`, `action`],
2405
- cardinality: `1:n`
2406
- })
2407
- };
2408
- timelines = /* @__PURE__ */ new Map();
2409
- timelineTopics = new Junction({
2410
- between: [`timelineKey`, `topicKey`],
2411
- cardinality: `1:n`
2412
- });
2413
- disposalTraces = new CircularBuffer(100);
2414
- molecules = /* @__PURE__ */ new Map();
2415
- moleculeJoins = new Junction(
2416
- {
2417
- between: [`moleculeKey`, `joinKey`],
2418
- cardinality: `n:n`
2419
- },
2420
- {
2421
- makeContentKey: (...keys) => keys.sort().join(`:`)
2422
- }
2423
- );
2424
- moleculeGraph = new Junction(
2425
- {
2426
- between: [`upstreamMoleculeKey`, `downstreamMoleculeKey`],
2427
- cardinality: `n:n`
2428
- },
2429
- {
2430
- makeContentKey: (...keys) => keys.sort().join(`:`)
2431
- }
2432
- );
2433
- moleculeData = new Junction(
2434
- {
2435
- between: [`moleculeKey`, `stateFamilyKey`],
2436
- cardinality: `n:n`
2437
- },
2438
- {
2439
- makeContentKey: (...keys) => keys.sort().join(`:`)
2440
- }
2441
- );
2442
- miscResources = /* @__PURE__ */ new Map();
2443
- on = {
2444
- atomCreation: new Subject(),
2445
- atomDisposal: new Subject(),
2446
- selectorCreation: new Subject(),
2447
- selectorDisposal: new Subject(),
2448
- timelineCreation: new Subject(),
2449
- transactionCreation: new Subject(),
2450
- transactionApplying: new StatefulSubject(
2451
- null
2452
- ),
2453
- operationClose: new Subject(),
2454
- moleculeCreation: new Subject(),
2455
- moleculeDisposal: new Subject()
2456
- };
2457
- operation = { open: false };
2458
- config = {
2459
- name: `IMPLICIT_STORE`,
2460
- lifespan: `ephemeral`
2461
- };
2462
- loggers = [
2463
- new AtomIOLogger(`warn`, (_, __, key) => !isReservedIntrospectionKey(key))
2464
- ];
2465
- logger = {
2466
- error: (...messages) => {
2467
- for (const logger of this.loggers) logger.error(...messages);
2468
- },
2469
- info: (...messages) => {
2470
- for (const logger of this.loggers) logger.info(...messages);
2471
- },
2472
- warn: (...messages) => {
2473
- for (const logger of this.loggers) logger.warn(...messages);
2474
- }
2475
- };
2476
- constructor(config, store = null) {
2477
- this.config = {
2478
- ...store?.config,
2479
- ...config
2480
- };
2481
- if (store !== null) {
2482
- this.valueMap = new Map(store?.valueMap);
2483
- this.operation = { ...store?.operation };
2484
- if (isRootStore(store)) {
2485
- this.transactionMeta = {
2486
- epoch: new Map(store?.transactionMeta.epoch),
2487
- actionContinuities: new Junction(
2488
- store?.transactionMeta.actionContinuities.toJSON()
2489
- )
2490
- };
2491
- }
2492
- for (const [, family] of store.families) {
2493
- if (family.internalRoles?.includes(`mutable`) || family.internalRoles?.includes(`join`)) {
2494
- continue;
2495
- }
2496
- family.install(this);
2497
- }
2498
- const mutableHelpers = /* @__PURE__ */ new Set();
2499
- for (const [, atom2] of store.atoms) {
2500
- if (mutableHelpers.has(atom2.key)) {
2501
- continue;
2502
- }
2503
- atom2.install(this);
2504
- if (atom2.type === `mutable_atom`) {
2505
- const originalJsonToken = getJsonToken(store, atom2);
2506
- const originalUpdateToken = getUpdateToken(atom2);
2507
- mutableHelpers.add(originalJsonToken.key);
2508
- mutableHelpers.add(originalUpdateToken.key);
2509
- }
2510
- }
2511
- for (const [, selector2] of store.readonlySelectors) {
2512
- selector2.install(this);
2513
- }
2514
- for (const [, selector2] of store.selectors) {
2515
- if (mutableHelpers.has(selector2.key)) {
2516
- continue;
2517
- }
2518
- selector2.install(this);
2519
- }
2520
- for (const [, tx] of store.transactions) {
2521
- tx.install(this);
2522
- }
2523
- for (const [, timeline2] of store.timelines) {
2524
- timeline2.install(this);
2525
- }
2526
- }
2527
- }
2528
- };
2529
- var IMPLICIT = {
2530
- get STORE() {
2531
- if (!globalThis.ATOM_IO_IMPLICIT_STORE) {
2532
- globalThis.ATOM_IO_IMPLICIT_STORE = new Store({
2533
- name: `IMPLICIT_STORE`,
2534
- lifespan: `ephemeral`
2535
- });
2536
- }
2537
- return globalThis.ATOM_IO_IMPLICIT_STORE;
2538
- }
2539
- };
2540
- var clearStore = (store) => {
2541
- const { config } = store;
2542
- for (const disposable of store.miscResources.values()) {
2543
- disposable[Symbol.dispose]();
2544
- }
2545
- Object.assign(store, new Store(config));
2546
- store.config = config;
2547
- };
2548
-
2549
- // internal/src/store/withdraw.ts
2550
- function withdraw(store, token) {
2551
- let withdrawn;
2552
- let target = store;
2553
- while (target !== null) {
2554
- switch (token.type) {
2555
- case `atom`:
2556
- case `mutable_atom`:
2557
- withdrawn = target.atoms.get(token.key);
2558
- break;
2559
- case `selector`:
2560
- withdrawn = target.selectors.get(token.key);
2561
- break;
2562
- case `readonly_selector`:
2563
- withdrawn = target.readonlySelectors.get(token.key);
2564
- break;
2565
- case `atom_family`:
2566
- case `mutable_atom_family`:
2567
- case `selector_family`:
2568
- case `readonly_selector_family`:
2569
- withdrawn = target.families.get(token.key);
2570
- break;
2571
- case `timeline`:
2572
- withdrawn = target.timelines.get(token.key);
2573
- break;
2574
- case `transaction`:
2575
- withdrawn = target.transactions.get(token.key);
2576
- break;
2577
- }
2578
- if (withdrawn) {
2579
- return withdrawn;
2580
- }
2581
- target = target.child;
2582
- }
2583
- throw new NotFoundError(token, store);
2584
- }
2585
-
2586
- // internal/src/subscribe/recall-state.ts
2587
- var recallState = (store, state) => {
2588
- const target = newest(store);
2589
- if (target.operation.open) {
2590
- return target.operation.prev.get(state.key);
2591
- }
2592
- return target.valueMap.get(state.key);
2593
- };
2594
-
2595
- // internal/src/subscribe/subscribe-in-store.ts
2596
- function subscribeInStore(store, token, handleUpdate, key = arbitrary()) {
2597
- switch (token.type) {
2598
- case `atom`:
2599
- case `mutable_atom`:
2600
- case `readonly_selector`:
2601
- case `selector`:
2602
- return subscribeToState(store, token, key, handleUpdate);
2603
- case `transaction`:
2604
- return subscribeToTransaction(store, token, key, handleUpdate);
2605
- case `timeline`:
2606
- return subscribeToTimeline(store, token, key, handleUpdate);
2607
- }
2608
- }
2609
-
2610
- // internal/src/subscribe/subscribe-to-root-atoms.ts
2611
- var subscribeToRootAtoms = (store, selector2) => {
2612
- const target = newest(store);
2613
- const dependencySubscriptions = traceAllSelectorAtoms(selector2, store).map(
2614
- (atomKey) => {
2615
- const atom2 = target.atoms.get(atomKey);
2616
- if (atom2 === void 0) {
2617
- throw new Error(
2618
- `Atom "${atomKey}", a dependency of selector "${selector2.key}", not found in store "${store.config.name}".`
2619
- );
2620
- }
2621
- return atom2.subject.subscribe(
2622
- `${selector2.type}:${selector2.key}`,
2623
- (atomChange) => {
2624
- store.logger.info(
2625
- `\u{1F4E2}`,
2626
- selector2.type,
2627
- selector2.key,
2628
- `root`,
2629
- atomKey,
2630
- `went`,
2631
- atomChange.oldValue,
2632
- `->`,
2633
- atomChange.newValue
2634
- );
2635
- const oldValue = recallState(target, selector2);
2636
- const newValue = readOrComputeValue(target, selector2);
2637
- store.logger.info(
2638
- `\u2728`,
2639
- selector2.type,
2640
- selector2.key,
2641
- `went`,
2642
- oldValue,
2643
- `->`,
2644
- newValue
2645
- );
2646
- selector2.subject.next({ newValue, oldValue });
2647
- }
2648
- );
2649
- }
2650
- );
2651
- return dependencySubscriptions;
2652
- };
2653
-
2654
- // internal/src/subscribe/subscribe-to-state.ts
2655
- function subscribeToState(store, token, key, handleUpdate) {
2656
- function safelyHandleUpdate(update) {
2657
- if (store.operation.open) {
2658
- const unsubscribe2 = store.on.operationClose.subscribe(
2659
- `state subscription ${key}`,
2660
- () => {
2661
- unsubscribe2();
2662
- handleUpdate(update);
2663
- }
2664
- );
2665
- } else {
2666
- handleUpdate(update);
2667
- }
2668
- }
2669
- const state = withdraw(store, token);
2670
- store.logger.info(`\u{1F440}`, state.type, state.key, `Adding subscription "${key}"`);
2671
- const isSelector = state.type === `selector` || state.type === `readonly_selector`;
2672
- let dependencyUnsubFunctions = null;
2673
- let updateHandler = safelyHandleUpdate;
2674
- if (isSelector) {
2675
- dependencyUnsubFunctions = subscribeToRootAtoms(store, state);
2676
- updateHandler = (update) => {
2677
- if (dependencyUnsubFunctions) {
2678
- dependencyUnsubFunctions.length = 0;
2679
- dependencyUnsubFunctions.push(...subscribeToRootAtoms(store, state));
2680
- }
2681
- safelyHandleUpdate(update);
2682
- };
2683
- }
2684
- const mainUnsubFunction = state.subject.subscribe(key, updateHandler);
2685
- const unsubscribe = () => {
2686
- store.logger.info(
2687
- `\u{1F648}`,
2688
- state.type,
2689
- state.key,
2690
- `Removing subscription "${key}"`
2691
- );
2692
- mainUnsubFunction();
2693
- if (dependencyUnsubFunctions) {
2694
- for (const unsubFromDependency of dependencyUnsubFunctions) {
2695
- unsubFromDependency();
2696
- }
2697
- }
2698
- };
2699
- return unsubscribe;
2700
- }
2701
-
2702
- // internal/src/subscribe/subscribe-to-timeline.ts
2703
- var subscribeToTimeline = (store, token, key, handleUpdate) => {
2704
- const tl = withdraw(store, token);
2705
- store.logger.info(`\u{1F440}`, `timeline`, token.key, `Adding subscription "${key}"`);
2706
- const unsubscribe = tl.subject.subscribe(key, handleUpdate);
2707
- return () => {
2708
- store.logger.info(
2709
- `\u{1F648}`,
2710
- `timeline`,
2711
- token.key,
2712
- `Removing subscription "${key}" from timeline`
2713
- );
2714
- unsubscribe();
2715
- };
2716
- };
2717
-
2718
- // internal/src/subscribe/subscribe-to-transaction.ts
2719
- var subscribeToTransaction = (store, token, key, handleUpdate) => {
2720
- const tx = withdraw(store, token);
2721
- store.logger.info(
2722
- `\u{1F440}`,
2723
- `transaction`,
2724
- token.key,
2725
- `Adding subscription "${key}"`
2726
- );
2727
- const unsubscribe = tx.subject.subscribe(key, handleUpdate);
2728
- return () => {
2729
- store.logger.info(
2730
- `\u{1F648}`,
2731
- `transaction`,
2732
- token.key,
2733
- `Removing subscription "${key}"`
2734
- );
2735
- unsubscribe();
2736
- };
2737
- };
2738
-
2739
- // internal/src/mutable/tracker.ts
2740
- var Tracker = class {
2741
- Update;
2742
- initializeState(mutableState, store) {
2743
- const latestUpdateStateKey = `*${mutableState.key}`;
2744
- store.atoms.delete(latestUpdateStateKey);
2745
- store.valueMap.delete(latestUpdateStateKey);
2746
- const familyMetaData = mutableState.family ? {
2747
- key: `*${mutableState.family.key}`,
2748
- subKey: mutableState.family.subKey
2749
- } : void 0;
2750
- const latestUpdateState = createRegularAtom(
2751
- store,
2752
- {
2753
- key: latestUpdateStateKey,
2754
- default: null
2755
- },
2756
- familyMetaData
2757
- );
2758
- if (store.parent?.valueMap.has(latestUpdateStateKey)) {
2759
- const parentValue = store.parent.valueMap.get(latestUpdateStateKey);
2760
- store.valueMap.set(latestUpdateStateKey, parentValue);
2761
- }
2762
- return latestUpdateState;
2763
- }
2764
- unsubscribeFromInnerValue;
2765
- unsubscribeFromState;
2766
- observeCore(mutableState, latestUpdateState, target) {
2767
- const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
2768
- const originalInnerValue = getFromStore(target, mutableState);
2769
- this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
2770
- subscriptionKey,
2771
- (update) => {
2772
- setIntoStore(target, latestUpdateState, update);
2773
- }
2774
- );
2775
- this.unsubscribeFromState = subscribeToState(
2776
- target,
2777
- mutableState,
2778
- subscriptionKey,
2779
- (update) => {
2780
- if (update.newValue !== update.oldValue) {
2781
- this.unsubscribeFromInnerValue();
2782
- this.unsubscribeFromInnerValue = update.newValue.subscribe(
2783
- subscriptionKey,
2784
- (transceiverUpdate) => {
2785
- setIntoStore(target, latestUpdateState, transceiverUpdate);
2786
- }
2787
- );
2788
- }
2789
- }
2790
- );
2791
- }
2792
- updateCore(mutableState, latestUpdateState, target) {
2793
- const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
2794
- subscribeToState(
2795
- target,
2796
- latestUpdateState,
2797
- subscriptionKey,
2798
- ({ newValue, oldValue }) => {
2799
- const timelineId = target.timelineTopics.getRelatedKey(
2800
- latestUpdateState.key
2801
- );
2802
- if (timelineId) {
2803
- const timelineData = target.timelines.get(timelineId);
2804
- if (timelineData?.timeTraveling) {
2805
- const unsubscribe2 = subscribeToTimeline(
2806
- target,
2807
- { key: timelineId, type: `timeline` },
2808
- subscriptionKey,
2809
- (update) => {
2810
- unsubscribe2();
2811
- setIntoStore(target, mutableState, (transceiver) => {
2812
- if (update === `redo` && newValue) {
2813
- transceiver.do(newValue);
2814
- } else if (update === `undo` && oldValue) {
2815
- transceiver.undo(oldValue);
2816
- }
2817
- return transceiver;
2818
- });
2819
- }
2820
- );
2821
- return;
2822
- }
2823
- }
2824
- const unsubscribe = target.on.operationClose.subscribe(
2825
- subscriptionKey,
2826
- () => {
2827
- unsubscribe();
2828
- const mutable = getFromStore(target, mutableState);
2829
- const updateNumber = newValue === null ? -1 : mutable.getUpdateNumber(newValue);
2830
- const eventOffset = updateNumber - mutable.cacheUpdateNumber;
2831
- if (newValue && eventOffset === 1) {
2832
- setIntoStore(
2833
- target,
2834
- mutableState,
2835
- (transceiver) => (transceiver.do(newValue), transceiver)
2836
- );
2837
- } else {
2838
- target.logger.info(
2839
- `\u274C`,
2840
- `mutable_atom`,
2841
- mutableState.key,
2842
- `could not be updated. Expected update number ${mutable.cacheUpdateNumber + 1}, but got ${updateNumber}`
2843
- );
2844
- }
2845
- }
2846
- );
2847
- }
2848
- );
2849
- }
2850
- mutableState;
2851
- latestUpdateState;
2852
- [Symbol.dispose];
2853
- constructor(mutableState, store) {
2854
- this.mutableState = mutableState;
2855
- const target = newest(store);
2856
- this.latestUpdateState = this.initializeState(mutableState, target);
2857
- this.observeCore(mutableState, this.latestUpdateState, target);
2858
- this.updateCore(mutableState, this.latestUpdateState, target);
2859
- target.trackers.set(mutableState.key, this);
2860
- this[Symbol.dispose] = () => {
2861
- this.unsubscribeFromInnerValue();
2862
- this.unsubscribeFromState();
2863
- target.trackers.delete(mutableState.key);
2864
- };
2865
- }
2866
- };
2867
-
2868
- // internal/src/mutable/create-mutable-atom.ts
2869
- function createMutableAtom(store, options, family) {
2870
- store.logger.info(
2871
- `\u{1F528}`,
2872
- `atom`,
2873
- options.key,
2874
- `creating in store "${store.config.name}"`
2875
- );
2876
- const target = newest(store);
2877
- const existing = target.atoms.get(options.key);
2878
- if (existing && existing.type === `mutable_atom`) {
2879
- store.logger.error(
2880
- `\u274C`,
2881
- `atom`,
2882
- options.key,
2883
- `Tried to create atom, but it already exists in the store.`
2884
- );
2885
- return deposit(existing);
2886
- }
2887
- const subject = new Subject();
2888
- const newAtom = {
2889
- ...options,
2890
- type: `mutable_atom`,
2891
- install: (s) => {
2892
- s.logger.info(
2893
- `\u{1F6E0}\uFE0F`,
2894
- `atom`,
2895
- options.key,
2896
- `installing in store "${s.config.name}"`
2897
- );
2898
- return createMutableAtom(s, options, family);
2899
- },
2900
- subject
2901
- };
2902
- if (family) {
2903
- newAtom.family = family;
2904
- }
2905
- const initialValue = options.default();
2906
- target.atoms.set(newAtom.key, newAtom);
2907
- markAtomAsDefault(store, options.key);
2908
- cacheValue(target, options.key, initialValue, subject);
2909
- const token = deposit(newAtom);
2910
- if (options.effects) {
2911
- let effectIndex = 0;
2912
- const cleanupFunctions = [];
2913
- for (const effect of options.effects) {
2914
- const cleanup = effect({
2915
- setSelf: (next) => {
2916
- setIntoStore(store, token, next);
2917
- },
2918
- onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
2919
- });
2920
- if (cleanup) {
2921
- cleanupFunctions.push(cleanup);
2922
- }
2923
- ++effectIndex;
2924
- }
2925
- newAtom.cleanup = () => {
2926
- for (const cleanup of cleanupFunctions) {
2927
- cleanup();
2928
- }
2929
- };
2930
- }
2931
- new Tracker(token, store);
2932
- if (!family) {
2933
- selectJson(token, options, store);
2934
- }
2935
- return token;
2936
- }
2937
-
2938
- // internal/src/mutable/tracker-family.ts
2939
- var FamilyTracker = class {
2940
- trackers = /* @__PURE__ */ new Map();
2941
- Update;
2942
- latestUpdateAtoms;
2943
- mutableAtoms;
2944
- constructor(mutableAtoms, store) {
2945
- const updateAtoms = createRegularAtomFamily(
2946
- store,
2947
- {
2948
- key: `*${mutableAtoms.key}`,
2949
- default: null
2950
- },
2951
- [`mutable`, `updates`]
2952
- );
2953
- this.latestUpdateAtoms = withdraw(store, updateAtoms);
2954
- this.mutableAtoms = mutableAtoms;
2955
- this.mutableAtoms.subject.subscribe(
2956
- `store=${store.config.name}::tracker-atom-family`,
2957
- (event) => {
2958
- const { type, token } = event;
2959
- if (token.family) {
2960
- const key = parseJson(token.family.subKey);
2961
- switch (type) {
2962
- case `state_creation`:
2963
- this.trackers.set(key, new Tracker(token, store));
2964
- break;
2965
- case `state_disposal`:
2966
- {
2967
- const tracker = this.trackers.get(key);
2968
- if (tracker) {
2969
- tracker[Symbol.dispose]();
2970
- this.trackers.delete(key);
2971
- }
2972
- }
2973
- break;
2974
- }
2975
- }
2976
- }
2977
- );
2978
- }
2979
- };
2980
-
2981
- // internal/src/mutable/create-mutable-atom-family.ts
2982
- function createMutableAtomFamily(store, options, internalRoles) {
2983
- const familyToken = {
2984
- key: options.key,
2985
- type: `mutable_atom_family`
2986
- };
2987
- const existing = store.families.get(options.key);
2988
- if (existing) {
2989
- store.logger.error(
2990
- `\u2757`,
2991
- `mutable_atom_family`,
2992
- options.key,
2993
- `Overwriting an existing ${prettyPrintTokenType(
2994
- existing
2995
- )} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`
2996
- );
2997
- }
2998
- const subject = new Subject();
2999
- const familyFunction = (key) => {
3000
- const subKey = stringifyJson(key);
3001
- const family = { key: options.key, subKey };
3002
- const fullKey = `${options.key}(${subKey})`;
3003
- const target = newest(store);
3004
- const individualOptions = {
3005
- key: fullKey,
3006
- default: () => options.default(key),
3007
- toJson: options.toJson,
3008
- fromJson: options.fromJson,
3009
- mutable: true
3010
- };
3011
- if (options.effects) {
3012
- individualOptions.effects = options.effects(key);
3013
- }
3014
- const token = createMutableAtom(target, individualOptions, family);
3015
- subject.next({ type: `state_creation`, token });
3016
- return token;
3017
- };
3018
- const atomFamily2 = Object.assign(familyFunction, familyToken, {
3019
- subject,
3020
- install: (s) => createMutableAtomFamily(s, options),
3021
- toJson: options.toJson,
3022
- fromJson: options.fromJson,
3023
- internalRoles
3024
- });
3025
- store.families.set(options.key, atomFamily2);
3026
- selectJsonFamily(store, atomFamily2, options);
3027
- new FamilyTracker(atomFamily2, store);
3028
- return familyToken;
3029
- }
3030
-
3031
- // internal/src/mutable/get-json-family.ts
3032
- var getJsonFamily = (mutableAtomFamily, store) => {
3033
- const target = newest(store);
3034
- const key = `${mutableAtomFamily.key}:JSON`;
3035
- const jsonFamily = target.families.get(key);
3036
- return jsonFamily;
3037
- };
3038
-
3039
- // internal/src/mutable/get-json-token.ts
3040
- var getJsonToken = (store, mutableAtomToken) => {
3041
- if (mutableAtomToken.family) {
3042
- const target = newest(store);
3043
- const jsonFamilyKey = `${mutableAtomToken.family.key}:JSON`;
3044
- const jsonFamilyToken = {
3045
- key: jsonFamilyKey,
3046
- type: `selector_family`
3047
- };
3048
- const family = withdraw(target, jsonFamilyToken);
3049
- const subKey = JSON.parse(mutableAtomToken.family.subKey);
3050
- const jsonToken = findInStore(store, family, subKey);
3051
- return jsonToken;
3052
- }
3053
- const token = {
3054
- type: `selector`,
3055
- key: `${mutableAtomToken.key}:JSON`
3056
- };
3057
- return token;
3058
- };
3059
-
3060
- // internal/src/mutable/get-update-family.ts
3061
- var getUpdateFamily = (mutableAtomFamily, store) => {
3062
- const target = newest(store);
3063
- const key = `*${mutableAtomFamily.key}`;
3064
- const updateFamily = target.families.get(
3065
- key
3066
- );
3067
- return updateFamily;
3068
- };
3069
-
3070
- // internal/src/mutable/get-update-token.ts
3071
- var getUpdateToken = (mutableAtomToken) => {
3072
- const key = `*${mutableAtomToken.key}`;
3073
- const updateToken = { type: `atom`, key };
3074
- if (mutableAtomToken.family) {
3075
- updateToken.family = {
3076
- key: `*${mutableAtomToken.family.key}`,
3077
- subKey: mutableAtomToken.family.subKey
3078
- };
3079
- }
3080
- return updateToken;
3081
- };
3082
-
3083
- // internal/src/mutable/transceiver.ts
3084
- function isTransceiver(value) {
3085
- return typeof value === `object` && value !== null && `do` in value && `undo` in value && `subscribe` in value;
3086
- }
3087
-
3088
- // internal/src/set-state/copy-mutable-if-needed.ts
3089
- function copyMutableIfNeeded(target, atom2, origin) {
3090
- const originValue = origin.valueMap.get(atom2.key);
3091
- const targetValue = target.valueMap.get(atom2.key);
3092
- if (originValue !== targetValue) {
3093
- return targetValue;
3094
- }
3095
- if (originValue === void 0) {
3096
- return atom2.default();
3097
- }
3098
- origin.logger.info(`\u{1F4C3}`, `atom`, atom2.key, `copying`);
3099
- const jsonValue = atom2.toJson(originValue);
3100
- const copiedValue = atom2.fromJson(jsonValue);
3101
- target.valueMap.set(atom2.key, copiedValue);
3102
- new Tracker(atom2, origin);
3103
- return copiedValue;
3104
- }
3105
-
3106
- // internal/src/caching.ts
3107
- function cacheValue(target, key, value, subject) {
3108
- const currentValue = target.valueMap.get(key);
3109
- if (currentValue instanceof Future) {
3110
- const future = currentValue;
3111
- future.use(value);
3112
- }
3113
- if (value instanceof Promise) {
3114
- const future = new Future(value);
3115
- target.valueMap.set(key, future);
3116
- future.then((resolved) => {
3117
- cacheValue(target, key, resolved, subject);
3118
- subject.next({ newValue: resolved, oldValue: future });
3119
- }).catch((thrown) => {
3120
- target.logger.error(`\u{1F4A5}`, `state`, key, `rejected:`, thrown);
3121
- });
3122
- return future;
3123
- }
3124
- target.valueMap.set(key, value);
3125
- return value;
3126
- }
3127
- var readCachedValue = (token, target) => {
3128
- let value = target.valueMap.get(token.key);
3129
- if (token.type === `mutable_atom` && isChildStore(target)) {
3130
- const { parent } = target;
3131
- const copiedValue = copyMutableIfNeeded(target, token, parent);
3132
- value = copiedValue;
3133
- }
3134
- return value;
3135
- };
3136
- var evictCachedValue = (key, target) => {
3137
- const currentValue = target.valueMap.get(key);
3138
- if (currentValue instanceof Future) {
3139
- const future = currentValue;
3140
- const selector2 = target.selectors.get(key) ?? target.readonlySelectors.get(key);
3141
- if (selector2) {
3142
- future.use(selector2.get());
3143
- }
3144
- return;
3145
- }
3146
- if (target.operation.open) {
3147
- target.operation.prev.set(key, currentValue);
3148
- }
3149
- target.valueMap.delete(key);
3150
- target.logger.info(`\u{1F5D1}`, `state`, key, `evicted`);
3151
- };
3152
-
3153
- // internal/src/atom/is-default.ts
3154
- var isAtomDefault = (store, key) => {
3155
- const core = newest(store);
3156
- return core.atomsThatAreDefault.has(key);
3157
- };
3158
- var markAtomAsDefault = (store, key) => {
3159
- const core = newest(store);
3160
- core.atomsThatAreDefault = new Set(core.atomsThatAreDefault).add(key);
3161
- };
3162
- var markAtomAsNotDefault = (store, key) => {
3163
- const core = newest(store);
3164
- core.atomsThatAreDefault = new Set(newest(store).atomsThatAreDefault);
3165
- core.atomsThatAreDefault.delete(key);
3166
- };
3167
-
3168
- // internal/src/atom/create-regular-atom.ts
3169
- function createRegularAtom(store, options, family) {
3170
- store.logger.info(
3171
- `\u{1F528}`,
3172
- `atom`,
3173
- options.key,
3174
- `creating in store "${store.config.name}"`
3175
- );
3176
- const target = newest(store);
3177
- const existing = target.atoms.get(options.key);
3178
- if (existing && existing.type === `atom`) {
3179
- store.logger.error(
3180
- `\u274C`,
3181
- `atom`,
3182
- options.key,
3183
- `Tried to create atom, but it already exists in the store.`
3184
- );
3185
- return deposit(existing);
3186
- }
3187
- const subject = new Subject();
3188
- const newAtom = {
3189
- ...options,
3190
- type: `atom`,
3191
- install: (s) => {
3192
- s.logger.info(
3193
- `\u{1F6E0}\uFE0F`,
3194
- `atom`,
3195
- options.key,
3196
- `installing in store "${s.config.name}"`
3197
- );
3198
- return createRegularAtom(s, options, family);
3199
- },
3200
- subject
3201
- };
3202
- if (family) {
3203
- newAtom.family = family;
3204
- }
3205
- let initialValue = options.default;
3206
- if (options.default instanceof Function) {
3207
- initialValue = options.default();
3208
- }
3209
- target.atoms.set(newAtom.key, newAtom);
3210
- markAtomAsDefault(store, options.key);
3211
- cacheValue(target, options.key, initialValue, subject);
3212
- const token = deposit(newAtom);
3213
- if (options.effects) {
3214
- let effectIndex = 0;
3215
- const cleanupFunctions = [];
3216
- for (const effect of options.effects) {
3217
- const cleanup = effect({
3218
- setSelf: (next) => {
3219
- setIntoStore(store, token, next);
3220
- },
3221
- onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
3222
- });
3223
- if (cleanup) {
3224
- cleanupFunctions.push(cleanup);
3225
- }
3226
- ++effectIndex;
3227
- }
3228
- newAtom.cleanup = () => {
3229
- for (const cleanup of cleanupFunctions) {
3230
- cleanup();
3231
- }
3232
- };
3233
- }
3234
- return token;
3235
- }
3236
-
3237
- // internal/src/atom/create-standalone-atom.ts
3238
- function createStandaloneAtom(store, options) {
3239
- const isMutable = `mutable` in options;
3240
- if (isMutable) {
3241
- const state2 = createMutableAtom(store, options, void 0);
3242
- store.on.atomCreation.next(state2);
3243
- return state2;
3244
- }
3245
- const state = createRegularAtom(store, options, void 0);
3246
- store.on.atomCreation.next(state);
3247
- return state;
3248
- }
3249
-
3250
- // internal/src/atom/dispose-atom.ts
3251
- function disposeAtom(store, atomToken) {
3252
- const target = newest(store);
3253
- const { key, family } = atomToken;
3254
- const atom2 = withdraw(target, atomToken);
3255
- if (!family) {
3256
- store.logger.error(`\u274C`, `atom`, key, `Standalone atoms cannot be disposed.`);
3257
- } else {
3258
- atom2.cleanup?.();
3259
- const lastValue = store.valueMap.get(atom2.key);
3260
- const atomFamily2 = withdraw(store, { key: family.key, type: `atom_family` });
3261
- const disposal = {
3262
- type: `state_disposal`,
3263
- subType: `atom`,
3264
- token: atomToken,
3265
- value: lastValue
3266
- };
3267
- atomFamily2.subject.next(disposal);
3268
- const isChild = isChildStore(target);
3269
- target.atoms.delete(key);
3270
- target.valueMap.delete(key);
3271
- target.selectorAtoms.delete(key);
3272
- target.atomsThatAreDefault.delete(key);
3273
- store.timelineTopics.delete(key);
3274
- if (atomToken.type === `mutable_atom`) {
3275
- const updateToken = getUpdateToken(atomToken);
3276
- disposeAtom(store, updateToken);
3277
- store.trackers.delete(key);
3278
- }
3279
- store.logger.info(`\u{1F525}`, `atom`, key, `deleted`);
3280
- if (isChild && target.transactionMeta.phase === `building`) {
3281
- const mostRecentUpdate = target.transactionMeta.update.updates.at(-1);
3282
- const wasMoleculeDisposal = mostRecentUpdate?.type === `molecule_disposal`;
3283
- const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k === atom2.family?.key);
3284
- if (!updateAlreadyCaptured) {
3285
- target.transactionMeta.update.updates.push(disposal);
3286
- }
3287
- } else {
3288
- store.on.atomDisposal.next(atomToken);
3289
- }
3290
- }
3291
- }
3292
-
3293
- // transceivers/set-rtx/src/set-rtx.ts
3294
- var SetRTX = class _SetRTX extends Set {
3295
- mode = `record`;
3296
- subject = new Subject();
3297
- cacheLimit = 0;
3298
- cache = [];
3299
- cacheIdx = -1;
3300
- cacheUpdateNumber = -1;
3301
- constructor(values, cacheLimit = 0) {
3302
- super(values);
3303
- if (values instanceof _SetRTX) {
3304
- this.parent = values;
3305
- this.cacheUpdateNumber = values.cacheUpdateNumber;
3306
- }
3307
- if (cacheLimit) {
3308
- this.cacheLimit = cacheLimit;
3309
- this.cache = new Array(cacheLimit);
3310
- this.subscribe(`auto cache`, (update) => {
3311
- this.cacheIdx++;
3312
- this.cacheIdx %= this.cacheLimit;
3313
- this.cache[this.cacheIdx] = update;
3314
- });
3315
- }
3316
- }
3317
- toJSON() {
3318
- return {
3319
- members: [...this],
3320
- cache: this.cache,
3321
- cacheLimit: this.cacheLimit,
3322
- cacheIdx: this.cacheIdx,
3323
- cacheUpdateNumber: this.cacheUpdateNumber
3324
- };
3325
- }
3326
- static fromJSON(json) {
3327
- const set = new _SetRTX(json.members, json.cacheLimit);
3328
- set.cache = json.cache;
3329
- set.cacheIdx = json.cacheIdx;
3330
- set.cacheUpdateNumber = json.cacheUpdateNumber;
3331
- return set;
3332
- }
3333
- add(value) {
3334
- const result = super.add(value);
3335
- if (this.mode === `record`) {
3336
- this.cacheUpdateNumber++;
3337
- this.emit(`add:${stringifyJson(value)}`);
3338
- }
3339
- return result;
3340
- }
3341
- clear() {
3342
- const capturedContents = this.mode === `record` ? [...this] : null;
3343
- super.clear();
3344
- if (capturedContents) {
3345
- this.cacheUpdateNumber++;
3346
- this.emit(`clear:${JSON.stringify(capturedContents)}`);
3347
- }
3348
- }
3349
- delete(value) {
3350
- const result = super.delete(value);
3351
- if (this.mode === `record`) {
3352
- this.cacheUpdateNumber++;
3353
- this.emit(`del:${stringifyJson(value)}`);
3354
- }
3355
- return result;
3356
- }
3357
- parent;
3358
- child = null;
3359
- transactionUpdates = null;
3360
- transaction(run) {
3361
- this.mode = `transaction`;
3362
- this.transactionUpdates = [];
3363
- this.child = new _SetRTX(this);
3364
- const unsubscribe = this.child._subscribe(`transaction`, (update) => {
3365
- this.transactionUpdates?.push(update);
3366
- });
3367
- try {
3368
- const shouldCommit = run(this.child);
3369
- if (shouldCommit) {
3370
- for (const update of this.transactionUpdates) {
3371
- this.doStep(update);
3372
- }
3373
- this.cacheUpdateNumber++;
3374
- this.emit(`tx:${this.transactionUpdates.join(`;`)}`);
3375
- }
3376
- } catch (thrown) {
3377
- console.warn(
3378
- `Did not apply transaction to SetRTX; this error was thrown:`,
3379
- thrown
3380
- );
3381
- throw thrown;
3382
- } finally {
3383
- unsubscribe();
3384
- this.child = null;
3385
- this.transactionUpdates = null;
3386
- this.mode = `record`;
3387
- }
3388
- }
3389
- _subscribe(key, fn) {
3390
- return this.subject.subscribe(key, fn);
3391
- }
3392
- subscribe(key, fn) {
3393
- return this.subject.subscribe(key, (update) => {
3394
- fn(`${this.cacheUpdateNumber}=${update}`);
3395
- });
3396
- }
3397
- emit(update) {
3398
- this.subject.next(update);
3399
- }
3400
- doStep(update) {
3401
- const typeValueBreak = update.indexOf(`:`);
3402
- const type = update.substring(0, typeValueBreak);
3403
- const value = update.substring(typeValueBreak + 1);
3404
- switch (type) {
3405
- case `add`:
3406
- this.add(JSON.parse(value));
3407
- break;
3408
- case `clear`:
3409
- this.clear();
3410
- break;
3411
- case `del`:
3412
- this.delete(JSON.parse(value));
3413
- break;
3414
- case `tx`:
3415
- for (const subUpdate of value.split(`;`)) {
3416
- this.doStep(subUpdate);
3417
- }
3418
- }
3419
- }
3420
- getUpdateNumber(update) {
3421
- const breakpoint = update.indexOf(`=`);
3422
- return Number(update.substring(0, breakpoint));
3423
- }
3424
- do(update) {
3425
- const breakpoint = update.indexOf(`=`);
3426
- const updateNumber = Number(update.substring(0, breakpoint));
3427
- const eventOffset = updateNumber - this.cacheUpdateNumber;
3428
- const isFuture = eventOffset > 0;
3429
- if (isFuture) {
3430
- if (eventOffset === 1) {
3431
- this.mode = `playback`;
3432
- const innerUpdate = update.substring(breakpoint + 1);
3433
- this.doStep(innerUpdate);
3434
- this.mode = `record`;
3435
- this.cacheUpdateNumber = updateNumber;
3436
- return null;
3437
- }
3438
- return this.cacheUpdateNumber + 1;
3439
- }
3440
- if (Math.abs(eventOffset) < this.cacheLimit) {
3441
- const eventIdx = this.cacheIdx + eventOffset;
3442
- const cachedUpdate = this.cache[eventIdx];
3443
- if (cachedUpdate === update) {
3444
- return null;
3445
- }
3446
- this.mode = `playback`;
3447
- let done = false;
3448
- while (!done) {
3449
- this.cacheIdx %= this.cacheLimit;
3450
- const u = this.cache[this.cacheIdx];
3451
- this.cacheIdx--;
3452
- if (!u) {
3453
- return `OUT_OF_RANGE`;
3454
- }
3455
- this.undo(u);
3456
- done = this.cacheIdx === eventIdx - 1;
3457
- }
3458
- const innerUpdate = update.substring(breakpoint + 1);
3459
- this.doStep(innerUpdate);
3460
- this.mode = `record`;
3461
- this.cacheUpdateNumber = updateNumber;
3462
- return null;
3463
- }
3464
- return `OUT_OF_RANGE`;
3465
- }
3466
- undoStep(update) {
3467
- const breakpoint = update.indexOf(`:`);
3468
- const type = update.substring(0, breakpoint);
3469
- const value = update.substring(breakpoint + 1);
3470
- switch (type) {
3471
- case `add`:
3472
- this.delete(JSON.parse(value));
3473
- break;
3474
- case `del`:
3475
- this.add(JSON.parse(value));
3476
- break;
3477
- case `clear`: {
3478
- const values = JSON.parse(value);
3479
- for (const v of values) this.add(v);
3480
- break;
3481
- }
3482
- case `tx`: {
3483
- const updates = value.split(`;`);
3484
- for (let i = updates.length - 1; i >= 0; i--) {
3485
- this.undoStep(updates[i]);
3486
- }
3487
- }
3488
- }
3489
- }
3490
- undo(update) {
3491
- const breakpoint = update.indexOf(`=`);
3492
- const updateNumber = Number(update.substring(0, breakpoint));
3493
- if (updateNumber === this.cacheUpdateNumber) {
3494
- this.mode = `playback`;
3495
- const innerUpdate = update.substring(breakpoint + 1);
3496
- this.undoStep(innerUpdate);
3497
- this.mode = `record`;
3498
- this.cacheUpdateNumber--;
3499
- return null;
3500
- }
3501
- return this.cacheUpdateNumber;
3502
- }
3503
- };
3504
-
3505
- // internal/src/join/join-internal.ts
3506
- var Join = class {
3507
- toolkit;
3508
- options;
3509
- defaultContent;
3510
- molecules = /* @__PURE__ */ new Map();
3511
- relations;
3512
- states;
3513
- core;
3514
- transact(toolkit, run) {
3515
- const originalToolkit = this.toolkit;
3516
- this.toolkit = toolkit;
3517
- run(this);
3518
- this.toolkit = originalToolkit;
3519
- }
3520
- store;
3521
- realm;
3522
- [Symbol.dispose]() {
3523
- }
3524
- constructor(options, defaultContent, store = IMPLICIT.STORE) {
3525
- this.store = store;
3526
- this.realm = new Anarchy(store);
3527
- this.options = options;
3528
- this.defaultContent = defaultContent;
3529
- this.store.miscResources.set(`join:${options.key}`, this);
3530
- this.realm.allocate(`root`, options.key);
3531
- this.toolkit = {
3532
- get: (...ps) => getFromStore(store, ...ps),
3533
- set: (...ps) => {
3534
- setIntoStore(store, ...ps);
3535
- },
3536
- find: (...ps) => findInStore(store, ...ps),
3537
- json: (token) => getJsonToken(store, token)
3538
- };
3539
- const aSide = options.between[0];
3540
- const bSide = options.between[1];
3541
- const relatedKeysAtoms = createMutableAtomFamily(
3542
- store,
3543
- {
3544
- key: `${options.key}/relatedKeys`,
3545
- default: () => new SetRTX(),
3546
- mutable: true,
3547
- fromJson: (json) => SetRTX.fromJSON(json),
3548
- toJson: (set) => set.toJSON()
3549
- },
3550
- [`join`, `relations`]
3551
- );
3552
- this.core = { relatedKeysAtoms };
3553
- const getRelatedKeys = ({ get }, key) => get(relatedKeysAtoms, key);
3554
- const addRelation = ({ set }, a, b) => {
3555
- if (!this.store.molecules.has(stringifyJson(a))) {
3556
- this.realm.allocate(options.key, a);
3557
- }
3558
- set(relatedKeysAtoms, a, (aKeys) => aKeys.add(b));
3559
- set(relatedKeysAtoms, b, (bKeys) => bKeys.add(a));
3560
- };
3561
- const deleteRelation = ({ set }, a, b) => {
3562
- set(relatedKeysAtoms, a, (aKeys) => {
3563
- aKeys.delete(b);
3564
- return aKeys;
3565
- });
3566
- set(relatedKeysAtoms, b, (bKeys) => {
3567
- bKeys.delete(a);
3568
- return bKeys;
3569
- });
3570
- };
3571
- const replaceRelationsSafely = (toolkit, a, newRelationsOfA) => {
3572
- const { find, get, set } = toolkit;
3573
- const relationsOfAState = find(relatedKeysAtoms, a);
3574
- const currentRelationsOfA = get(relationsOfAState);
3575
- for (const currentRelationB of currentRelationsOfA) {
3576
- const remainsRelated = newRelationsOfA.includes(currentRelationB);
3577
- if (remainsRelated) {
3578
- continue;
3579
- }
3580
- set(relatedKeysAtoms, currentRelationB, (relationsOfB) => {
3581
- relationsOfB.delete(a);
3582
- return relationsOfB;
3583
- });
3584
- }
3585
- set(relationsOfAState, (relationsOfA) => {
3586
- relationsOfA.transaction((nextRelationsOfA) => {
3587
- nextRelationsOfA.clear();
3588
- for (const newRelationB of newRelationsOfA) {
3589
- const relationsOfB = getRelatedKeys(toolkit, newRelationB);
3590
- const newRelationBIsAlreadyRelated = relationsOfB.has(a);
3591
- if (this.relations.cardinality === `1:n`) {
3592
- const previousOwnersToDispose = [];
3593
- for (const previousOwner of relationsOfB) {
3594
- if (previousOwner === a) {
3595
- continue;
3596
- }
3597
- const previousOwnerRelations = getRelatedKeys(
3598
- toolkit,
3599
- previousOwner
3600
- );
3601
- previousOwnerRelations.delete(newRelationB);
3602
- if (previousOwnerRelations.size === 0) {
3603
- previousOwnersToDispose.push(previousOwner);
3604
- }
3605
- }
3606
- if (!newRelationBIsAlreadyRelated && relationsOfB.size > 0) {
3607
- relationsOfB.clear();
3608
- }
3609
- for (const previousOwner of previousOwnersToDispose) {
3610
- const sorted = [newRelationB, previousOwner].sort();
3611
- const compositeKey = `"${sorted[0]}:${sorted[1]}"`;
3612
- this.molecules.delete(compositeKey);
3613
- }
3614
- }
3615
- if (!newRelationBIsAlreadyRelated) {
3616
- relationsOfB.add(a);
3617
- }
3618
- nextRelationsOfA.add(newRelationB);
3619
- }
3620
- return true;
3621
- });
3622
- return relationsOfA;
3623
- });
3624
- };
3625
- const replaceRelationsUnsafely = (toolkit, a, newRelationsOfA) => {
3626
- const { set } = toolkit;
3627
- set(relatedKeysAtoms, a, (relationsOfA) => {
3628
- relationsOfA.transaction((nextRelationsOfA) => {
3629
- for (const newRelationB of newRelationsOfA) {
3630
- nextRelationsOfA.add(newRelationB);
3631
- }
3632
- return true;
3633
- });
3634
- return relationsOfA;
3635
- });
3636
- for (const newRelationB of newRelationsOfA) {
3637
- set(relatedKeysAtoms, newRelationB, (newRelationsB) => {
3638
- newRelationsB.add(a);
3639
- return newRelationsB;
3640
- });
3641
- }
3642
- return true;
3643
- };
3644
- const has = (toolkit, a, b) => {
3645
- const aKeys = getRelatedKeys(toolkit, a);
3646
- return b ? aKeys.has(b) : aKeys.size > 0;
3647
- };
3648
- const baseExternalStoreConfiguration = {
3649
- getRelatedKeys: (key) => getRelatedKeys(this.toolkit, key),
3650
- addRelation: (a, b) => {
3651
- this.store.moleculeJoins.set(
3652
- a,
3653
- options.key
3654
- );
3655
- this.store.moleculeJoins.set(
3656
- b,
3657
- options.key
3658
- );
3659
- addRelation(this.toolkit, a, b);
3660
- },
3661
- deleteRelation: (a, b) => {
3662
- deleteRelation(this.toolkit, a, b);
3663
- },
3664
- replaceRelationsSafely: (a, bs) => {
3665
- replaceRelationsSafely(this.toolkit, a, bs);
3666
- },
3667
- replaceRelationsUnsafely: (a, bs) => {
3668
- replaceRelationsUnsafely(this.toolkit, a, bs);
3669
- },
3670
- has: (a, b) => has(this.toolkit, a, b)
3671
- };
3672
- let externalStore;
3673
- let contentAtoms;
3674
- if (defaultContent) {
3675
- contentAtoms = createRegularAtomFamily(
3676
- store,
3677
- {
3678
- key: `${options.key}/content`,
3679
- default: defaultContent
3680
- },
3681
- [`join`, `content`]
3682
- );
3683
- const getContent = ({ get }, key) => get(contentAtoms, key);
3684
- const setContent = ({ set }, key, content) => {
3685
- set(contentAtoms, key, content);
3686
- };
3687
- const externalStoreWithContentConfiguration = {
3688
- getContent: (contentKey) => {
3689
- const content = getContent(this.toolkit, contentKey);
3690
- return content;
3691
- },
3692
- setContent: (contentKey, content) => {
3693
- setContent(this.toolkit, contentKey, content);
3694
- },
3695
- deleteContent: (contentKey) => {
3696
- this.realm.deallocate(contentKey);
3697
- }
3698
- };
3699
- externalStore = Object.assign(
3700
- baseExternalStoreConfiguration,
3701
- externalStoreWithContentConfiguration
3702
- );
3703
- } else {
3704
- externalStore = baseExternalStoreConfiguration;
3705
- }
3706
- const relations = new Junction(
3707
- options,
3708
- {
3709
- externalStore,
3710
- isAType: options.isAType,
3711
- isBType: options.isBType,
3712
- makeContentKey: (...args) => {
3713
- const [a, b] = args;
3714
- const sorted = args.sort();
3715
- const compositeKey = `${sorted[0]}:${sorted[1]}`;
3716
- const aMolecule = store.molecules.get(stringifyJson(a));
3717
- const bMolecule = store.molecules.get(stringifyJson(b));
3718
- if (!aMolecule) {
3719
- this.realm.allocate(options.key, a);
3720
- }
3721
- if (!bMolecule) {
3722
- this.realm.allocate(options.key, b);
3723
- }
3724
- this.realm.allocate(a, compositeKey, `all`);
3725
- this.realm.claim(b, compositeKey);
3726
- this.store.moleculeJoins.set(compositeKey, options.key);
3727
- return compositeKey;
3728
- }
3729
- }
3730
- );
3731
- const createSingleKeySelectorFamily = () => createReadonlySelectorFamily(
3732
- store,
3733
- {
3734
- key: `${options.key}/singleRelatedKey`,
3735
- get: (key) => ({ get }) => {
3736
- const relatedKeys = get(relatedKeysAtoms, key);
3737
- for (const relatedKey of relatedKeys) {
3738
- return relatedKey;
3739
- }
3740
- return null;
3741
- }
3742
- },
3743
- [`join`, `keys`]
3744
- );
3745
- const getMultipleKeySelectorFamily = () => {
3746
- return createReadonlySelectorFamily(
3747
- store,
3748
- {
3749
- key: `${options.key}/multipleRelatedKeys`,
3750
- get: (key) => ({ get }) => {
3751
- const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
3752
- const json = get(jsonFamily, key);
3753
- return json.members;
3754
- }
3755
- },
3756
- [`join`, `keys`]
3757
- );
3758
- };
3759
- const createSingleEntrySelectorFamily = () => createReadonlySelectorFamily(
3760
- store,
3761
- {
3762
- key: `${options.key}/singleRelatedEntry`,
3763
- get: (x) => ({ get }) => {
3764
- const relatedKeys = get(relatedKeysAtoms, x);
3765
- for (const y of relatedKeys) {
3766
- let a = relations.isAType?.(x) ? x : void 0;
3767
- let b = a === void 0 ? x : void 0;
3768
- a ??= y;
3769
- b ??= y;
3770
- const contentKey = relations.makeContentKey(a, b);
3771
- const content = get(contentAtoms, contentKey);
3772
- return [y, content];
3773
- }
3774
- return null;
3775
- }
3776
- },
3777
- [`join`, `entries`]
3778
- );
3779
- const getMultipleEntrySelectorFamily = () => createReadonlySelectorFamily(
3780
- store,
3781
- {
3782
- key: `${options.key}/multipleRelatedEntries`,
3783
- get: (x) => ({ get }) => {
3784
- const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
3785
- const json = get(jsonFamily, x);
3786
- return json.members.map((y) => {
3787
- let a = relations.isAType?.(x) ? x : void 0;
3788
- let b = a === void 0 ? x : void 0;
3789
- a ??= y;
3790
- b ??= y;
3791
- const contentKey = relations.makeContentKey(a, b);
3792
- const content = get(contentAtoms, contentKey);
3793
- return [y, content];
3794
- });
3795
- }
3796
- },
3797
- [`join`, `entries`]
3798
- );
3799
- switch (options.cardinality) {
3800
- case `1:1`: {
3801
- const singleRelatedKeySelectors = createSingleKeySelectorFamily();
3802
- const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
3803
- const stateKeyB = `${bSide}KeyOf${capitalize(aSide)}`;
3804
- const baseStates = {
3805
- [stateKeyA]: singleRelatedKeySelectors,
3806
- [stateKeyB]: singleRelatedKeySelectors
3807
- };
3808
- let states;
3809
- if (defaultContent) {
3810
- const singleEntrySelectors = createSingleEntrySelectorFamily();
3811
- const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}`;
3812
- const entriesStateKeyB = `${bSide}EntryOf${capitalize(aSide)}`;
3813
- const contentStates = {
3814
- [entriesStateKeyA]: singleEntrySelectors,
3815
- [entriesStateKeyB]: singleEntrySelectors
3816
- };
3817
- states = Object.assign(baseStates, contentStates);
3818
- } else {
3819
- states = baseStates;
3820
- }
3821
- this.relations = relations;
3822
- this.states = states;
3823
- break;
3824
- }
3825
- case `1:n`: {
3826
- const singleRelatedKeySelectors = createSingleKeySelectorFamily();
3827
- const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
3828
- const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
3829
- const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
3830
- const baseStates = {
3831
- [stateKeyA]: singleRelatedKeySelectors,
3832
- [stateKeyB]: multipleRelatedKeysSelectors
3833
- };
3834
- let states;
3835
- if (defaultContent) {
3836
- const singleRelatedEntrySelectors = createSingleEntrySelectorFamily();
3837
- const multipleRelatedEntriesSelectors = getMultipleEntrySelectorFamily();
3838
- const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}`;
3839
- const entriesStateKeyB = `${bSide}EntriesOf${capitalize(
3840
- aSide
3841
- )}`;
3842
- const contentStates = {
3843
- [entriesStateKeyA]: singleRelatedEntrySelectors,
3844
- [entriesStateKeyB]: multipleRelatedEntriesSelectors
3845
- };
3846
- states = Object.assign(baseStates, contentStates);
3847
- } else {
3848
- states = baseStates;
3849
- }
3850
- this.relations = relations;
3851
- this.states = states;
3852
- break;
3853
- }
3854
- case `n:n`: {
3855
- const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
3856
- const stateKeyA = `${aSide}KeysOf${capitalize(bSide)}`;
3857
- const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
3858
- const baseStates = {
3859
- [stateKeyA]: multipleRelatedKeysSelectors,
3860
- [stateKeyB]: multipleRelatedKeysSelectors
3861
- };
3862
- let states;
3863
- if (defaultContent) {
3864
- const multipleRelatedEntriesSelectors = getMultipleEntrySelectorFamily();
3865
- const entriesStateKeyA = `${aSide}EntriesOf${capitalize(
3866
- bSide
3867
- )}`;
3868
- const entriesStateKeyB = `${bSide}EntriesOf${capitalize(
3869
- aSide
3870
- )}`;
3871
- const contentStates = {
3872
- [entriesStateKeyA]: multipleRelatedEntriesSelectors,
3873
- [entriesStateKeyB]: multipleRelatedEntriesSelectors
3874
- };
3875
- states = Object.assign(baseStates, contentStates);
3876
- } else {
3877
- states = baseStates;
3878
- }
3879
- this.relations = relations;
3880
- this.states = states;
3881
- }
3882
- }
3883
- }
3884
- };
3885
-
3886
- // internal/src/join/get-join.ts
3887
- function getJoin(token, store) {
3888
- let myJoin = store.joins.get(token.key);
3889
- if (myJoin === void 0) {
3890
- const rootJoinMap = IMPLICIT.STORE.joins;
3891
- const rootJoin = rootJoinMap.get(token.key);
3892
- if (rootJoin === void 0) {
3893
- throw new Error(
3894
- `Join "${token.key}" not found in store "${store.config.name}"`
3895
- );
3896
- }
3897
- myJoin = new Join(rootJoin.options, rootJoin.defaultContent, store);
3898
- store.joins.set(token.key, myJoin);
3899
- }
3900
- return myJoin;
3901
- }
3902
-
3903
- // internal/src/join/edit-relations-in-store.ts
3904
- function editRelationsInStore(token, change, store) {
3905
- const myJoin = getJoin(token, store);
3906
- const target = newest(store);
3907
- if (isChildStore(target)) {
3908
- const { toolkit } = target.transactionMeta;
3909
- myJoin.transact(toolkit, ({ relations }) => {
3910
- change(relations);
3911
- });
3912
- } else {
3913
- change(myJoin.relations);
3914
- }
3915
- }
3916
-
3917
- // internal/src/join/find-relations-in-store.ts
3918
- function findRelationsInStore(token, key, store) {
3919
- const myJoin = getJoin(token, store);
3920
- let relations;
3921
- switch (token.cardinality) {
3922
- case `1:1`: {
3923
- const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
3924
- const keyBA = `${token.b}KeyOf${capitalize(token.a)}`;
3925
- relations = {
3926
- get [keyAB]() {
3927
- const familyAB = myJoin.states[keyAB];
3928
- const state = findInStore(store, familyAB, key);
3929
- return state;
3930
- },
3931
- get [keyBA]() {
3932
- const familyBA = myJoin.states[keyBA];
3933
- const state = findInStore(store, familyBA, key);
3934
- return state;
3935
- }
3936
- };
3937
- const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
3938
- if (entryAB in myJoin.states) {
3939
- const entryBA = `${token.b}EntryOf${capitalize(token.a)}`;
3940
- Object.assign(relations, {
3941
- get [entryAB]() {
3942
- const familyAB = myJoin.states[entryAB];
3943
- const state = findInStore(store, familyAB, key);
3944
- return state;
3945
- },
3946
- get [entryBA]() {
3947
- const familyBA = myJoin.states[entryBA];
3948
- const state = findInStore(store, familyBA, key);
3949
- return state;
3950
- }
3951
- });
3952
- }
3953
- break;
3954
- }
3955
- case `1:n`: {
3956
- const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
3957
- const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
3958
- relations = {
3959
- get [keyAB]() {
3960
- const familyAB = myJoin.states[keyAB];
3961
- const state = findInStore(store, familyAB, key);
3962
- return state;
3963
- },
3964
- get [keysBA]() {
3965
- const familyBA = myJoin.states[keysBA];
3966
- const state = findInStore(store, familyBA, key);
3967
- return state;
3968
- }
3969
- };
3970
- const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
3971
- if (entryAB in myJoin.states) {
3972
- const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
3973
- Object.assign(relations, {
3974
- get [entryAB]() {
3975
- const familyAB = myJoin.states[entryAB];
3976
- const state = findInStore(store, familyAB, key);
3977
- return state;
3978
- },
3979
- get [entriesBA]() {
3980
- const familyBA = myJoin.states[entriesBA];
3981
- const state = findInStore(store, familyBA, key);
3982
- return state;
3983
- }
3984
- });
3985
- }
3986
- break;
3987
- }
3988
- case `n:n`: {
3989
- const keysAB = `${token.a}KeysOf${capitalize(token.b)}`;
3990
- const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
3991
- relations = {
3992
- get [keysAB]() {
3993
- const familyAB = myJoin.states[keysAB];
3994
- const state = findInStore(store, familyAB, key);
3995
- return state;
3996
- },
3997
- get [keysBA]() {
3998
- const familyBA = myJoin.states[keysBA];
3999
- const state = findInStore(store, familyBA, key);
4000
- return state;
4001
- }
4002
- };
4003
- const entriesAB = `${token.a}EntriesOf${capitalize(token.b)}`;
4004
- if (entriesAB in myJoin.states) {
4005
- const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
4006
- Object.assign(relations, {
4007
- get [entriesAB]() {
4008
- const familyAB = myJoin.states[entriesAB];
4009
- const state = findInStore(store, familyAB, key);
4010
- return state;
4011
- },
4012
- get [entriesBA]() {
4013
- const familyBA = myJoin.states[entriesBA];
4014
- const state = findInStore(store, familyBA, key);
4015
- return state;
4016
- }
4017
- });
4018
- }
4019
- }
4020
- }
4021
- return relations;
4022
- }
4023
-
4024
- // internal/src/join/get-internal-relations-from-store.ts
4025
- function getInternalRelationsFromStore(token, store) {
4026
- const myJoin = getJoin(token, store);
4027
- const family = myJoin.core.relatedKeysAtoms;
4028
- return family;
4029
- }
4030
-
4031
- // internal/src/reserved-keys.ts
4032
- function isReservedIntrospectionKey(value) {
4033
- return value.startsWith(`\u{1F50D} `);
4034
- }
4035
-
4036
- // internal/src/timeline/create-timeline.ts
4037
- function createTimeline(store, options, data) {
4038
- const tl = {
4039
- type: `timeline`,
4040
- key: options.key,
4041
- at: 0,
4042
- timeTraveling: null,
4043
- selectorTime: null,
4044
- transactionKey: null,
4045
- ...data,
4046
- history: data?.history.map((update) => ({ ...update })) ?? [],
4047
- install: (s) => createTimeline(s, options, tl),
4048
- subject: new Subject(),
4049
- subscriptions: /* @__PURE__ */ new Map()
4050
- };
4051
- if (options.shouldCapture) {
4052
- tl.shouldCapture = options.shouldCapture;
4053
- }
4054
- const timelineKey = options.key;
4055
- const target = newest(store);
4056
- for (const initialTopic of options.scope) {
4057
- switch (initialTopic.type) {
4058
- case `atom`:
4059
- case `mutable_atom`:
4060
- {
4061
- const atomToken = initialTopic;
4062
- const atomKey = atomToken.key;
4063
- let existingTimelineKey = target.timelineTopics.getRelatedKey(atomKey);
4064
- if (`family` in atomToken) {
4065
- const familyKey = atomToken.family.key;
4066
- existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
4067
- if (existingTimelineKey) {
4068
- store.logger.error(
4069
- `\u274C`,
4070
- `timeline`,
4071
- options.key,
4072
- `Failed to add atom "${atomKey}" because its family "${familyKey}" already belongs to timeline "${existingTimelineKey}"`
4073
- );
4074
- continue;
4075
- }
4076
- }
4077
- if (existingTimelineKey) {
4078
- store.logger.error(
4079
- `\u274C`,
4080
- `timeline`,
4081
- options.key,
4082
- `Failed to add atom "${atomKey}" because it already belongs to timeline "${existingTimelineKey}"`
4083
- );
4084
- continue;
4085
- }
4086
- addAtomToTimeline(store, atomToken, tl);
4087
- }
4088
- break;
4089
- case `atom_family`:
4090
- case `mutable_atom_family`:
4091
- {
4092
- const familyToken = initialTopic;
4093
- const familyKey = familyToken.key;
4094
- const existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
4095
- if (existingTimelineKey) {
4096
- store.logger.error(
4097
- `\u274C`,
4098
- `timeline`,
4099
- options.key,
4100
- `Failed to add atom family "${familyKey}" because it already belongs to timeline "${existingTimelineKey}"`
4101
- );
4102
- continue;
4103
- }
4104
- addAtomFamilyToTimeline(store, familyToken, tl);
4105
- }
4106
- break;
4107
- }
4108
- }
4109
- store.timelines.set(options.key, tl);
4110
- const token = {
4111
- key: timelineKey,
4112
- type: `timeline`
4113
- };
4114
- store.on.timelineCreation.next(token);
4115
- return token;
4116
- }
4117
- function addAtomToTimeline(store, atomToken, tl) {
4118
- let maybeAtom = withdraw(store, atomToken);
4119
- if (maybeAtom.type === `mutable_atom`) {
4120
- const updateToken = getUpdateToken(maybeAtom);
4121
- maybeAtom = withdraw(store, updateToken);
4122
- }
4123
- const atom2 = maybeAtom;
4124
- store.timelineTopics.set(
4125
- { topicKey: atom2.key, timelineKey: tl.key },
4126
- { topicType: `atom` }
4127
- );
4128
- tl.subscriptions.set(
4129
- atom2.key,
4130
- atom2.subject.subscribe(
4131
- `timeline`,
4132
- function timelineCapturesAtomUpdate(update) {
4133
- const target = newest(store);
4134
- const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
4135
- const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
4136
- const txUpdateInProgress = target.on.transactionApplying.state?.update;
4137
- store.logger.info(
4138
- `\u23F3`,
4139
- `timeline`,
4140
- tl.key,
4141
- `atom`,
4142
- atomToken.key,
4143
- `went`,
4144
- update.oldValue,
4145
- `->`,
4146
- update.newValue,
4147
- txUpdateInProgress ? `in transaction "${txUpdateInProgress.key}"` : currentSelectorKey ? `in selector "${currentSelectorKey}"` : ``
4148
- );
4149
- if (tl.timeTraveling === null) {
4150
- if (txUpdateInProgress) {
4151
- joinTransaction(store, tl, txUpdateInProgress);
4152
- } else if (currentSelectorKey && currentSelectorTime) {
4153
- let latestUpdate = tl.history.at(-1);
4154
- if (currentSelectorTime !== tl.selectorTime) {
4155
- latestUpdate = {
4156
- type: `selector_update`,
4157
- timestamp: currentSelectorTime,
4158
- key: currentSelectorKey,
4159
- atomUpdates: []
4160
- };
4161
- latestUpdate.atomUpdates.push({
4162
- key: atom2.key,
4163
- type: `atom_update`,
4164
- ...update
4165
- });
4166
- if (tl.at !== tl.history.length) {
4167
- tl.history.splice(tl.at);
4168
- }
4169
- tl.history.push(latestUpdate);
4170
- store.logger.info(
4171
- `\u231B`,
4172
- `timeline`,
4173
- tl.key,
4174
- `got a selector_update "${currentSelectorKey}" with`,
4175
- latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
4176
- );
4177
- tl.at = tl.history.length;
4178
- tl.selectorTime = currentSelectorTime;
4179
- } else {
4180
- if (latestUpdate?.type === `selector_update`) {
4181
- latestUpdate.atomUpdates.push({
4182
- key: atom2.key,
4183
- type: `atom_update`,
4184
- ...update
4185
- });
4186
- store.logger.info(
4187
- `\u231B`,
4188
- `timeline`,
4189
- tl.key,
4190
- `set selector_update "${currentSelectorKey}" to`,
4191
- latestUpdate?.atomUpdates.map((atomUpdate) => atomUpdate.key)
4192
- );
4193
- }
4194
- }
4195
- if (latestUpdate) {
4196
- const willCaptureSelectorUpdate = tl.shouldCapture?.(latestUpdate, tl) ?? true;
4197
- if (willCaptureSelectorUpdate) {
4198
- tl.subject.next(latestUpdate);
4199
- } else {
4200
- tl.history.pop();
4201
- tl.at = tl.history.length;
4202
- }
4203
- }
4204
- } else {
4205
- const timestamp = Date.now();
4206
- tl.selectorTime = null;
4207
- if (tl.at !== tl.history.length) {
4208
- tl.history.splice(tl.at);
4209
- }
4210
- const atomUpdate = {
4211
- type: `atom_update`,
4212
- timestamp,
4213
- key: atom2.key,
4214
- oldValue: update.oldValue,
4215
- newValue: update.newValue
4216
- };
4217
- if (atom2.family) {
4218
- atomUpdate.family = atom2.family;
4219
- }
4220
- const willCapture = tl.shouldCapture?.(atomUpdate, tl) ?? true;
4221
- store.logger.info(
4222
- `\u231B`,
4223
- `timeline`,
4224
- tl.key,
4225
- `got an atom_update to "${atom2.key}"`
4226
- );
4227
- if (willCapture) {
4228
- tl.history.push(atomUpdate);
4229
- tl.at = tl.history.length;
4230
- tl.subject.next(atomUpdate);
4231
- }
4232
- }
4233
- }
4234
- }
4235
- )
4236
- );
4237
- }
4238
- function addAtomFamilyToTimeline(store, atomFamilyToken, tl) {
4239
- const family = withdraw(store, atomFamilyToken);
4240
- store.timelineTopics.set(
4241
- { topicKey: family.key, timelineKey: tl.key },
4242
- { topicType: `atom_family` }
4243
- );
4244
- tl.subscriptions.set(
4245
- family.key,
4246
- family.subject.subscribe(
4247
- `timeline`,
4248
- function timelineCapturesStateLifecycleEvent(creationOrDisposal) {
4249
- handleStateLifecycleEvent(store, creationOrDisposal, tl);
4250
- }
4251
- )
4252
- );
4253
- for (const atom2 of store.atoms.values()) {
4254
- if (atom2.family?.key === family.key) {
4255
- addAtomToTimeline(store, atom2, tl);
4256
- }
4257
- }
4258
- }
4259
- function joinTransaction(store, tl, txUpdateInProgress) {
4260
- const currentTxKey = txUpdateInProgress.key;
4261
- const currentTxInstanceId = txUpdateInProgress.id;
4262
- const currentTxToken = {
4263
- key: currentTxKey,
4264
- type: `transaction`
4265
- };
4266
- const currentTransaction = withdraw(store, currentTxToken);
4267
- if (currentTxKey && tl.transactionKey === null) {
4268
- tl.transactionKey = currentTxKey;
4269
- const unsubscribe = currentTransaction.subject.subscribe(
4270
- `timeline:${tl.key}`,
4271
- (transactionUpdate) => {
4272
- unsubscribe();
4273
- tl.transactionKey = null;
4274
- if (tl.timeTraveling === null && currentTxInstanceId) {
4275
- if (tl.at !== tl.history.length) {
4276
- tl.history.splice(tl.at);
4277
- }
4278
- const timelineTopics = store.timelineTopics.getRelatedKeys(tl.key);
4279
- const updates = filterTransactionUpdates(
4280
- transactionUpdate.updates,
4281
- timelineTopics
4282
- );
4283
- const timelineTransactionUpdate = {
4284
- timestamp: Date.now(),
4285
- ...transactionUpdate,
4286
- updates
4287
- };
4288
- const willCapture = tl.shouldCapture?.(timelineTransactionUpdate, tl) ?? true;
4289
- if (willCapture) {
4290
- tl.history.push(timelineTransactionUpdate);
4291
- tl.at = tl.history.length;
4292
- tl.subject.next(timelineTransactionUpdate);
4293
- }
4294
- }
4295
- }
4296
- );
4297
- }
4298
- }
4299
- function filterTransactionUpdates(updates, timelineTopics) {
4300
- return updates.filter((updateFromTx) => {
4301
- if (updateFromTx.type === `transaction_update`) {
4302
- return true;
4303
- }
4304
- let key;
4305
- let familyKey;
4306
- switch (updateFromTx.type) {
4307
- case `state_creation`:
4308
- case `state_disposal`:
4309
- key = updateFromTx.token.key;
4310
- familyKey = updateFromTx.token.family?.key;
4311
- break;
4312
- case `molecule_creation`:
4313
- case `molecule_disposal`:
4314
- case `molecule_transfer`:
4315
- return true;
4316
- // always include
4317
- case `atom_update`:
4318
- case `selector_update`:
4319
- key = updateFromTx.key;
4320
- familyKey = updateFromTx.family?.key;
4321
- break;
4322
- }
4323
- timelineTopics.has(key);
4324
- if (familyKey && timelineTopics.has(familyKey)) {
4325
- return true;
4326
- }
4327
- return timelineTopics.has(key);
4328
- }).map((updateFromTx) => {
4329
- if (`updates` in updateFromTx) {
4330
- return {
4331
- ...updateFromTx,
4332
- updates: filterTransactionUpdates(
4333
- updateFromTx.updates,
4334
- timelineTopics
4335
- )
4336
- };
4337
- }
4338
- return updateFromTx;
4339
- });
4340
- }
4341
- function handleStateLifecycleEvent(store, event, tl) {
4342
- const timestamp = Date.now();
4343
- const timelineEvent = Object.assign(event, {
4344
- timestamp
4345
- });
4346
- if (!tl.timeTraveling) {
4347
- const target = newest(store);
4348
- if (isChildStore(target)) ; else {
4349
- const txUpdateInProgress = target.on.transactionApplying.state;
4350
- if (txUpdateInProgress) {
4351
- joinTransaction(store, tl, txUpdateInProgress.update);
4352
- } else {
4353
- tl.history.push(timelineEvent);
4354
- tl.at = tl.history.length;
4355
- tl.subject.next(timelineEvent);
4356
- }
4357
- }
4358
- }
4359
- switch (event.type) {
4360
- case `state_creation`:
4361
- addAtomToTimeline(store, event.token, tl);
4362
- break;
4363
- case `state_disposal`:
4364
- tl.subscriptions.get(event.token.key)?.();
4365
- tl.subscriptions.delete(event.token.key);
4366
- break;
4367
- }
4368
- }
4369
-
4370
- // internal/src/timeline/time-travel.ts
4371
- var timeTravel = (store, action, token) => {
4372
- store.logger.info(
4373
- action === `redo` ? `\u23E9` : `\u23EA`,
4374
- `timeline`,
4375
- token.key,
4376
- action
4377
- );
4378
- const timelineData = store.timelines.get(token.key);
4379
- if (!timelineData) {
4380
- store.logger.error(
4381
- `\u{1F41E}`,
4382
- `timeline`,
4383
- token.key,
4384
- `Failed to ${action}. This timeline has not been initialized.`
4385
- );
4386
- return;
4387
- }
4388
- if (action === `redo` && timelineData.at === timelineData.history.length || action === `undo` && timelineData.at === 0) {
4389
- store.logger.warn(
4390
- `\u{1F481}`,
4391
- `timeline`,
4392
- token.key,
4393
- `Failed to ${action} at the ${action === `redo` ? `end` : `beginning`} of timeline "${token.key}". There is nothing to ${action}.`
4394
- );
4395
- return;
4396
- }
4397
- timelineData.timeTraveling = action === `redo` ? `into_future` : `into_past`;
4398
- if (action === `undo`) {
4399
- --timelineData.at;
4400
- }
4401
- const update = timelineData.history[timelineData.at];
4402
- const applying = action === `redo` ? `newValue` : `oldValue`;
4403
- switch (update.type) {
4404
- case `atom_update`: {
4405
- ingestAtomUpdate(applying, update, store);
4406
- break;
4407
- }
4408
- case `selector_update`: {
4409
- ingestSelectorUpdate(applying, update, store);
4410
- break;
4411
- }
4412
- case `transaction_update`: {
4413
- ingestTransactionUpdate(applying, update, store);
4414
- break;
4415
- }
4416
- case `state_creation`: {
4417
- ingestCreationEvent(update, applying, store);
4418
- break;
4419
- }
4420
- case `state_disposal`: {
4421
- ingestDisposalEvent(update, applying, store);
4422
- break;
4423
- }
4424
- }
4425
- if (action === `redo`) {
4426
- ++timelineData.at;
4427
- }
4428
- timelineData.subject.next(action);
4429
- timelineData.timeTraveling = null;
4430
- store.logger.info(
4431
- `\u23F9\uFE0F`,
4432
- `timeline`,
4433
- token.key,
4434
- `"${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
4435
- );
4436
- };
4437
-
4438
- // json/src/select-json.ts
4439
- var selectJson = (atom2, transform, store = IMPLICIT.STORE) => {
4440
- return createStandaloneSelector(store, {
4441
- key: `${atom2.key}:JSON`,
4442
- get: ({ get }) => transform.toJson(get(atom2)),
4443
- set: ({ set }, newValue) => {
4444
- set(atom2, transform.fromJson(newValue));
4445
- }
4446
- });
4447
- };
4448
-
4449
- // json/src/select-json-family.ts
4450
- function selectJsonFamily(store, atomFamilyToken, transform) {
4451
- const jsonFamily = createWritableSelectorFamily(
4452
- store,
4453
- {
4454
- key: `${atomFamilyToken.key}:JSON`,
4455
- get: (key) => ({ get }) => {
4456
- const baseState = get(atomFamilyToken, key);
4457
- return transform.toJson(baseState);
4458
- },
4459
- set: (key) => ({ set }, newValue) => {
4460
- set(atomFamilyToken, key, transform.fromJson(newValue));
4461
- }
4462
- },
4463
- [`mutable`, `json`]
4464
- );
4465
- return jsonFamily;
4466
- }
4467
-
4468
- // json/src/index.ts
4469
- var parseJson = (str) => JSON.parse(str);
4470
- var stringifyJson = (json) => JSON.stringify(json);
4471
- var JSON_PROTOTYPES = [
4472
- Array.prototype,
4473
- Boolean.prototype,
4474
- Number.prototype,
4475
- Object.prototype,
4476
- String.prototype
4477
- ];
4478
- var isJson = (input) => {
4479
- if (input === null) return true;
4480
- if (input === void 0) return false;
4481
- const prototype = Object.getPrototypeOf(input);
4482
- return JSON_PROTOTYPES.includes(prototype);
4483
- };
4484
- var JSON_TYPE_NAMES = [
4485
- `array`,
4486
- `boolean`,
4487
- `null`,
4488
- `number`,
4489
- `object`,
4490
- `string`
4491
- ];
4492
- var JSON_DEFAULTS = {
4493
- array: [],
4494
- boolean: false,
4495
- null: null,
4496
- number: 0,
4497
- object: {},
4498
- string: ``
4499
- };
4500
-
4501
- export { $claim, Anarchy, AtomIOLogger, CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, JSON_DEFAULTS, JSON_TYPE_NAMES, Join, Junction, LOG_LEVELS, LazyMap, NotFoundError, Realm, SetRTX, Silo, StatefulSubject, Store, Subject, T$, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, allocateIntoStore, applyTransaction, arbitrary, assignTransactionToContinuity, atom, atomFamily, become, belongsTo, buildTransaction, cacheValue, capitalize, claimWithinStore, clearStore, closeOperation, counterfeit, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deallocateFromStore, deposit, disposeAtom, disposeFromStore, disposeSelector, disposeState, editRelations, editRelationsInStore, evictCachedValue, findInStore, findRelations, findRelationsInStore, findState, fromEntries, fuseWithinStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getInternalRelations, getInternalRelationsFromStore, getJoin, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getState, getTrace, getUpdateFamily, getUpdateToken, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, isAtomDefault, isAtomKey, isChildStore, isDone, isJson, isReadonlySelectorKey, isReservedIntrospectionKey, isRootStore, isSelectorKey, isStateKey, isToken, isTransceiver, join, makeRootMoleculeInStore, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, parseJson, prettyPrintTokenType, readCachedValue, readOrComputeValue, recallState, redo, registerSelector, runTransaction, seekInStore, selectJson, selectJsonFamily, selector, selectorFamily, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, setState, simpleLog, simpleLogger, stringifyJson, subscribe, subscribeInStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, timeline, toEntries, traceAllSelectorAtoms, traceSelectorAtoms, transaction, undo, updateSelectorAtoms, withdraw };