@adobe/data 0.1.3 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (591) hide show
  1. package/.cursorrules +28 -0
  2. package/.eslintrc.cjs +48 -0
  3. package/.github/CONTRIBUTING.md +47 -0
  4. package/CODE_OF_CONDUCT.md +79 -0
  5. package/LICENSE +21 -0
  6. package/README.md +2 -2
  7. package/asconfig.json +22 -0
  8. package/assembly/index.ts +85 -0
  9. package/assembly/tsconfig.json +17 -0
  10. package/c/build_run.sh +2 -0
  11. package/c/vector_addition +0 -0
  12. package/c/vector_addition.c +125 -0
  13. package/{cache/functions/types.js → config/license.js} +0 -2
  14. package/docs/perftest.html +28 -0
  15. package/index.html +10 -0
  16. package/package.json +50 -28
  17. package/scripts/deploy-docs.sh +41 -0
  18. package/{assembly-test/assembly.test.js → src/assembly-test/assembly.test.ts} +4 -4
  19. package/src/cache/async-cache.ts +38 -0
  20. package/{cache/blob-store.test.js → src/cache/blob-store.test.ts} +41 -7
  21. package/src/cache/blob-store.ts +278 -0
  22. package/src/cache/data-cache.test.ts +61 -0
  23. package/src/cache/data-cache.ts +183 -0
  24. package/src/cache/expiring-data-cache.test.ts +81 -0
  25. package/src/cache/expiring-data-cache.ts +61 -0
  26. package/src/cache/fallback-async-cache.ts +49 -0
  27. package/src/cache/functions/async-data-function.ts +25 -0
  28. package/src/cache/functions/functions.test.ts +84 -0
  29. package/{cache/functions/get-cached.test.js → src/cache/functions/get-cached.test.ts} +24 -7
  30. package/{cache/functions/get-cached.js → src/cache/functions/get-cached.ts} +12 -6
  31. package/{cache/functions/hashing/blob-to-hash.js → src/cache/functions/hashing/blob-to-hash.ts} +20 -18
  32. package/{cache/functions/hashing/buffer-to-hash.js → src/cache/functions/hashing/buffer-to-hash.ts} +7 -7
  33. package/src/cache/functions/hashing/hashing.test.ts +95 -0
  34. package/{cache/functions/hashing/index.js → src/cache/functions/hashing/index.ts} +1 -1
  35. package/{cache/functions/hashing/json-to-hash.js → src/cache/functions/hashing/json-to-hash.ts} +3 -3
  36. package/{cache/functions/hashing/string-to-hash.js → src/cache/functions/hashing/string-to-hash.ts} +11 -10
  37. package/{cache/functions/index.js → src/cache/functions/index.ts} +2 -4
  38. package/{cache/functions/memoize.js → src/cache/functions/memoize.ts} +22 -15
  39. package/src/cache/functions/prevent-parallel-execution.ts +50 -0
  40. package/src/cache/get-persistent-cache.ts +62 -0
  41. package/{cache/index.js → src/cache/index.ts} +9 -3
  42. package/src/cache/managed-array.ts +243 -0
  43. package/{cache/managed-async-cache.browser.test.js → src/cache/managed-async-cache.browser.test.ts} +27 -24
  44. package/src/cache/managed-async-cache.ts +78 -0
  45. package/src/cache/memory-allocator.ts +176 -0
  46. package/src/cache/memory-async-cache.ts +51 -0
  47. package/src/data.ts +38 -0
  48. package/src/ecs/README.md +21 -0
  49. package/src/ecs/archetype/archetype.ts +39 -0
  50. package/src/ecs/archetype/create-archetype.test.ts +115 -0
  51. package/src/ecs/archetype/create-archetype.ts +52 -0
  52. package/src/ecs/archetype/delete-row.test.ts +110 -0
  53. package/src/ecs/archetype/delete-row.ts +37 -0
  54. package/src/ecs/archetype/index.ts +24 -0
  55. package/src/ecs/component-schemas.ts +24 -0
  56. package/src/ecs/core-components.ts +443 -0
  57. package/src/ecs/database/create-database.test.ts +745 -0
  58. package/src/ecs/database/create-database.ts +205 -0
  59. package/src/ecs/database/database.ts +81 -0
  60. package/src/ecs/database/index.ts +24 -0
  61. package/src/ecs/database/observe-dependent-value.test.ts +198 -0
  62. package/src/ecs/database/observe-dependent-value.ts +78 -0
  63. package/src/ecs/database/transactional-store/create-transactional-store.test.ts +250 -0
  64. package/src/ecs/database/transactional-store/create-transactional-store.ts +281 -0
  65. package/{ecs/ecs/ecs-types.js → src/ecs/database/transactional-store/index.ts} +1 -2
  66. package/src/ecs/database/transactional-store/transactional-store.ts +80 -0
  67. package/src/ecs/entity-location-table/create-entity-location-table.test.ts +170 -0
  68. package/src/ecs/entity-location-table/create-entity-location-table.ts +96 -0
  69. package/src/ecs/entity-location-table/entity-location-table.ts +30 -0
  70. package/{core/schema/schema.js → src/ecs/entity-location-table/entity-location.ts} +11 -11
  71. package/src/ecs/entity-location-table/index.ts +23 -0
  72. package/src/ecs/entity.ts +26 -0
  73. package/src/ecs/index.ts +26 -0
  74. package/src/ecs/store/core/core.ts +71 -0
  75. package/src/ecs/store/core/create-core.test.ts +440 -0
  76. package/src/ecs/store/core/create-core.ts +168 -0
  77. package/{cache/async-cache.js → src/ecs/store/core/index.ts} +1 -2
  78. package/src/ecs/store/create-store.test.ts +562 -0
  79. package/src/ecs/store/create-store.ts +97 -0
  80. package/src/ecs/store/index.ts +23 -0
  81. package/{types/types.js → src/ecs/store/resource-components.ts} +2 -6
  82. package/src/ecs/store/store.ts +55 -0
  83. package/src/equals-shallow.test.ts +133 -0
  84. package/src/equals-shallow.ts +37 -0
  85. package/src/equals.test.ts +175 -0
  86. package/src/equals.ts +70 -0
  87. package/src/index.ts +27 -0
  88. package/src/internal/array-buffer-like/copy.ts +469 -0
  89. package/src/internal/array-buffer-like/grow.ts +53 -0
  90. package/{core/index.js → src/internal/array-buffer-like/index.ts} +4 -4
  91. package/src/internal/array-buffer-like/is-array-buffer.ts +445 -0
  92. package/src/internal/array-buffer-like/is-shared-array-buffer.ts +445 -0
  93. package/{core/functions/is-async-generator.js → src/internal/async-generator/is-async-generator.ts} +2 -2
  94. package/{core/schema.js → src/internal/data-view-32/create-data-view-32.ts} +8 -11
  95. package/src/internal/data-view-32/data-view-32.ts +447 -0
  96. package/{ecs/action-ecs/index.js → src/internal/data-view-32/index.ts} +2 -2
  97. package/src/internal/function/memoize-factory.ts +12 -0
  98. package/src/internal/object/index.ts +23 -0
  99. package/{cache/functions/bind-functions.js → src/internal/object/map-entries.ts} +6 -11
  100. package/src/internal/promise/is-promise.ts +28 -0
  101. package/src/internal/typed-array/get-byte-size.ts +50 -0
  102. package/src/internal/typed-array/index.ts +24 -0
  103. package/src/internal/typed-array/typed-array-constructer.ts +32 -0
  104. package/src/internal/typed-array/typed-array.ts +25 -0
  105. package/src/is-data.ts +47 -0
  106. package/src/lit/decorators/apply-decorator.ts +24 -0
  107. package/src/lit/decorators/apply-service-decorators.ts +13 -0
  108. package/src/lit/decorators/index.ts +24 -0
  109. package/src/lit/decorators/require-service.ts +19 -0
  110. package/src/lit/elements/index.ts +3 -0
  111. package/src/lit/elements/service-application.ts +26 -0
  112. package/src/lit/elements/service-context.ts +3 -0
  113. package/src/lit/elements/service-element.ts +18 -0
  114. package/src/lit/hooks/component/component.ts +10 -0
  115. package/src/lit/hooks/component/stack.ts +17 -0
  116. package/src/lit/hooks/index.ts +13 -0
  117. package/src/lit/hooks/use-connected.ts +39 -0
  118. package/src/lit/hooks/use-effect.ts +17 -0
  119. package/src/lit/hooks/use-element.ts +8 -0
  120. package/src/lit/hooks/use-memo.ts +14 -0
  121. package/src/lit/hooks/use-observable-values.ts +9 -0
  122. package/src/lit/hooks/use-observable.ts +13 -0
  123. package/src/lit/hooks/use-ref.ts +6 -0
  124. package/src/lit/hooks/use-resize-observer.ts +27 -0
  125. package/src/lit/hooks/use-state.ts +17 -0
  126. package/src/lit/hooks/use-window-event.ts +14 -0
  127. package/src/lit/hooks/with-hooks.ts +20 -0
  128. package/src/lit/index.ts +3 -0
  129. package/src/mutable-clone.ts +29 -0
  130. package/{core/data.test.js → src/normalize.test.ts} +22 -22
  131. package/src/normalize.ts +37 -0
  132. package/src/observe/create-observable-event.ts +47 -0
  133. package/src/observe/create-observable-state.ts +51 -0
  134. package/src/observe/create-persisted-state.test.ts +143 -0
  135. package/src/observe/create-persisted-state.ts +60 -0
  136. package/src/observe/create-query-state.ts +70 -0
  137. package/{observe/from-array.js → src/observe/from-array.ts} +14 -3
  138. package/{service/service.js → src/observe/from-constant.ts} +13 -4
  139. package/{observe/from-element-id.js → src/observe/from-element-id.ts} +44 -39
  140. package/src/observe/from-element-properties-and-events.ts +47 -0
  141. package/{observe/from-element-property.js → src/observe/from-element-property.ts} +33 -25
  142. package/src/observe/from-promise-with-error.ts +51 -0
  143. package/src/observe/from-promise.ts +49 -0
  144. package/src/observe/from-properties.ts +67 -0
  145. package/{observe/index.js → src/observe/index.ts} +4 -1
  146. package/src/observe/observe.test.ts +467 -0
  147. package/src/observe/to-promise.ts +40 -0
  148. package/src/observe/to-properties.ts +41 -0
  149. package/src/observe/types.ts +40 -0
  150. package/src/observe/with-async-map.ts +37 -0
  151. package/src/observe/with-batch.test.ts +141 -0
  152. package/src/observe/with-batch.ts +67 -0
  153. package/{core/data.js → src/observe/with-cache.ts} +32 -26
  154. package/src/observe/with-copy.ts +32 -0
  155. package/src/observe/with-deduplicate-data.ts +43 -0
  156. package/src/observe/with-deduplicate.ts +41 -0
  157. package/src/observe/with-default.ts +48 -0
  158. package/src/observe/with-lazy.test.ts +68 -0
  159. package/{core/functions/is-promise.js → src/observe/with-lazy.ts} +17 -5
  160. package/{observe/with-map-data.js → src/observe/with-map-data.ts} +9 -3
  161. package/src/observe/with-map.ts +36 -0
  162. package/src/observe/with-optional.ts +47 -0
  163. package/src/observe/with-unwrap.ts +54 -0
  164. package/src/old-ecs/action-ecs/action-ecs.test.ts +420 -0
  165. package/src/old-ecs/action-ecs/action-ecs.ts +274 -0
  166. package/src/old-ecs/action-ecs/action-types.ts +178 -0
  167. package/src/old-ecs/action-ecs/index.ts +29 -0
  168. package/{service/sequential-action.js → src/old-ecs/action-ecs/sequential-action.ts} +19 -4
  169. package/src/old-ecs/core-ecs/core-ecs-serialization.test.ts +244 -0
  170. package/src/old-ecs/core-ecs/core-ecs-types.ts +183 -0
  171. package/src/old-ecs/core-ecs/core-ecs.test.ts +474 -0
  172. package/src/old-ecs/core-ecs/core-ecs.ts +640 -0
  173. package/{core/functions/index.js → src/old-ecs/core-ecs/index.ts} +9 -4
  174. package/src/old-ecs/ecs/ecs-types.ts +189 -0
  175. package/src/old-ecs/ecs/ecs-where-functions.ts +95 -0
  176. package/src/old-ecs/ecs/ecs.test.ts +461 -0
  177. package/src/old-ecs/ecs/ecs.ts +279 -0
  178. package/{ecs/core-ecs/core-ecs-types.js → src/old-ecs/ecs/index.ts} +2 -2
  179. package/src/old-ecs/entity.ts +26 -0
  180. package/{ecs/index.js → src/old-ecs/index.ts} +1 -1
  181. package/{ecs/transaction-ecs/index.js → src/old-ecs/transaction-ecs/index.ts} +0 -1
  182. package/src/old-ecs/transaction-ecs/transaction-ecs.test.ts +725 -0
  183. package/src/old-ecs/transaction-ecs/transaction-ecs.ts +283 -0
  184. package/src/old-ecs/transaction-ecs/transaction-types.ts +248 -0
  185. package/src/old-ecs/transaction-ecs/transactions.ts +243 -0
  186. package/src/perftest/ecs-perf.ts +255 -0
  187. package/src/perftest/helper-functions.ts +31 -0
  188. package/src/perftest/horizon-perf.ts +132 -0
  189. package/{perftest/index.js → src/perftest/index.ts} +9 -7
  190. package/src/perftest/perf-test.ts +193 -0
  191. package/src/perftest/perf.md +90 -0
  192. package/src/perftest/vanilla-perf.ts +136 -0
  193. package/src/schema/boolean.ts +5 -0
  194. package/src/schema/dynamic/deep-merge.test.ts +100 -0
  195. package/src/schema/dynamic/deep-merge.ts +67 -0
  196. package/{core/schema/dynamic/enumerate-patches.test.js → src/schema/dynamic/enumerate-patches.test.ts} +49 -23
  197. package/{core/schema/dynamic/enumerate-patches.js → src/schema/dynamic/enumerate-patches.ts} +44 -4
  198. package/{core/schema/dynamic/get-dynamic-schema.test.js → src/schema/dynamic/get-dynamic-schema.test.ts} +41 -6
  199. package/src/schema/dynamic/get-dynamic-schema.ts +48 -0
  200. package/src/schema/dynamic/index.ts +22 -0
  201. package/src/schema/f32.ts +30 -0
  202. package/src/schema/i32.ts +31 -0
  203. package/src/schema/index.ts +32 -0
  204. package/{cache/functions/omit.js → src/schema/nullable.ts} +10 -7
  205. package/src/schema/schema.ts +229 -0
  206. package/src/schema/time.ts +5 -0
  207. package/src/schema/true.ts +26 -0
  208. package/src/schema/tuple.ts +5 -0
  209. package/src/schema/u32.ts +31 -0
  210. package/{core/schema/validation/is-valid.test.js → src/schema/validation/is-valid.test.ts} +6 -3
  211. package/{core/functions/array-equals.js → src/schema/validation/is-valid.ts} +8 -10
  212. package/{core/schema/validation/validate.test.js → src/schema/validation/validate.test.ts} +18 -4
  213. package/{core/schema/validation/validate.js → src/schema/validation/validate.ts} +9 -6
  214. package/{core/functions/with-validation.test.js → src/schema/validation/with-validation.test.ts} +28 -12
  215. package/{core/functions/with-validation.js → src/schema/validation/with-validation.ts} +14 -10
  216. package/src/schema.test.ts +55 -0
  217. package/src/service/add-observable-actions.ts +207 -0
  218. package/{service/index.js → src/service/index.ts} +4 -4
  219. package/src/service/is-service.ts +7 -0
  220. package/src/service/progressive-result.ts +141 -0
  221. package/src/service/service.ts +27 -0
  222. package/src/table/add-row.ts +42 -0
  223. package/src/table/create-table.ts +36 -0
  224. package/src/table/delete-row.ts +42 -0
  225. package/src/table/ensure-capacity.ts +37 -0
  226. package/src/table/get-row-data.ts +31 -0
  227. package/src/table/index.ts +29 -0
  228. package/src/table/row-index.ts +26 -0
  229. package/src/table/table.ts +32 -0
  230. package/src/table/update-row.ts +35 -0
  231. package/src/tsconfig.json +6 -0
  232. package/src/typed-buffer/copy-to-gpu-buffer.ts +23 -0
  233. package/{cache/expiring-data-cache.js → src/typed-buffer/create-array-buffer.ts} +31 -25
  234. package/src/typed-buffer/create-number-buffer.ts +90 -0
  235. package/src/typed-buffer/create-struct-buffer.ts +93 -0
  236. package/src/typed-buffer/create-typed-buffer.ts +49 -0
  237. package/src/typed-buffer/index.ts +26 -0
  238. package/src/typed-buffer/structs/assert-struct.ts +37 -0
  239. package/src/typed-buffer/structs/create-read-struct.test.ts +202 -0
  240. package/src/typed-buffer/structs/create-read-struct.ts +77 -0
  241. package/src/typed-buffer/structs/create-write-struct.ts +73 -0
  242. package/src/typed-buffer/structs/get-field-offset.ts +36 -0
  243. package/src/typed-buffer/structs/get-struct-layout.test.ts +146 -0
  244. package/src/typed-buffer/structs/get-struct-layout.ts +222 -0
  245. package/src/typed-buffer/structs/index.ts +22 -0
  246. package/src/typed-buffer/structs/read-struct.ts +25 -0
  247. package/src/typed-buffer/structs/struct-layout.ts +465 -0
  248. package/src/typed-buffer/structs/write-struct.test.ts +195 -0
  249. package/src/typed-buffer/structs/write-struct.ts +25 -0
  250. package/src/typed-buffer/typed-buffer.test.ts +253 -0
  251. package/src/typed-buffer/typed-buffer.ts +41 -0
  252. package/src/types/assert.ts +22 -0
  253. package/src/types/equal.ts +24 -0
  254. package/{types/index.js → src/types/index.ts} +3 -1
  255. package/src/types/types.ts +166 -0
  256. package/tsconfig-base.json +25 -0
  257. package/tsconfig.json +8 -0
  258. package/typedoc.json +22 -0
  259. package/vite.config.js +16 -0
  260. package/assembly/index.d.ts +0 -30
  261. package/assembly/index.js +0 -18
  262. package/assembly/index.wasm +0 -0
  263. package/assembly/index.wasm.map +0 -1
  264. package/assembly-test/assembly.test.d.ts +0 -1
  265. package/assembly-test/assembly.test.js.map +0 -1
  266. package/cache/async-cache.d.ts +0 -15
  267. package/cache/async-cache.js.map +0 -1
  268. package/cache/blob-store.d.ts +0 -94
  269. package/cache/blob-store.js +0 -191
  270. package/cache/blob-store.js.map +0 -1
  271. package/cache/blob-store.test.d.ts +0 -1
  272. package/cache/blob-store.test.js.map +0 -1
  273. package/cache/data-cache.d.ts +0 -38
  274. package/cache/data-cache.js +0 -96
  275. package/cache/data-cache.js.map +0 -1
  276. package/cache/data-cache.test.d.ts +0 -1
  277. package/cache/data-cache.test.js +0 -50
  278. package/cache/data-cache.test.js.map +0 -1
  279. package/cache/expiring-data-cache.d.ts +0 -6
  280. package/cache/expiring-data-cache.js.map +0 -1
  281. package/cache/expiring-data-cache.test.d.ts +0 -1
  282. package/cache/expiring-data-cache.test.js +0 -62
  283. package/cache/expiring-data-cache.test.js.map +0 -1
  284. package/cache/fallback-async-cache.d.ts +0 -7
  285. package/cache/fallback-async-cache.js +0 -22
  286. package/cache/fallback-async-cache.js.map +0 -1
  287. package/cache/functions/bind-functions.d.ts +0 -6
  288. package/cache/functions/bind-functions.js.map +0 -1
  289. package/cache/functions/functions.test.d.ts +0 -1
  290. package/cache/functions/functions.test.js +0 -79
  291. package/cache/functions/functions.test.js.map +0 -1
  292. package/cache/functions/get-cached.d.ts +0 -11
  293. package/cache/functions/get-cached.js.map +0 -1
  294. package/cache/functions/get-cached.test.d.ts +0 -1
  295. package/cache/functions/get-cached.test.js.map +0 -1
  296. package/cache/functions/hashing/blob-to-hash.d.ts +0 -4
  297. package/cache/functions/hashing/blob-to-hash.js.map +0 -1
  298. package/cache/functions/hashing/buffer-to-hash.d.ts +0 -4
  299. package/cache/functions/hashing/buffer-to-hash.js.map +0 -1
  300. package/cache/functions/hashing/hashing.test.d.ts +0 -1
  301. package/cache/functions/hashing/hashing.test.js +0 -95
  302. package/cache/functions/hashing/hashing.test.js.map +0 -1
  303. package/cache/functions/hashing/index.d.ts +0 -4
  304. package/cache/functions/hashing/index.js.map +0 -1
  305. package/cache/functions/hashing/json-to-hash.d.ts +0 -4
  306. package/cache/functions/hashing/json-to-hash.js.map +0 -1
  307. package/cache/functions/hashing/string-to-hash.d.ts +0 -4
  308. package/cache/functions/hashing/string-to-hash.js.map +0 -1
  309. package/cache/functions/index.d.ts +0 -5
  310. package/cache/functions/index.js.map +0 -1
  311. package/cache/functions/memoize.d.ts +0 -12
  312. package/cache/functions/memoize.js.map +0 -1
  313. package/cache/functions/omit.d.ts +0 -1
  314. package/cache/functions/omit.js.map +0 -1
  315. package/cache/functions/prevent-parallel-execution.d.ts +0 -7
  316. package/cache/functions/prevent-parallel-execution.js +0 -25
  317. package/cache/functions/prevent-parallel-execution.js.map +0 -1
  318. package/cache/functions/types.d.ts +0 -1
  319. package/cache/functions/types.js.map +0 -1
  320. package/cache/get-persistent-cache.d.ts +0 -12
  321. package/cache/get-persistent-cache.js +0 -23
  322. package/cache/get-persistent-cache.js.map +0 -1
  323. package/cache/index.d.ts +0 -3
  324. package/cache/index.js.map +0 -1
  325. package/cache/managed-array.d.ts +0 -23
  326. package/cache/managed-array.js +0 -160
  327. package/cache/managed-array.js.map +0 -1
  328. package/cache/managed-async-cache.browser.test.d.ts +0 -1
  329. package/cache/managed-async-cache.browser.test.js.map +0 -1
  330. package/cache/managed-async-cache.d.ts +0 -4
  331. package/cache/managed-async-cache.js +0 -45
  332. package/cache/managed-async-cache.js.map +0 -1
  333. package/cache/memory-allocator.d.ts +0 -23
  334. package/cache/memory-allocator.js +0 -94
  335. package/cache/memory-allocator.js.map +0 -1
  336. package/cache/memory-async-cache.d.ts +0 -6
  337. package/cache/memory-async-cache.js +0 -23
  338. package/cache/memory-async-cache.js.map +0 -1
  339. package/core/data.d.ts +0 -22
  340. package/core/data.js.map +0 -1
  341. package/core/data.test.d.ts +0 -1
  342. package/core/data.test.js.map +0 -1
  343. package/core/functions/array-equals.d.ts +0 -1
  344. package/core/functions/array-equals.js.map +0 -1
  345. package/core/functions/deep-merge.d.ts +0 -32
  346. package/core/functions/deep-merge.js +0 -54
  347. package/core/functions/deep-merge.js.map +0 -1
  348. package/core/functions/deep-merge.test.d.ts +0 -1
  349. package/core/functions/deep-merge.test.js +0 -94
  350. package/core/functions/deep-merge.test.js.map +0 -1
  351. package/core/functions/index.d.ts +0 -3
  352. package/core/functions/index.js.map +0 -1
  353. package/core/functions/is-async-generator.d.ts +0 -1
  354. package/core/functions/is-async-generator.js.map +0 -1
  355. package/core/functions/is-promise.d.ts +0 -1
  356. package/core/functions/is-promise.js.map +0 -1
  357. package/core/functions/with-validation.d.ts +0 -5
  358. package/core/functions/with-validation.js.map +0 -1
  359. package/core/functions/with-validation.test.d.ts +0 -1
  360. package/core/functions/with-validation.test.js.map +0 -1
  361. package/core/index.d.ts +0 -3
  362. package/core/index.js.map +0 -1
  363. package/core/schema/dynamic/dynamic-schema.d.ts +0 -27
  364. package/core/schema/dynamic/dynamic-schema.js +0 -2
  365. package/core/schema/dynamic/dynamic-schema.js.map +0 -1
  366. package/core/schema/dynamic/enumerate-patches.d.ts +0 -9
  367. package/core/schema/dynamic/enumerate-patches.js.map +0 -1
  368. package/core/schema/dynamic/enumerate-patches.test.d.ts +0 -134
  369. package/core/schema/dynamic/enumerate-patches.test.js.map +0 -1
  370. package/core/schema/dynamic/get-dynamic-schema.d.ts +0 -5
  371. package/core/schema/dynamic/get-dynamic-schema.js +0 -26
  372. package/core/schema/dynamic/get-dynamic-schema.js.map +0 -1
  373. package/core/schema/dynamic/get-dynamic-schema.test.d.ts +0 -1
  374. package/core/schema/dynamic/get-dynamic-schema.test.js.map +0 -1
  375. package/core/schema/dynamic/index.d.ts +0 -1
  376. package/core/schema/dynamic/index.js +0 -2
  377. package/core/schema/dynamic/index.js.map +0 -1
  378. package/core/schema/dynamic/schema-path-value-path.d.ts +0 -5
  379. package/core/schema/dynamic/schema-path-value-path.js +0 -12
  380. package/core/schema/dynamic/schema-path-value-path.js.map +0 -1
  381. package/core/schema/dynamic-schema.d.ts +0 -27
  382. package/core/schema/dynamic-schema.js +0 -2
  383. package/core/schema/dynamic-schema.js.map +0 -1
  384. package/core/schema/index.d.ts +0 -4
  385. package/core/schema/index.js +0 -26
  386. package/core/schema/index.js.map +0 -1
  387. package/core/schema/schema.d.ts +0 -122
  388. package/core/schema/schema.js.map +0 -1
  389. package/core/schema/schemas.d.ts +0 -45
  390. package/core/schema/schemas.js +0 -39
  391. package/core/schema/schemas.js.map +0 -1
  392. package/core/schema/ui-schema.d.ts +0 -25
  393. package/core/schema/ui-schema.js +0 -2
  394. package/core/schema/ui-schema.js.map +0 -1
  395. package/core/schema/validation/is-valid.d.ts +0 -2
  396. package/core/schema/validation/is-valid.js +0 -14
  397. package/core/schema/validation/is-valid.js.map +0 -1
  398. package/core/schema/validation/is-valid.test.d.ts +0 -1
  399. package/core/schema/validation/is-valid.test.js.map +0 -1
  400. package/core/schema/validation/validate.d.ts +0 -2
  401. package/core/schema/validation/validate.js.map +0 -1
  402. package/core/schema/validation/validate.test.d.ts +0 -1
  403. package/core/schema/validation/validate.test.js.map +0 -1
  404. package/core/schema/validation/with-validation.d.ts +0 -5
  405. package/core/schema/validation/with-validation.js +0 -16
  406. package/core/schema/validation/with-validation.js.map +0 -1
  407. package/core/schema/validation/with-validation.test.d.ts +0 -1
  408. package/core/schema/validation/with-validation.test.js +0 -96
  409. package/core/schema/validation/with-validation.test.js.map +0 -1
  410. package/core/schema.d.ts +0 -86
  411. package/core/schema.js.map +0 -1
  412. package/core/schema.test.d.ts +0 -1
  413. package/core/schema.test.js +0 -16
  414. package/core/schema.test.js.map +0 -1
  415. package/core/schemas.d.ts +0 -45
  416. package/core/schemas.js +0 -39
  417. package/core/schemas.js.map +0 -1
  418. package/ecs/action-ecs/action-ecs.d.ts +0 -19
  419. package/ecs/action-ecs/action-ecs.js +0 -203
  420. package/ecs/action-ecs/action-ecs.js.map +0 -1
  421. package/ecs/action-ecs/action-ecs.test.d.ts +0 -1
  422. package/ecs/action-ecs/action-ecs.test.js +0 -362
  423. package/ecs/action-ecs/action-ecs.test.js.map +0 -1
  424. package/ecs/action-ecs/action-types.d.ts +0 -106
  425. package/ecs/action-ecs/action-types.js +0 -19
  426. package/ecs/action-ecs/action-types.js.map +0 -1
  427. package/ecs/action-ecs/index.d.ts +0 -2
  428. package/ecs/action-ecs/index.js.map +0 -1
  429. package/ecs/core-ecs/core-ecs-serialization.test.d.ts +0 -1
  430. package/ecs/core-ecs/core-ecs-serialization.test.js +0 -230
  431. package/ecs/core-ecs/core-ecs-serialization.test.js.map +0 -1
  432. package/ecs/core-ecs/core-ecs-types.d.ts +0 -141
  433. package/ecs/core-ecs/core-ecs-types.js.map +0 -1
  434. package/ecs/core-ecs/core-ecs.d.ts +0 -7
  435. package/ecs/core-ecs/core-ecs.js +0 -492
  436. package/ecs/core-ecs/core-ecs.js.map +0 -1
  437. package/ecs/core-ecs/core-ecs.test.d.ts +0 -1
  438. package/ecs/core-ecs/core-ecs.test.js +0 -425
  439. package/ecs/core-ecs/core-ecs.test.js.map +0 -1
  440. package/ecs/core-ecs/index.d.ts +0 -1
  441. package/ecs/core-ecs/index.js +0 -2
  442. package/ecs/core-ecs/index.js.map +0 -1
  443. package/ecs/ecs/ecs-types.d.ts +0 -132
  444. package/ecs/ecs/ecs-types.js.map +0 -1
  445. package/ecs/ecs/ecs-where-functions.d.ts +0 -6
  446. package/ecs/ecs/ecs-where-functions.js +0 -91
  447. package/ecs/ecs/ecs-where-functions.js.map +0 -1
  448. package/ecs/ecs/ecs.d.ts +0 -13
  449. package/ecs/ecs/ecs.js +0 -177
  450. package/ecs/ecs/ecs.js.map +0 -1
  451. package/ecs/ecs/ecs.test.d.ts +0 -1
  452. package/ecs/ecs/ecs.test.js +0 -399
  453. package/ecs/ecs/ecs.test.js.map +0 -1
  454. package/ecs/ecs/index.d.ts +0 -3
  455. package/ecs/ecs/index.js +0 -3
  456. package/ecs/ecs/index.js.map +0 -1
  457. package/ecs/index.d.ts +0 -4
  458. package/ecs/index.js.map +0 -1
  459. package/ecs/transaction-ecs/index.d.ts +0 -2
  460. package/ecs/transaction-ecs/index.js.map +0 -1
  461. package/ecs/transaction-ecs/transaction-ecs.d.ts +0 -11
  462. package/ecs/transaction-ecs/transaction-ecs.js +0 -184
  463. package/ecs/transaction-ecs/transaction-ecs.js.map +0 -1
  464. package/ecs/transaction-ecs/transaction-ecs.test.d.ts +0 -1
  465. package/ecs/transaction-ecs/transaction-ecs.test.js +0 -599
  466. package/ecs/transaction-ecs/transaction-ecs.test.js.map +0 -1
  467. package/ecs/transaction-ecs/transaction-types.d.ts +0 -135
  468. package/ecs/transaction-ecs/transaction-types.js +0 -2
  469. package/ecs/transaction-ecs/transaction-types.js.map +0 -1
  470. package/ecs/transaction-ecs/transactions.d.ts +0 -5
  471. package/ecs/transaction-ecs/transactions.js +0 -158
  472. package/ecs/transaction-ecs/transactions.js.map +0 -1
  473. package/index.d.ts +0 -1
  474. package/index.js +0 -23
  475. package/index.js.map +0 -1
  476. package/observe/create-observable-event.d.ts +0 -10
  477. package/observe/create-observable-event.js +0 -22
  478. package/observe/create-observable-event.js.map +0 -1
  479. package/observe/create-observable-state.d.ts +0 -7
  480. package/observe/create-observable-state.js +0 -27
  481. package/observe/create-observable-state.js.map +0 -1
  482. package/observe/create-persisted-state.d.ts +0 -11
  483. package/observe/create-persisted-state.js +0 -31
  484. package/observe/create-persisted-state.js.map +0 -1
  485. package/observe/create-persisted-state.test.d.ts +0 -1
  486. package/observe/create-persisted-state.test.js +0 -124
  487. package/observe/create-persisted-state.test.js.map +0 -1
  488. package/observe/from-array.d.ts +0 -5
  489. package/observe/from-array.js.map +0 -1
  490. package/observe/from-constant.d.ts +0 -5
  491. package/observe/from-constant.js +0 -12
  492. package/observe/from-constant.js.map +0 -1
  493. package/observe/from-element-id.d.ts +0 -7
  494. package/observe/from-element-id.js.map +0 -1
  495. package/observe/from-element-properties-and-events.d.ts +0 -2
  496. package/observe/from-element-properties-and-events.js +0 -18
  497. package/observe/from-element-properties-and-events.js.map +0 -1
  498. package/observe/from-element-property.d.ts +0 -11
  499. package/observe/from-element-property.js.map +0 -1
  500. package/observe/from-promise-with-error.d.ts +0 -7
  501. package/observe/from-promise-with-error.js +0 -27
  502. package/observe/from-promise-with-error.js.map +0 -1
  503. package/observe/from-promise.d.ts +0 -6
  504. package/observe/from-promise.js +0 -22
  505. package/observe/from-promise.js.map +0 -1
  506. package/observe/from-properties.d.ts +0 -10
  507. package/observe/from-properties.js +0 -33
  508. package/observe/from-properties.js.map +0 -1
  509. package/observe/index.d.ts +0 -27
  510. package/observe/index.js.map +0 -1
  511. package/observe/observe.test.d.ts +0 -7
  512. package/observe/observe.test.js +0 -417
  513. package/observe/observe.test.js.map +0 -1
  514. package/observe/to-promise.d.ts +0 -8
  515. package/observe/to-promise.js +0 -18
  516. package/observe/to-promise.js.map +0 -1
  517. package/observe/to-properties.d.ts +0 -11
  518. package/observe/to-properties.js +0 -9
  519. package/observe/to-properties.js.map +0 -1
  520. package/observe/types.d.ts +0 -17
  521. package/observe/types.js +0 -2
  522. package/observe/types.js.map +0 -1
  523. package/observe/with-async-map.d.ts +0 -6
  524. package/observe/with-async-map.js +0 -12
  525. package/observe/with-async-map.js.map +0 -1
  526. package/observe/with-cache.d.ts +0 -6
  527. package/observe/with-cache.js +0 -33
  528. package/observe/with-cache.js.map +0 -1
  529. package/observe/with-copy.d.ts +0 -5
  530. package/observe/with-copy.js +0 -10
  531. package/observe/with-copy.js.map +0 -1
  532. package/observe/with-deduplicate-data.d.ts +0 -7
  533. package/observe/with-deduplicate-data.js +0 -18
  534. package/observe/with-deduplicate-data.js.map +0 -1
  535. package/observe/with-deduplicate.d.ts +0 -6
  536. package/observe/with-deduplicate.js +0 -19
  537. package/observe/with-deduplicate.js.map +0 -1
  538. package/observe/with-default.d.ts +0 -6
  539. package/observe/with-default.js +0 -21
  540. package/observe/with-default.js.map +0 -1
  541. package/observe/with-map-data.d.ts +0 -7
  542. package/observe/with-map-data.js.map +0 -1
  543. package/observe/with-map.d.ts +0 -5
  544. package/observe/with-map.js +0 -11
  545. package/observe/with-map.js.map +0 -1
  546. package/observe/with-optional.d.ts +0 -5
  547. package/observe/with-optional.js +0 -20
  548. package/observe/with-optional.js.map +0 -1
  549. package/observe/with-unwrap.d.ts +0 -5
  550. package/observe/with-unwrap.js +0 -26
  551. package/observe/with-unwrap.js.map +0 -1
  552. package/perftest/ecs-perf.d.ts +0 -49
  553. package/perftest/ecs-perf.js +0 -230
  554. package/perftest/ecs-perf.js.map +0 -1
  555. package/perftest/helper-functions.d.ts +0 -1
  556. package/perftest/helper-functions.js +0 -31
  557. package/perftest/helper-functions.js.map +0 -1
  558. package/perftest/horizon-perf.d.ts +0 -22
  559. package/perftest/horizon-perf.js +0 -126
  560. package/perftest/horizon-perf.js.map +0 -1
  561. package/perftest/index.d.ts +0 -1
  562. package/perftest/index.js.map +0 -1
  563. package/perftest/perf-test.d.ts +0 -18
  564. package/perftest/perf-test.js +0 -124
  565. package/perftest/perf-test.js.map +0 -1
  566. package/perftest/vanilla-perf.d.ts +0 -38
  567. package/perftest/vanilla-perf.js +0 -128
  568. package/perftest/vanilla-perf.js.map +0 -1
  569. package/schemas/index.d.ts +0 -1
  570. package/schemas/index.js +0 -23
  571. package/schemas/index.js.map +0 -1
  572. package/schemas/schemas.d.ts +0 -45
  573. package/schemas/schemas.js +0 -39
  574. package/schemas/schemas.js.map +0 -1
  575. package/service/add-observable-actions.d.ts +0 -29
  576. package/service/add-observable-actions.js +0 -108
  577. package/service/add-observable-actions.js.map +0 -1
  578. package/service/index.d.ts +0 -4
  579. package/service/index.js.map +0 -1
  580. package/service/progressive-result.d.ts +0 -96
  581. package/service/progressive-result.js +0 -99
  582. package/service/progressive-result.js.map +0 -1
  583. package/service/sequential-action.d.ts +0 -18
  584. package/service/sequential-action.js.map +0 -1
  585. package/service/service.d.ts +0 -4
  586. package/service/service.js.map +0 -1
  587. package/tsconfig.tsbuildinfo +0 -1
  588. package/types/index.d.ts +0 -1
  589. package/types/index.js.map +0 -1
  590. package/types/types.d.ts +0 -61
  591. package/types/types.js.map +0 -1
@@ -0,0 +1,250 @@
1
+ /*MIT License
2
+
3
+ © Copyright 2025 Adobe. All rights reserved.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.*/
22
+ import { describe, it, expect } from "vitest";
23
+ import { createTransactionalStore } from "./create-transactional-store.js";
24
+ import { createStore } from "../../store/create-store.js";
25
+ import { F32Schema } from "../../../schema/f32.js";
26
+ import { Schema } from "../../../schema/schema.js";
27
+
28
+ // Test schemas
29
+ const positionSchema = {
30
+ type: "object",
31
+ properties: {
32
+ x: F32Schema,
33
+ y: F32Schema,
34
+ z: F32Schema,
35
+ }
36
+ } as const satisfies Schema;
37
+
38
+ const healthSchema = {
39
+ type: "object",
40
+ properties: {
41
+ current: F32Schema,
42
+ max: F32Schema,
43
+ }
44
+ } as const satisfies Schema;
45
+
46
+ describe("createTransactionalStore", () => {
47
+ it("should create transactional store with basic components", () => {
48
+ const baseStore = createStore(
49
+ { position: positionSchema, health: healthSchema },
50
+ { time: { delta: 0.016, elapsed: 0 } }
51
+ );
52
+
53
+ const store = createTransactionalStore(baseStore);
54
+
55
+ expect(store).toBeDefined();
56
+ expect(store.componentSchemas).toHaveProperty("id");
57
+ expect(store.componentSchemas).toHaveProperty("position");
58
+ expect(store.componentSchemas).toHaveProperty("health");
59
+ expect(store.resources).toHaveProperty("time");
60
+ });
61
+
62
+ it("should execute transactions successfully", () => {
63
+ const baseStore = createStore(
64
+ { position: positionSchema, health: healthSchema },
65
+ { time: { delta: 0.016, elapsed: 0 } }
66
+ );
67
+
68
+ const store = createTransactionalStore(baseStore);
69
+
70
+ const result = store.execute((transactionStore) => {
71
+ // Create an entity
72
+ const archetype = transactionStore.ensureArchetype(["id", "position"]);
73
+ const entity = archetype.insert({ position: { x: 1, y: 2, z: 3 } });
74
+
75
+ // Update the entity
76
+ transactionStore.update(entity, { position: { x: 10, y: 20, z: 30 } });
77
+
78
+ // Update resources
79
+ transactionStore.resources.time = { delta: 0.032, elapsed: 1 };
80
+ });
81
+
82
+ expect(result).toBeDefined();
83
+ expect(result.redo).toHaveLength(3); // insert + update
84
+ expect(result.undo).toHaveLength(3); // delete + insert with old values
85
+ expect(result.changedEntities.size).toBe(2);
86
+ expect(result.changedComponents.size).toBe(2); // position
87
+ expect(result.changedArchetypes.size).toBe(2);
88
+ });
89
+
90
+ it("should rollback on error", () => {
91
+ const baseStore = createStore(
92
+ { position: positionSchema, health: healthSchema },
93
+ { time: { delta: 0.016, elapsed: 0 } }
94
+ );
95
+
96
+ const store = createTransactionalStore(baseStore);
97
+
98
+ // Create initial entity in a transaction
99
+ let entity: number = -1;
100
+ store.execute((transactionStore) => {
101
+ const archetype = transactionStore.ensureArchetype(["id", "position"]);
102
+ entity = archetype.insert({ position: { x: 1, y: 2, z: 3 } });
103
+ });
104
+
105
+ // Verify initial state
106
+ const initialData = store.read(entity);
107
+ expect(initialData?.position).toEqual({ x: 1, y: 2, z: 3 });
108
+
109
+ // Execute transaction that throws an error
110
+ expect(() => {
111
+ store.execute((transactionStore) => {
112
+ // Update entity
113
+ transactionStore.update(entity, { position: { x: 10, y: 20, z: 30 } });
114
+
115
+ // This should cause rollback
116
+ throw new Error("Transaction failed");
117
+ });
118
+ }).toThrow("Transaction failed");
119
+
120
+ // Verify rollback occurred
121
+ const finalData = store.read(entity);
122
+ expect(finalData?.position).toEqual({ x: 1, y: 2, z: 3 });
123
+ });
124
+
125
+ it("should combine multiple updates to the same entity", () => {
126
+ const baseStore = createStore(
127
+ { position: positionSchema, health: healthSchema },
128
+ { time: { delta: 0.016, elapsed: 0 } }
129
+ );
130
+
131
+ const store = createTransactionalStore(baseStore);
132
+
133
+ const result = store.execute((transactionStore) => {
134
+ const archetype = transactionStore.ensureArchetype(["id", "position", "health"]);
135
+ const entity = archetype.insert({
136
+ position: { x: 1, y: 2, z: 3 },
137
+ health: { current: 100, max: 100 }
138
+ });
139
+
140
+ // Multiple updates to the same entity should be combined
141
+ transactionStore.update(entity, { position: { x: 10, y: 20, z: 30 } });
142
+ transactionStore.update(entity, { health: { current: 50, max: 100 } });
143
+ });
144
+
145
+ // Should have combined updates
146
+ expect(result.redo).toHaveLength(2); // insert + combined update
147
+ expect(result.undo).toHaveLength(2); // delete + insert with old values
148
+
149
+ const updateOperation = result.redo.find(op => op.type === "update");
150
+ expect(updateOperation?.type).toBe("update");
151
+ if (updateOperation?.type === "update") {
152
+ expect(updateOperation.values).toHaveProperty("position");
153
+ expect(updateOperation.values).toHaveProperty("health");
154
+ }
155
+ });
156
+
157
+ it("should track changed entities, components, and archetypes", () => {
158
+ const baseStore = createStore(
159
+ { position: positionSchema, health: healthSchema },
160
+ { time: { delta: 0.016, elapsed: 0 } }
161
+ );
162
+
163
+ const store = createTransactionalStore(baseStore);
164
+
165
+ const result = store.execute((transactionStore) => {
166
+ // Create entities in different archetypes
167
+ const posArchetype = transactionStore.ensureArchetype(["id", "position"]);
168
+ const healthArchetype = transactionStore.ensureArchetype(["id", "health"]);
169
+
170
+ const entity1 = posArchetype.insert({ position: { x: 1, y: 2, z: 3 } });
171
+ const entity2 = healthArchetype.insert({ health: { current: 100, max: 100 } });
172
+
173
+ // Update resources
174
+ transactionStore.resources.time = { delta: 0.032, elapsed: 1 };
175
+ });
176
+
177
+ expect(result.changedEntities.size).toBe(3);
178
+ expect(result.changedComponents.size).toBe(3); // position, health
179
+ expect(result.changedArchetypes.size).toBe(3); // two different archetypes
180
+ });
181
+
182
+ it("should preserve base store functionality", () => {
183
+ const baseStore = createStore(
184
+ { position: positionSchema, health: healthSchema },
185
+ { time: { delta: 0.016, elapsed: 0 } }
186
+ );
187
+
188
+ const store = createTransactionalStore(baseStore);
189
+
190
+ // Verify all base store methods are available
191
+ expect(store.componentSchemas).toBeDefined();
192
+ expect(store.resources).toBeDefined();
193
+ expect(store.queryArchetypes).toBeDefined();
194
+ expect(store.ensureArchetype).toBeDefined();
195
+ expect(store.locate).toBeDefined();
196
+ expect(store.read).toBeDefined();
197
+ expect(store.execute).toBeDefined();
198
+
199
+ // Verify we can use the store normally for read operations
200
+ const archetypes = store.queryArchetypes(["id"]);
201
+ expect(archetypes.length).toBeGreaterThan(0);
202
+
203
+ // Verify we can create entities through transactions
204
+ store.execute((transactionStore) => {
205
+ const archetype = transactionStore.ensureArchetype(["id", "position"]);
206
+ const entity = archetype.insert({ position: { x: 1, y: 2, z: 3 } });
207
+ expect(store.read(entity)).toBeDefined();
208
+ });
209
+ });
210
+
211
+ it("should support transient transactions", () => {
212
+ const baseStore = createStore(
213
+ { position: positionSchema, health: healthSchema },
214
+ { time: { delta: 0.016, elapsed: 0 } }
215
+ );
216
+
217
+ const store = createTransactionalStore(baseStore);
218
+
219
+ // Execute a regular transaction (non-transient)
220
+ const regularResult = store.execute((transactionStore) => {
221
+ const archetype = transactionStore.ensureArchetype(["id", "position"]);
222
+ archetype.insert({ position: { x: 1, y: 2, z: 3 } });
223
+ });
224
+
225
+ expect(regularResult.transient).toBe(false);
226
+
227
+ // Execute a transient transaction
228
+ const transientResult = store.execute((transactionStore) => {
229
+ const archetype = transactionStore.ensureArchetype(["id", "position"]);
230
+ archetype.insert({ position: { x: 10, y: 20, z: 30 } });
231
+ }, { transient: true });
232
+
233
+ expect(transientResult.transient).toBe(true);
234
+
235
+ // Both transactions should have the same structure but different transient flags
236
+ expect(regularResult).toHaveProperty("value");
237
+ expect(regularResult).toHaveProperty("redo");
238
+ expect(regularResult).toHaveProperty("undo");
239
+ expect(regularResult).toHaveProperty("changedEntities");
240
+ expect(regularResult).toHaveProperty("changedComponents");
241
+ expect(regularResult).toHaveProperty("changedArchetypes");
242
+
243
+ expect(transientResult).toHaveProperty("value");
244
+ expect(transientResult).toHaveProperty("redo");
245
+ expect(transientResult).toHaveProperty("undo");
246
+ expect(transientResult).toHaveProperty("changedEntities");
247
+ expect(transientResult).toHaveProperty("changedComponents");
248
+ expect(transientResult).toHaveProperty("changedArchetypes");
249
+ });
250
+ });
@@ -0,0 +1,281 @@
1
+ /*MIT License
2
+
3
+ © Copyright 2025 Adobe. All rights reserved.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.*/
22
+ import { ArchetypeId, EntityInsertValues } from "../../archetype/index.js";
23
+ import { CoreComponents } from "../../core-components.js";
24
+ import { ResourceComponents } from "../../store/resource-components.js";
25
+ import { Store } from "../../store/index.js";
26
+ import { Entity } from "../../entity.js";
27
+ import { EntityUpdateValues } from "../../store/core/index.js";
28
+ import { TransactionalStore, TransactionResult, TransactionWriteOperation } from "./transactional-store.js";
29
+ import { StringKeyof } from "../../../types/types.js";
30
+
31
+ // Sentinel value used to indicate a component should be deleted
32
+ const DELETE: unknown = "_$_DELETE_$_";
33
+
34
+ export function createTransactionalStore<C extends CoreComponents, R extends ResourceComponents>(
35
+ store: Store<C, R>,
36
+ ): TransactionalStore<C, R> {
37
+
38
+ // Transaction state (mutable during transaction execution)
39
+ let undoOperationsInReverseOrder: TransactionWriteOperation<C>[] = [];
40
+ let redoOperations: TransactionWriteOperation<C>[] = [];
41
+ const changed = {
42
+ entities: new Set<Entity>(),
43
+ components: new Set<keyof C>(),
44
+ archetypes: new Set<ArchetypeId>(),
45
+ };
46
+
47
+ // Wrap archetype creation to track operations
48
+ const wrapArchetype = (archetype: any) => {
49
+ const { id } = archetype;
50
+ return {
51
+ ...archetype,
52
+ insert: (values: EntityInsertValues<C>) => {
53
+ const entity = archetype.insert(values);
54
+ redoOperations.push({
55
+ type: "insert",
56
+ values: values,
57
+ });
58
+ undoOperationsInReverseOrder.push({ type: "delete", entity });
59
+ changed.entities.add(entity);
60
+ changed.archetypes.add(id);
61
+ for (const key in values) {
62
+ changed.components.add(key as keyof C);
63
+ }
64
+ return entity;
65
+ },
66
+ };
67
+ };
68
+
69
+ // Create wrapped archetypes for transaction tracking
70
+ const wrappedArchetypes = new Map<ArchetypeId, any>();
71
+
72
+ const getWrappedArchetype = (archetype: any) => {
73
+ if (!wrappedArchetypes.has(archetype.id)) {
74
+ wrappedArchetypes.set(archetype.id, wrapArchetype(archetype));
75
+ }
76
+ return wrappedArchetypes.get(archetype.id);
77
+ };
78
+
79
+ // Transaction-aware update function
80
+ const updateEntity = (entity: Entity, values: EntityUpdateValues<C>) => {
81
+ const oldValues = store.read(entity);
82
+ if (!oldValues) {
83
+ throw new Error(`Entity not found: ${entity}`);
84
+ }
85
+
86
+ const replacedValues: any = {};
87
+ for (const name in values) {
88
+ let newValue = (values as any)[name];
89
+ if (newValue === DELETE) {
90
+ newValue = undefined;
91
+ }
92
+ let oldValue = (oldValues as any)[name];
93
+ if (newValue !== oldValue) {
94
+ if (oldValue === undefined) {
95
+ oldValue = DELETE;
96
+ }
97
+ replacedValues[name] = oldValue;
98
+ changed.components.add(name as keyof C);
99
+ }
100
+ }
101
+
102
+ changed.entities.add(entity);
103
+ const location = store.locate(entity);
104
+ if (location) {
105
+ changed.archetypes.add(location.archetype);
106
+ }
107
+
108
+ // Perform the actual update
109
+ store.update(entity, values as any);
110
+
111
+ // Check if archetype changed after update
112
+ const newLocation = store.locate(entity);
113
+ if (newLocation) {
114
+ changed.archetypes.add(newLocation.archetype);
115
+ }
116
+
117
+ // Add operations with potential combining
118
+ addUpdateOperationsMaybeCombineLast(undoOperationsInReverseOrder, redoOperations, entity, values, replacedValues);
119
+ };
120
+
121
+ // Transaction-aware delete function
122
+ const deleteEntity = (entity: Entity) => {
123
+ const location = store.locate(entity);
124
+ if (location) {
125
+ changed.archetypes.add(location.archetype);
126
+ }
127
+ changed.entities.add(entity);
128
+
129
+ const oldValues = store.read(entity);
130
+ if (!oldValues) {
131
+ throw new Error(`Entity not found: ${entity}`);
132
+ }
133
+
134
+ const { id: _ignore, ...oldValuesWithoutId } = oldValues as any;
135
+ for (const key in oldValuesWithoutId) {
136
+ changed.components.add(key as keyof C);
137
+ }
138
+
139
+ store.delete(entity);
140
+ redoOperations.push({ type: "delete", entity });
141
+ undoOperationsInReverseOrder.push({ type: "insert", values: oldValuesWithoutId });
142
+ };
143
+
144
+ const resources = {} as { [K in keyof R]: R[K] };
145
+ for (const name of Object.keys(store.resources)) {
146
+ const resourceId = name as keyof C;
147
+ const archetype = store.ensureArchetype(["id", resourceId] as StringKeyof<C>[]);
148
+ const entityId = archetype.columns.id.get(0);
149
+ Object.defineProperty(resources, name, {
150
+ get: Object.getOwnPropertyDescriptor(store.resources, name)!.get,
151
+ set: (newValue) => {
152
+ updateEntity(entityId, { [resourceId]: newValue } as any);
153
+ },
154
+ enumerable: true,
155
+ });
156
+ }
157
+
158
+
159
+ // Create transaction-aware store
160
+ const transactionStore: Store<C, R> = {
161
+ ...store,
162
+ resources,
163
+ ensureArchetype: (componentNames) => {
164
+ const archetype = store.ensureArchetype(componentNames);
165
+ return getWrappedArchetype(archetype);
166
+ },
167
+ update: updateEntity,
168
+ delete: deleteEntity,
169
+ };
170
+
171
+ // Execute transaction function
172
+ const execute = (
173
+ transactionFunction: (store: Store<C, R>) => Entity | void,
174
+ options?: {
175
+ transient?: boolean;
176
+ }
177
+ ): TransactionResult<C> => {
178
+ // Reset transaction state
179
+ undoOperationsInReverseOrder = [];
180
+ redoOperations = [];
181
+ changed.entities.clear();
182
+ changed.components.clear();
183
+ changed.archetypes.clear();
184
+
185
+ try {
186
+ // Execute the transaction
187
+ const value = transactionFunction(transactionStore);
188
+
189
+ // Return the transaction result
190
+ const result: TransactionResult<C> = {
191
+ value: value ?? undefined,
192
+ transient: options?.transient ?? false,
193
+ redo: [...redoOperations],
194
+ undo: [...undoOperationsInReverseOrder.reverse()],
195
+ changedEntities: new Set(changed.entities),
196
+ changedComponents: new Set(changed.components),
197
+ changedArchetypes: new Set(changed.archetypes),
198
+ };
199
+
200
+ return result;
201
+ } catch (error) {
202
+ // Rollback on error by applying undo operations in reverse
203
+ applyWriteOperations(store, undoOperationsInReverseOrder.reverse());
204
+ throw error;
205
+ } finally {
206
+ // Clean up transaction state
207
+ undoOperationsInReverseOrder = [];
208
+ redoOperations = [];
209
+ changed.entities.clear();
210
+ changed.components.clear();
211
+ changed.archetypes.clear();
212
+ wrappedArchetypes.clear();
213
+ }
214
+ };
215
+
216
+ // Create the transactional store interface
217
+ const transactionalStore: TransactionalStore<C, R> = {
218
+ ...store,
219
+ execute,
220
+ };
221
+
222
+ return transactionalStore as any;
223
+ }
224
+
225
+ // Helper function to combine update operations for the same entity
226
+ function addUpdateOperationsMaybeCombineLast<C>(
227
+ undoOperationsInReverseOrder: TransactionWriteOperation<C>[],
228
+ redoOperations: TransactionWriteOperation<C>[],
229
+ entity: Entity,
230
+ values: EntityUpdateValues<C>,
231
+ replacedValues: EntityUpdateValues<C>
232
+ ) {
233
+ const lastUndoOperation: TransactionWriteOperation<C> | undefined =
234
+ undoOperationsInReverseOrder[undoOperationsInReverseOrder.length - 1];
235
+
236
+ if (
237
+ lastUndoOperation?.type === "update" &&
238
+ lastUndoOperation.entity === entity
239
+ ) {
240
+ // Combine with previous update operation
241
+ const lastRedoOperation = redoOperations[redoOperations.length - 1];
242
+ if (lastRedoOperation?.type === "update") {
243
+ lastRedoOperation.values = { ...lastRedoOperation.values, ...values };
244
+ lastUndoOperation.values = {
245
+ ...replacedValues,
246
+ ...lastUndoOperation.values,
247
+ };
248
+ }
249
+ } else {
250
+ // Add new update operations
251
+ redoOperations.push({ type: "update", entity, values });
252
+ undoOperationsInReverseOrder.push({
253
+ type: "update",
254
+ entity,
255
+ values: replacedValues,
256
+ });
257
+ }
258
+ }
259
+
260
+ // Helper function to apply write operations for rollback
261
+ function applyWriteOperations<C extends CoreComponents, R extends ResourceComponents>(
262
+ store: Store<C, R>,
263
+ operations: TransactionWriteOperation<C>[]
264
+ ): void {
265
+ for (const operation of operations) {
266
+ switch (operation.type) {
267
+ case "insert": {
268
+ const componentNames = ["id", ...Object.keys(operation.values)] as StringKeyof<C>[];
269
+ const archetype = store.ensureArchetype(componentNames);
270
+ archetype.insert(operation.values);
271
+ break;
272
+ }
273
+ case "update":
274
+ store.update(operation.entity, operation.values);
275
+ break;
276
+ case "delete":
277
+ store.delete(operation.entity);
278
+ break;
279
+ }
280
+ }
281
+ }
@@ -19,5 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.*/
22
- export {};
23
- //# sourceMappingURL=ecs-types.js.map
22
+ export * from "./transactional-store.js";
@@ -0,0 +1,80 @@
1
+ /*MIT License
2
+
3
+ © Copyright 2025 Adobe. All rights reserved.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.*/
22
+ import { ArchetypeId, EntityInsertValues } from "../../archetype/index.js";
23
+ import { CoreComponents } from "../../core-components.js";
24
+ import { ResourceComponents } from "../../store/resource-components.js";
25
+ import { ReadonlyStore, Store } from "../../store/index.js";
26
+ import { Entity } from "../../entity.js";
27
+ import { EntityUpdateValues } from "../../store/core/index.js";
28
+
29
+ export interface TransactionalStore<
30
+ C extends CoreComponents = CoreComponents,
31
+ R extends ResourceComponents = never
32
+ > extends ReadonlyStore<C, R> {
33
+ /**
34
+ * Execute a transaction on the store.
35
+ * The transactionFunction must NOT directly mutate archetype rows as those changes would not be captured.
36
+ * Instead, use the store's update and delete and archetype insert methods to make changes.
37
+ * @param transactionFunction - A function that takes the store as an argument and performs some operations on it.
38
+ * @returns A promise that resolves when the transaction is complete.
39
+ */
40
+ execute(
41
+ transactionFunction: (store: Store<C, R>) => Entity | void,
42
+ options?: {
43
+ transient?: boolean;
44
+ }
45
+ ): TransactionResult<C>;
46
+ }
47
+
48
+ export type TransactionInsertOperation<C> = {
49
+ type: "insert";
50
+ values: EntityInsertValues<C>;
51
+ };
52
+
53
+ export type TransactionUpdateOperation<C> = {
54
+ type: "update";
55
+ entity: Entity;
56
+ values: EntityUpdateValues<C>;
57
+ };
58
+
59
+ export type TransactionDeleteOperation = {
60
+ type: "delete";
61
+ entity: Entity
62
+ };
63
+
64
+ export type TransactionWriteOperation<C> =
65
+ | TransactionInsertOperation<C>
66
+ | TransactionUpdateOperation<C>
67
+ | TransactionDeleteOperation;
68
+
69
+ export interface TransactionResult<C> {
70
+ /**
71
+ * The Entity value if any returned by the transaction function.
72
+ */
73
+ readonly value: Entity | void;
74
+ readonly transient: boolean;
75
+ readonly redo: TransactionWriteOperation<C>[];
76
+ readonly undo: TransactionWriteOperation<C>[];
77
+ readonly changedEntities: Set<Entity>;
78
+ readonly changedComponents: Set<keyof C>;
79
+ readonly changedArchetypes: Set<ArchetypeId>;
80
+ }