@oasys/oecs 0.3.1 → 0.5.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 (324) hide show
  1. package/CHANGELOG.md +553 -0
  2. package/README.md +207 -267
  3. package/dist/core/ecs/access_check.d.cts +77 -0
  4. package/dist/core/ecs/access_check.d.ts +77 -0
  5. package/dist/core/ecs/access_check.d.ts.map +1 -0
  6. package/dist/core/ecs/archetype.d.cts +486 -0
  7. package/dist/core/ecs/archetype.d.ts +486 -0
  8. package/dist/core/ecs/archetype.d.ts.map +1 -0
  9. package/dist/core/ecs/archetype_graph.d.cts +96 -0
  10. package/dist/core/ecs/archetype_graph.d.ts +96 -0
  11. package/dist/core/ecs/archetype_graph.d.ts.map +1 -0
  12. package/dist/core/ecs/builtin_relations.d.cts +43 -0
  13. package/dist/core/ecs/builtin_relations.d.ts +43 -0
  14. package/dist/core/ecs/builtin_relations.d.ts.map +1 -0
  15. package/dist/core/ecs/command_log.d.cts +116 -0
  16. package/dist/core/ecs/command_log.d.ts +116 -0
  17. package/dist/core/ecs/command_log.d.ts.map +1 -0
  18. package/dist/core/ecs/component.d.cts +176 -0
  19. package/dist/core/ecs/component.d.ts +176 -0
  20. package/dist/core/ecs/component.d.ts.map +1 -0
  21. package/dist/core/ecs/compute_backend.d.cts +37 -0
  22. package/dist/core/ecs/compute_backend.d.ts +37 -0
  23. package/dist/core/ecs/compute_backend.d.ts.map +1 -0
  24. package/dist/core/ecs/debug_names.d.cts +7 -0
  25. package/dist/core/ecs/debug_names.d.ts +7 -0
  26. package/dist/core/ecs/debug_names.d.ts.map +1 -0
  27. package/dist/core/ecs/deferred_commands.d.cts +55 -0
  28. package/dist/core/ecs/deferred_commands.d.ts +55 -0
  29. package/dist/core/ecs/deferred_commands.d.ts.map +1 -0
  30. package/dist/core/ecs/dispatch_trace.d.cts +93 -0
  31. package/dist/core/ecs/dispatch_trace.d.ts +93 -0
  32. package/dist/core/ecs/dispatch_trace.d.ts.map +1 -0
  33. package/dist/core/ecs/ecs.d.cts +562 -0
  34. package/dist/core/ecs/ecs.d.ts +562 -0
  35. package/dist/core/ecs/ecs.d.ts.map +1 -0
  36. package/dist/core/ecs/ecs_memory.d.cts +179 -0
  37. package/dist/core/ecs/ecs_memory.d.ts +179 -0
  38. package/dist/core/ecs/ecs_memory.d.ts.map +1 -0
  39. package/dist/core/ecs/entity.d.cts +34 -0
  40. package/dist/core/ecs/entity.d.ts +34 -0
  41. package/dist/core/ecs/entity.d.ts.map +1 -0
  42. package/dist/core/ecs/entity_allocator.d.cts +59 -0
  43. package/dist/core/ecs/entity_allocator.d.ts +59 -0
  44. package/dist/core/ecs/entity_allocator.d.ts.map +1 -0
  45. package/dist/core/ecs/event.d.cts +79 -0
  46. package/dist/core/ecs/event.d.ts +79 -0
  47. package/dist/core/ecs/event.d.ts.map +1 -0
  48. package/dist/core/ecs/event_registry.d.cts +22 -0
  49. package/dist/core/ecs/event_registry.d.ts +22 -0
  50. package/dist/core/ecs/event_registry.d.ts.map +1 -0
  51. package/dist/core/ecs/facades.d.cts +158 -0
  52. package/dist/core/ecs/facades.d.ts +158 -0
  53. package/dist/core/ecs/facades.d.ts.map +1 -0
  54. package/dist/core/ecs/frame_stepper.d.cts +58 -0
  55. package/dist/core/ecs/frame_stepper.d.ts +58 -0
  56. package/dist/core/ecs/frame_stepper.d.ts.map +1 -0
  57. package/dist/core/ecs/frame_trace.d.cts +133 -0
  58. package/dist/core/ecs/frame_trace.d.ts +133 -0
  59. package/dist/core/ecs/frame_trace.d.ts.map +1 -0
  60. package/dist/core/ecs/host_commands.d.cts +274 -0
  61. package/dist/core/ecs/host_commands.d.ts +274 -0
  62. package/dist/core/ecs/host_commands.d.ts.map +1 -0
  63. package/dist/core/ecs/index.d.cts +46 -0
  64. package/dist/core/ecs/index.d.ts +46 -0
  65. package/dist/core/ecs/index.d.ts.map +1 -0
  66. package/dist/core/ecs/observer.d.cts +173 -0
  67. package/dist/core/ecs/observer.d.ts +173 -0
  68. package/dist/core/ecs/observer.d.ts.map +1 -0
  69. package/dist/core/ecs/query.d.cts +718 -0
  70. package/dist/core/ecs/query.d.ts +718 -0
  71. package/dist/core/ecs/query.d.ts.map +1 -0
  72. package/dist/core/ecs/ref.d.cts +31 -0
  73. package/dist/core/ecs/ref.d.ts +31 -0
  74. package/dist/core/ecs/ref.d.ts.map +1 -0
  75. package/dist/core/ecs/relation.d.cts +243 -0
  76. package/dist/core/ecs/relation.d.ts +243 -0
  77. package/dist/core/ecs/relation.d.ts.map +1 -0
  78. package/dist/core/ecs/relation_service.d.cts +235 -0
  79. package/dist/core/ecs/relation_service.d.ts +235 -0
  80. package/dist/core/ecs/relation_service.d.ts.map +1 -0
  81. package/dist/core/ecs/resource.d.cts +53 -0
  82. package/dist/core/ecs/resource.d.ts +53 -0
  83. package/dist/core/ecs/resource.d.ts.map +1 -0
  84. package/dist/core/ecs/resource_registry.d.cts +20 -0
  85. package/dist/core/ecs/resource_registry.d.ts +20 -0
  86. package/dist/core/ecs/resource_registry.d.ts.map +1 -0
  87. package/dist/core/ecs/resume.d.cts +85 -0
  88. package/dist/core/ecs/resume.d.ts +85 -0
  89. package/dist/core/ecs/resume.d.ts.map +1 -0
  90. package/dist/core/ecs/run_condition.d.cts +81 -0
  91. package/dist/core/ecs/run_condition.d.ts +81 -0
  92. package/dist/core/ecs/run_condition.d.ts.map +1 -0
  93. package/dist/core/ecs/schedule.d.cts +142 -0
  94. package/dist/core/ecs/schedule.d.ts +142 -0
  95. package/dist/core/ecs/schedule.d.ts.map +1 -0
  96. package/dist/core/ecs/snapshot_service.d.cts +94 -0
  97. package/dist/core/ecs/snapshot_service.d.ts +94 -0
  98. package/dist/core/ecs/snapshot_service.d.ts.map +1 -0
  99. package/dist/core/ecs/sparse_store.d.cts +110 -0
  100. package/dist/core/ecs/sparse_store.d.ts +110 -0
  101. package/dist/core/ecs/sparse_store.d.ts.map +1 -0
  102. package/dist/core/ecs/store.d.cts +950 -0
  103. package/dist/core/ecs/store.d.ts +950 -0
  104. package/dist/core/ecs/store.d.ts.map +1 -0
  105. package/dist/core/ecs/store_layout_listener.d.cts +23 -0
  106. package/dist/core/ecs/store_layout_listener.d.ts +23 -0
  107. package/dist/core/ecs/store_layout_listener.d.ts.map +1 -0
  108. package/dist/core/ecs/system.d.cts +250 -0
  109. package/dist/core/ecs/system.d.ts +250 -0
  110. package/dist/core/ecs/system.d.ts.map +1 -0
  111. package/dist/core/ecs/utils/arrays.d.cts +7 -0
  112. package/dist/{utils → core/ecs/utils}/arrays.d.ts +2 -1
  113. package/dist/core/ecs/utils/arrays.d.ts.map +1 -0
  114. package/dist/core/ecs/utils/constants.d.ts +12 -0
  115. package/dist/core/ecs/utils/constants.d.ts.map +1 -0
  116. package/dist/core/ecs/utils/error.d.cts +61 -0
  117. package/dist/core/ecs/utils/error.d.ts +61 -0
  118. package/dist/core/ecs/utils/error.d.ts.map +1 -0
  119. package/dist/core/store/action_ring.d.cts +136 -0
  120. package/dist/core/store/action_ring.d.ts +136 -0
  121. package/dist/core/store/action_ring.d.ts.map +1 -0
  122. package/dist/core/store/allocator.d.cts +238 -0
  123. package/dist/core/store/allocator.d.ts +238 -0
  124. package/dist/core/store/allocator.d.ts.map +1 -0
  125. package/dist/core/store/buffer_backed_column.d.cts +69 -0
  126. package/dist/core/store/buffer_backed_column.d.ts +69 -0
  127. package/dist/core/store/buffer_backed_column.d.ts.map +1 -0
  128. package/dist/core/store/column_store.d.cts +273 -0
  129. package/dist/core/store/column_store.d.ts +273 -0
  130. package/dist/core/store/column_store.d.ts.map +1 -0
  131. package/dist/core/store/command_dispatch.d.cts +52 -0
  132. package/dist/core/store/command_dispatch.d.ts +52 -0
  133. package/dist/core/store/command_dispatch.d.ts.map +1 -0
  134. package/dist/core/store/command_ring.d.cts +107 -0
  135. package/dist/core/store/command_ring.d.ts +107 -0
  136. package/dist/core/store/command_ring.d.ts.map +1 -0
  137. package/dist/core/store/descriptor.d.cts +80 -0
  138. package/dist/core/store/descriptor.d.ts +80 -0
  139. package/dist/core/store/descriptor.d.ts.map +1 -0
  140. package/dist/core/store/entity_index.d.cts +108 -0
  141. package/dist/core/store/entity_index.d.ts +108 -0
  142. package/dist/core/store/entity_index.d.ts.map +1 -0
  143. package/dist/core/store/event_ring.d.cts +95 -0
  144. package/dist/core/store/event_ring.d.ts +95 -0
  145. package/dist/core/store/event_ring.d.ts.map +1 -0
  146. package/dist/core/store/extend.d.cts +39 -0
  147. package/dist/core/store/extend.d.ts +39 -0
  148. package/dist/core/store/extend.d.ts.map +1 -0
  149. package/dist/core/store/grow.d.cts +34 -0
  150. package/dist/core/store/grow.d.ts +34 -0
  151. package/dist/core/store/grow.d.ts.map +1 -0
  152. package/dist/core/store/header.d.cts +64 -0
  153. package/dist/core/store/header.d.ts +64 -0
  154. package/dist/core/store/header.d.ts.map +1 -0
  155. package/dist/core/store/index.d.cts +17 -0
  156. package/dist/core/store/index.d.ts +17 -0
  157. package/dist/core/store/index.d.ts.map +1 -0
  158. package/dist/core/store/layout_ops.d.cts +152 -0
  159. package/dist/core/store/layout_ops.d.ts +152 -0
  160. package/dist/core/store/layout_ops.d.ts.map +1 -0
  161. package/dist/core/store/region_table.d.cts +74 -0
  162. package/dist/core/store/region_table.d.ts +74 -0
  163. package/dist/core/store/region_table.d.ts.map +1 -0
  164. package/dist/core/store/snapshot.d.cts +43 -0
  165. package/dist/core/store/snapshot.d.ts +43 -0
  166. package/dist/core/store/snapshot.d.ts.map +1 -0
  167. package/dist/core/store/state_hash.d.cts +38 -0
  168. package/dist/core/store/state_hash.d.ts +38 -0
  169. package/dist/core/store/state_hash.d.ts.map +1 -0
  170. package/dist/core/store/store_regions.d.cts +38 -0
  171. package/dist/core/store/store_regions.d.ts +38 -0
  172. package/dist/core/store/store_regions.d.ts.map +1 -0
  173. package/dist/core/store/vendored_abi/abi.d.cts +43 -0
  174. package/dist/core/store/vendored_abi/abi.d.ts +43 -0
  175. package/dist/core/store/vendored_abi/abi.d.ts.map +1 -0
  176. package/dist/dev_flag.d.cts +17 -0
  177. package/dist/dev_flag.d.ts +17 -0
  178. package/dist/dev_flag.d.ts.map +1 -0
  179. package/dist/extensions/editor/editor.d.cts +170 -0
  180. package/dist/extensions/editor/editor.d.ts +170 -0
  181. package/dist/extensions/editor/editor.d.ts.map +1 -0
  182. package/dist/extensions/editor/field_handle.d.cts +40 -0
  183. package/dist/extensions/editor/field_handle.d.ts +40 -0
  184. package/dist/extensions/editor/field_handle.d.ts.map +1 -0
  185. package/dist/extensions/editor/index.cjs +1 -0
  186. package/dist/extensions/editor/index.d.cts +21 -0
  187. package/dist/extensions/editor/index.d.ts +21 -0
  188. package/dist/extensions/editor/index.d.ts.map +1 -0
  189. package/dist/extensions/editor/index.js +237 -0
  190. package/dist/extensions/reactive/ecs_sync.d.cts +214 -0
  191. package/dist/extensions/reactive/ecs_sync.d.ts +214 -0
  192. package/dist/extensions/reactive/ecs_sync.d.ts.map +1 -0
  193. package/dist/extensions/reactive/index.cjs +1 -0
  194. package/dist/extensions/reactive/index.d.cts +23 -0
  195. package/dist/extensions/reactive/index.d.ts +23 -0
  196. package/dist/extensions/reactive/index.d.ts.map +1 -0
  197. package/dist/extensions/reactive/index.js +215 -0
  198. package/dist/extensions/solid/index.cjs +1 -0
  199. package/dist/extensions/solid/index.d.cts +6 -0
  200. package/dist/extensions/solid/index.d.ts +6 -0
  201. package/dist/extensions/solid/index.d.ts.map +1 -0
  202. package/dist/extensions/solid/index.js +36 -0
  203. package/dist/extensions/solid/kernel_solid.d.cts +45 -0
  204. package/dist/extensions/solid/kernel_solid.d.ts +45 -0
  205. package/dist/extensions/solid/kernel_solid.d.ts.map +1 -0
  206. package/dist/host_commands-BF8QMi3c.cjs +1 -0
  207. package/dist/host_commands-i4cAeyL5.js +2318 -0
  208. package/dist/index.cjs +1 -1
  209. package/dist/index.d.cts +66 -0
  210. package/dist/index.d.ts +65 -12
  211. package/dist/index.d.ts.map +1 -1
  212. package/dist/index.js +7080 -1289
  213. package/dist/internal.cjs +2 -0
  214. package/dist/internal.d.cts +20 -0
  215. package/dist/internal.d.ts +20 -0
  216. package/dist/internal.d.ts.map +1 -0
  217. package/dist/internal.js +141 -0
  218. package/dist/interop-CT-REx0W.cjs +1 -0
  219. package/dist/interop-CcY6ASQc.js +18 -0
  220. package/dist/kernel-DgyrLFjW.js +227 -0
  221. package/dist/kernel-yWV3XnAb.cjs +1 -0
  222. package/dist/primitives.cjs +1 -0
  223. package/dist/primitives.d.cts +18 -0
  224. package/dist/primitives.d.ts +18 -0
  225. package/dist/primitives.d.ts.map +1 -0
  226. package/dist/primitives.js +45 -0
  227. package/dist/reactive/array.d.cts +24 -0
  228. package/dist/reactive/array.d.ts +24 -0
  229. package/dist/reactive/array.d.ts.map +1 -0
  230. package/dist/reactive/index.cjs +1 -0
  231. package/dist/reactive/index.d.cts +11 -0
  232. package/dist/reactive/index.d.ts +11 -0
  233. package/dist/reactive/index.d.ts.map +1 -0
  234. package/dist/reactive/index.js +18 -0
  235. package/dist/reactive/interop.d.cts +19 -0
  236. package/dist/reactive/interop.d.ts +19 -0
  237. package/dist/reactive/interop.d.ts.map +1 -0
  238. package/dist/reactive/kernel.d.cts +73 -0
  239. package/dist/reactive/kernel.d.ts +73 -0
  240. package/dist/reactive/kernel.d.ts.map +1 -0
  241. package/dist/reactive/map.d.cts +16 -0
  242. package/dist/reactive/map.d.ts +16 -0
  243. package/dist/reactive/map.d.ts.map +1 -0
  244. package/dist/reactive/shallow.d.cts +11 -0
  245. package/dist/reactive/shallow.d.ts +11 -0
  246. package/dist/reactive/shallow.d.ts.map +1 -0
  247. package/dist/reactive/struct.d.cts +10 -0
  248. package/dist/reactive/struct.d.ts +10 -0
  249. package/dist/reactive/struct.d.ts.map +1 -0
  250. package/dist/shallow-DQ8aG51_.cjs +1 -0
  251. package/dist/shallow-DfnAm9vG.js +150 -0
  252. package/dist/shared-BU1Cd40h.js +103 -0
  253. package/dist/shared-BymrGTyR.cjs +1 -0
  254. package/dist/shared.cjs +1 -0
  255. package/dist/shared.d.cts +22 -0
  256. package/dist/shared.d.ts +22 -0
  257. package/dist/shared.d.ts.map +1 -0
  258. package/dist/shared.js +7 -0
  259. package/dist/topological_sort-BDvEyb9W.cjs +1 -0
  260. package/dist/topological_sort-DK6EjpWa.js +135 -0
  261. package/dist/type_primitives/assertions.d.cts +32 -0
  262. package/dist/type_primitives/assertions.d.ts +25 -9
  263. package/dist/type_primitives/assertions.d.ts.map +1 -1
  264. package/dist/type_primitives/binary_heap/binary_heap.d.cts +37 -0
  265. package/dist/type_primitives/binary_heap/binary_heap.d.ts +6 -2
  266. package/dist/type_primitives/binary_heap/binary_heap.d.ts.map +1 -1
  267. package/dist/type_primitives/bitset/bitset.d.cts +54 -0
  268. package/dist/type_primitives/bitset/bitset.d.ts +16 -4
  269. package/dist/type_primitives/bitset/bitset.d.ts.map +1 -1
  270. package/dist/type_primitives/brand.d.cts +23 -0
  271. package/dist/type_primitives/brand.d.ts +6 -1
  272. package/dist/type_primitives/brand.d.ts.map +1 -1
  273. package/dist/type_primitives/error.d.cts +16 -0
  274. package/dist/type_primitives/error.d.ts +8 -3
  275. package/dist/type_primitives/error.d.ts.map +1 -1
  276. package/dist/type_primitives/index.d.cts +13 -0
  277. package/dist/type_primitives/index.d.ts +12 -9
  278. package/dist/type_primitives/index.d.ts.map +1 -1
  279. package/dist/type_primitives/sparse_map/sparse_map.d.cts +30 -0
  280. package/dist/type_primitives/sparse_map/sparse_map.d.ts +7 -3
  281. package/dist/type_primitives/sparse_map/sparse_map.d.ts.map +1 -1
  282. package/dist/type_primitives/sparse_set/sparse_set.d.cts +28 -0
  283. package/dist/type_primitives/sparse_set/sparse_set.d.ts +4 -0
  284. package/dist/type_primitives/sparse_set/sparse_set.d.ts.map +1 -1
  285. package/dist/type_primitives/topological_sort/topological_sort.d.cts +29 -0
  286. package/dist/type_primitives/topological_sort/topological_sort.d.ts +7 -3
  287. package/dist/type_primitives/topological_sort/topological_sort.d.ts.map +1 -1
  288. package/dist/type_primitives/typed_arrays/typed_arrays.d.cts +127 -0
  289. package/dist/type_primitives/typed_arrays/typed_arrays.d.ts +53 -16
  290. package/dist/type_primitives/typed_arrays/typed_arrays.d.ts.map +1 -1
  291. package/dist/typed_arrays-BcXcnzB4.js +258 -0
  292. package/dist/typed_arrays-D3NmwtCG.cjs +1 -0
  293. package/dist/utils/error.d.cts +6 -0
  294. package/dist/utils/error.d.ts +2 -20
  295. package/dist/utils/error.d.ts.map +1 -1
  296. package/dist/version.d.cts +10 -0
  297. package/dist/version.d.ts +10 -0
  298. package/dist/version.d.ts.map +1 -0
  299. package/package.json +115 -5
  300. package/dist/archetype.d.ts +0 -108
  301. package/dist/archetype.d.ts.map +0 -1
  302. package/dist/component.d.ts +0 -45
  303. package/dist/component.d.ts.map +0 -1
  304. package/dist/ecs.d.ts +0 -104
  305. package/dist/ecs.d.ts.map +0 -1
  306. package/dist/entity.d.ts +0 -11
  307. package/dist/entity.d.ts.map +0 -1
  308. package/dist/event.d.ts +0 -30
  309. package/dist/event.d.ts.map +0 -1
  310. package/dist/query.d.ts +0 -94
  311. package/dist/query.d.ts.map +0 -1
  312. package/dist/ref.d.ts +0 -23
  313. package/dist/ref.d.ts.map +0 -1
  314. package/dist/resource.d.ts +0 -23
  315. package/dist/resource.d.ts.map +0 -1
  316. package/dist/schedule.d.ts +0 -45
  317. package/dist/schedule.d.ts.map +0 -1
  318. package/dist/store.d.ts +0 -118
  319. package/dist/store.d.ts.map +0 -1
  320. package/dist/system.d.ts +0 -16
  321. package/dist/system.d.ts.map +0 -1
  322. package/dist/utils/arrays.d.ts.map +0 -1
  323. package/dist/utils/constants.d.ts.map +0 -1
  324. /package/dist/{utils/constants.d.ts → core/ecs/utils/constants.d.cts} +0 -0
@@ -0,0 +1,94 @@
1
+ import { Archetype } from './archetype.cjs';
2
+ import { EntityAllocator } from './entity_allocator.cjs';
3
+ import { SparseComponentStore } from './sparse_store.cjs';
4
+ import { RelationStore } from './relation.cjs';
5
+ import { ColumnStore, InPlaceBufferAllocator } from '../store/index.cjs';
6
+ import { HostState } from './resume.cjs';
7
+ /** What the snapshot/resume orchestration needs from `Store` — closure-
8
+ * injected (the `RelationServiceHost` style). Accessors re-read live fields
9
+ * per call (the column store and the entity-index views are replaced on
10
+ * restore); the three mutation members keep Store-owned state transitions on
11
+ * the Store side. All cold-path. */
12
+ export interface SnapshotHost {
13
+ readonly sparseStores: () => readonly SparseComponentStore[];
14
+ readonly relationStores: () => readonly RelationStore[];
15
+ /** Live SAB generations view (replanted on restore) — for rebuilding
16
+ * relation ids from entity indices. */
17
+ readonly generations: () => Int32Array;
18
+ readonly archetypes: () => readonly Archetype[];
19
+ readonly columnStore: () => ColumnStore;
20
+ readonly bufferAllocator: () => InPlaceBufferAllocator;
21
+ readonly entityIndexCapacity: () => number;
22
+ readonly tick: () => number;
23
+ readonly setTick: (tick: number) => void;
24
+ /** Stamp live row counts into the dense descriptors so a bare dense
25
+ * reader of the snapshot sees self-consistent counts. */
26
+ readonly publishRowCounts: () => void;
27
+ /** Adopt a restored dense store: swap the live backing, refresh archetype
28
+ * views, recover the allocator high-water from the restored region, and
29
+ * republish (the grow tail). Owned by Store — see `_mountRestoredDense`. */
30
+ readonly mountRestoredDense: (restored: ColumnStore) => void;
31
+ /** Rebuild each archetype's host-side `length`/`enabledCount`/entity-id
32
+ * back-references from the restored entity-index region + captured host
33
+ * state. Owned by Store — see `_reconstructHostRows`. */
34
+ readonly reconstructHostRows: (host: HostState) => void;
35
+ /** Every archetype's membership just changed — bump the query epoch and
36
+ * force the next descriptor publish. */
37
+ readonly invalidateQueryCaches: () => void;
38
+ }
39
+ export declare class SnapshotService {
40
+ private readonly host;
41
+ /** The allocator IS its own snapshot seam (H1 step 3): free-list copy on
42
+ * capture; `setHighWater` + `restoreHostState` on mount. */
43
+ private readonly allocator;
44
+ constructor(host: SnapshotHost, allocator: EntityAllocator);
45
+ /** Serialize the sparse stores **and** relation side data to a self-contained
46
+ * byte buffer — the sparse half of a world snapshot (the dense half is the
47
+ * SAB snapshot). Two framed sections: the sparse stores (`snapshotSparseStores`
48
+ * — exclusive relation targets + multi membership ride here) followed
49
+ * by the relation side data (`snapshotRelations` — multi forward target
50
+ * sets, which live outside the sparse store). Both are written in canonical
51
+ * entity-index order, so two worlds with identical contents inserted in
52
+ * different orders snapshot byte-for-byte the same (#470). The reverse index
53
+ * is derived and never serialized — `restoreSparse` rebuilds it. */
54
+ snapshotSparse(): Uint8Array;
55
+ /** Repopulate the sparse stores from `snapshotSparse` bytes, replacing all
56
+ * current sparse data (full-equality round-trip of membership + data), then
57
+ * rebuild every relation's derived side indices: multi forward sets from the
58
+ * relation section, and the reverse index for both cardinalities (exclusive
59
+ * from the just-restored sparse target field, multi from the rebuilt forward
60
+ * sets). The sparse components and relations must already be registered in
61
+ * the same order — restore carries data, not the registration (which is
62
+ * code). Throws `SparseRestoreError` if the snapshot's shape, field identity,
63
+ * entity-index bounds, or frame length don't validate. */
64
+ restoreSparse(bytes: Uint8Array): void;
65
+ /** Rebuild every relation's derived side indices after the sparse stores have
66
+ * been restored. `restoreRelations` resets all relations, rebuilds the multi
67
+ * forward sets + their reverse edges from `relBytes`, and validates shape.
68
+ * The exclusive reverse index can't be carried in the bytes (it's derivable),
69
+ * so it's rebuilt here from the backing sparse store: every member row holds
70
+ * `(source index → target EntityID)`, which is exactly one reverse edge. */
71
+ private rebuildRelationIndices;
72
+ /** Capture the full live world to one self-contained byte buffer that
73
+ * `restoreInto` can mount back onto a live, ticking world (#789). Three
74
+ * sections (see `resume.ts`): the dense SAB column bytes, the sparse +
75
+ * relation bytes, and the host-side bookkeeping the SAB omits. */
76
+ snapshot(): Uint8Array;
77
+ /** Gather the host-side state a snapshot carries alongside the dense + sparse
78
+ * bytes — see `snapshot()`. The free-list is copied (it's a live mutable). */
79
+ private collectHostState;
80
+ /** Mount a `snapshot()` buffer onto the live world and leave it ready to keep
81
+ * ticking. Fails closed on a malformed frame or a registration mismatch
82
+ * BEFORE any live state is touched. */
83
+ restoreInto(bytes: Uint8Array): void;
84
+ /** Read-only validation of a `snapshotSparse` SECTION (the framed
85
+ * `[sparseLen][relLen][sparse][rel]` buffer) against the live registry, used
86
+ * by `restoreInto` to fail closed on a sparse-registration mismatch BEFORE the
87
+ * dense mount commits. Mirrors `restoreSparse`'s frame check, then validates the
88
+ * sparse-stores sub-section without mutating. A relation-registration difference
89
+ * surfaces here too: every `registerRelation` adds a backing sparse store, so a
90
+ * differing relation set changes the sparse store count / schema. Throws
91
+ * `SparseRestoreError` on a mismatch. */
92
+ private assertSparseSectionMatches;
93
+ }
94
+ //# sourceMappingURL=snapshot_service.d.ts.map
@@ -0,0 +1,94 @@
1
+ import { Archetype } from './archetype.js';
2
+ import { EntityAllocator } from './entity_allocator.js';
3
+ import { SparseComponentStore } from './sparse_store.js';
4
+ import { RelationStore } from './relation.js';
5
+ import { ColumnStore, InPlaceBufferAllocator } from '../store/index.js';
6
+ import { HostState } from './resume.js';
7
+ /** What the snapshot/resume orchestration needs from `Store` — closure-
8
+ * injected (the `RelationServiceHost` style). Accessors re-read live fields
9
+ * per call (the column store and the entity-index views are replaced on
10
+ * restore); the three mutation members keep Store-owned state transitions on
11
+ * the Store side. All cold-path. */
12
+ export interface SnapshotHost {
13
+ readonly sparseStores: () => readonly SparseComponentStore[];
14
+ readonly relationStores: () => readonly RelationStore[];
15
+ /** Live SAB generations view (replanted on restore) — for rebuilding
16
+ * relation ids from entity indices. */
17
+ readonly generations: () => Int32Array;
18
+ readonly archetypes: () => readonly Archetype[];
19
+ readonly columnStore: () => ColumnStore;
20
+ readonly bufferAllocator: () => InPlaceBufferAllocator;
21
+ readonly entityIndexCapacity: () => number;
22
+ readonly tick: () => number;
23
+ readonly setTick: (tick: number) => void;
24
+ /** Stamp live row counts into the dense descriptors so a bare dense
25
+ * reader of the snapshot sees self-consistent counts. */
26
+ readonly publishRowCounts: () => void;
27
+ /** Adopt a restored dense store: swap the live backing, refresh archetype
28
+ * views, recover the allocator high-water from the restored region, and
29
+ * republish (the grow tail). Owned by Store — see `_mountRestoredDense`. */
30
+ readonly mountRestoredDense: (restored: ColumnStore) => void;
31
+ /** Rebuild each archetype's host-side `length`/`enabledCount`/entity-id
32
+ * back-references from the restored entity-index region + captured host
33
+ * state. Owned by Store — see `_reconstructHostRows`. */
34
+ readonly reconstructHostRows: (host: HostState) => void;
35
+ /** Every archetype's membership just changed — bump the query epoch and
36
+ * force the next descriptor publish. */
37
+ readonly invalidateQueryCaches: () => void;
38
+ }
39
+ export declare class SnapshotService {
40
+ private readonly host;
41
+ /** The allocator IS its own snapshot seam (H1 step 3): free-list copy on
42
+ * capture; `setHighWater` + `restoreHostState` on mount. */
43
+ private readonly allocator;
44
+ constructor(host: SnapshotHost, allocator: EntityAllocator);
45
+ /** Serialize the sparse stores **and** relation side data to a self-contained
46
+ * byte buffer — the sparse half of a world snapshot (the dense half is the
47
+ * SAB snapshot). Two framed sections: the sparse stores (`snapshotSparseStores`
48
+ * — exclusive relation targets + multi membership ride here) followed
49
+ * by the relation side data (`snapshotRelations` — multi forward target
50
+ * sets, which live outside the sparse store). Both are written in canonical
51
+ * entity-index order, so two worlds with identical contents inserted in
52
+ * different orders snapshot byte-for-byte the same (#470). The reverse index
53
+ * is derived and never serialized — `restoreSparse` rebuilds it. */
54
+ snapshotSparse(): Uint8Array;
55
+ /** Repopulate the sparse stores from `snapshotSparse` bytes, replacing all
56
+ * current sparse data (full-equality round-trip of membership + data), then
57
+ * rebuild every relation's derived side indices: multi forward sets from the
58
+ * relation section, and the reverse index for both cardinalities (exclusive
59
+ * from the just-restored sparse target field, multi from the rebuilt forward
60
+ * sets). The sparse components and relations must already be registered in
61
+ * the same order — restore carries data, not the registration (which is
62
+ * code). Throws `SparseRestoreError` if the snapshot's shape, field identity,
63
+ * entity-index bounds, or frame length don't validate. */
64
+ restoreSparse(bytes: Uint8Array): void;
65
+ /** Rebuild every relation's derived side indices after the sparse stores have
66
+ * been restored. `restoreRelations` resets all relations, rebuilds the multi
67
+ * forward sets + their reverse edges from `relBytes`, and validates shape.
68
+ * The exclusive reverse index can't be carried in the bytes (it's derivable),
69
+ * so it's rebuilt here from the backing sparse store: every member row holds
70
+ * `(source index → target EntityID)`, which is exactly one reverse edge. */
71
+ private rebuildRelationIndices;
72
+ /** Capture the full live world to one self-contained byte buffer that
73
+ * `restoreInto` can mount back onto a live, ticking world (#789). Three
74
+ * sections (see `resume.ts`): the dense SAB column bytes, the sparse +
75
+ * relation bytes, and the host-side bookkeeping the SAB omits. */
76
+ snapshot(): Uint8Array;
77
+ /** Gather the host-side state a snapshot carries alongside the dense + sparse
78
+ * bytes — see `snapshot()`. The free-list is copied (it's a live mutable). */
79
+ private collectHostState;
80
+ /** Mount a `snapshot()` buffer onto the live world and leave it ready to keep
81
+ * ticking. Fails closed on a malformed frame or a registration mismatch
82
+ * BEFORE any live state is touched. */
83
+ restoreInto(bytes: Uint8Array): void;
84
+ /** Read-only validation of a `snapshotSparse` SECTION (the framed
85
+ * `[sparseLen][relLen][sparse][rel]` buffer) against the live registry, used
86
+ * by `restoreInto` to fail closed on a sparse-registration mismatch BEFORE the
87
+ * dense mount commits. Mirrors `restoreSparse`'s frame check, then validates the
88
+ * sparse-stores sub-section without mutating. A relation-registration difference
89
+ * surfaces here too: every `registerRelation` adds a backing sparse store, so a
90
+ * differing relation set changes the sparse store count / schema. Throws
91
+ * `SparseRestoreError` on a mismatch. */
92
+ private assertSparseSectionMatches;
93
+ }
94
+ //# sourceMappingURL=snapshot_service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot_service.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/snapshot_service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EACN,oBAAoB,EAKpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAuC,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAGN,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAC3B,MAAM,UAAU,CAAC;AAClB,OAAO,EAON,KAAK,SAAS,EACd,MAAM,UAAU,CAAC;AAElB;;;;oCAIoC;AACpC,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,SAAS,oBAAoB,EAAE,CAAC;IAC7D,QAAQ,CAAC,cAAc,EAAE,MAAM,SAAS,aAAa,EAAE,CAAC;IACxD;2CACuC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,UAAU,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,SAAS,SAAS,EAAE,CAAC;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,WAAW,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,MAAM,sBAAsB,CAAC;IACvD,QAAQ,CAAC,mBAAmB,EAAE,MAAM,MAAM,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC;6DACyD;IACzD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,IAAI,CAAC;IACtC;;gFAE4E;IAC5E,QAAQ,CAAC,kBAAkB,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7D;;6DAEyD;IACzD,QAAQ,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACxD;4CACwC;IACxC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,IAAI,CAAC;CAC3C;AAED,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAe;IACpC;gEAC4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;gBAEhC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe;IAK1D;;;;;;;;wEAQoE;IAC7D,cAAc,IAAI,UAAU;IAanC;;;;;;;;8DAQ0D;IACnD,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAuB7C;;;;;gFAK4E;IAC5E,OAAO,CAAC,sBAAsB;IAW9B;;;sEAGkE;IAC3D,QAAQ,IAAI,UAAU;IAa7B;kFAC8E;IAC9E,OAAO,CAAC,gBAAgB;IAqBxB;;2CAEuC;IAChC,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IA2C3C;;;;;;;6CAOyC;IACzC,OAAO,CAAC,0BAA0B;CAgBlC"}
@@ -0,0 +1,110 @@
1
+ import { Brand, TypedArrayTag } from '../../type_primitives/index.cjs';
2
+ import { ComponentSchema } from './component.cjs';
3
+ /** Sparse-component handle id. A separate id space from `ComponentID` — it
4
+ * indexes `Store`'s `sparseStores`, never the archetype mask, which is the
5
+ * mechanism by which sparse components escape the 128-bit identity cap. */
6
+ export type SparseComponentID = Brand<number, "sparse_component_id">;
7
+ declare const __sparseSchema: unique symbol;
8
+ export type SparseComponentDef<S extends ComponentSchema = ComponentSchema> = SparseComponentID & {
9
+ readonly [__sparseSchema]: S;
10
+ };
11
+ /** Recover a sparse def's schema type — the sparse sibling of `SchemaOf`
12
+ * (component.ts), used by the typed `SystemContext` sparse surface. */
13
+ export type SparseSchemaOf<D> = D extends SparseComponentDef<infer S extends ComponentSchema> ? S : never;
14
+ /** One sparse component's membership + data. Pure data structure — the `Store`
15
+ * owns liveness checks and dev-mode error throwing; this class only knows
16
+ * entity indices and field rows. */
17
+ export declare class SparseComponentStore {
18
+ /** entity index → field-value row (length = field count; `[]` for a tag). */
19
+ private readonly _data;
20
+ readonly fieldNames: string[];
21
+ readonly fieldTypes: TypedArrayTag[];
22
+ readonly fieldIndex: Record<string, number>;
23
+ constructor(fieldNames: string[], fieldTypes: TypedArrayTag[]);
24
+ /** Number of entities holding this sparse component. */
25
+ get size(): number;
26
+ /** Live entity indices that hold this component (dense, iteration order is
27
+ * SparseMap insertion/swap order — NOT canonical). Used by the hot query
28
+ * integration path (#469); for the determinism surface use
29
+ * `canonicalIndices` instead. */
30
+ get indices(): readonly number[];
31
+ /** Live entity indices in **canonical** (ascending) order — the determinism
32
+ * ordering for `stateHash` + snapshot/restore (ADR-0011, #470). The native
33
+ * `indices` getter is insertion/swap order and would make two worlds with
34
+ * identical contents reached by different add/remove histories diverge, so
35
+ * the cold determinism paths sort here. Allocates a sorted copy each call;
36
+ * never call it on the hot query path. Indices are 20-bit entity indices,
37
+ * so the subtraction comparator can't overflow. */
38
+ canonicalIndices(): number[];
39
+ /** The field-value row for `index` (length = field count; `[]` for a tag),
40
+ * or `undefined` if `index` isn't a member. Read-only view for the
41
+ * determinism paths (`stateHash`, snapshot); mutate via `setField`. */
42
+ getRow(index: number): readonly number[] | undefined;
43
+ /** Drop all membership + data. Restore path only — `restoreSparseStores`
44
+ * repopulates a cleared store from snapshot bytes. */
45
+ clear(): void;
46
+ /** Insert the positional field-value `row` for `index`, taking ownership of
47
+ * the array. Restore path only; bypasses the name→index mapping `setRow`
48
+ * does, because snapshot bytes are already positional. */
49
+ setRawRow(index: number, row: number[]): void;
50
+ has(index: number): boolean;
51
+ /** Insert or overwrite the row for `index`, building it from `values`.
52
+ * Fields absent from `values` default to 0; a tag stores `[]`. */
53
+ setRow(index: number, values: Record<string, number>): void;
54
+ /** Drop `index`'s membership + data. Returns whether it was present. */
55
+ remove(index: number): boolean;
56
+ /** Read one field, or `undefined` if `index` doesn't hold this component. */
57
+ getField(index: number, fieldIdx: number): number | undefined;
58
+ /** Write one field. Returns `false` (no-op) if `index` isn't a member. */
59
+ setField(index: number, fieldIdx: number, value: number): boolean;
60
+ }
61
+ export declare class SparseRestoreError extends Error {
62
+ constructor(message: string);
63
+ }
64
+ /** Serialize a registry of sparse stores into a self-contained byte buffer —
65
+ * the **sparse half** of a world snapshot (the dense half is the SAB snapshot,
66
+ * `snapshotColumnStore`). Members are emitted in canonical (ascending
67
+ * entity-index) order so the bytes are independent of insertion / removal
68
+ * history: two worlds with identical sparse contents reached by different
69
+ * mutation orders serialize byte-for-byte the same (#470).
70
+ *
71
+ * Layout (all integers little-endian, to match the dense SAB snapshot and stay
72
+ * architecture-independent):
73
+ *
74
+ * u32 storeCount
75
+ * repeat storeCount times:
76
+ * u32 fieldCount
77
+ * u32 schemaHash
78
+ * u32 memberCount
79
+ * repeat memberCount times (canonical entity-index order):
80
+ * u32 entityIndex
81
+ * f64 × fieldCount (the positional field row; none for a tag)
82
+ *
83
+ * `fieldCount` is redundant with the registered schema but is written so
84
+ * `restoreSparseStores` can reject a snapshot whose shape doesn't match the
85
+ * stores it's restoring into; `schemaHash` (a `schemaFingerprint` over the
86
+ * field names + types) goes further and rejects a buffer whose shape matches
87
+ * field-for-field but whose field **identity** doesn't (#494). */
88
+ export declare function snapshotSparseStores(stores: readonly SparseComponentStore[]): Uint8Array;
89
+ /** Repopulate already-registered sparse stores from `snapshotSparseStores`
90
+ * bytes, giving full-equality round-trip (membership + data). The `stores`
91
+ * registry must already exist with the same shape the snapshot was taken from
92
+ * — restore replays data into a world whose sparse components are registered
93
+ * in the same order (the registration is code, not snapshot state). Each store
94
+ * is cleared first, so restoring is idempotent and drops any pre-existing rows.
95
+ *
96
+ * Throws `SparseRestoreError` on any shape or identity mismatch (store count,
97
+ * field count, schema-hash field identity, an entity index past `MAX_INDEX`,
98
+ * or a truncated / over-long buffer) rather than silently corrupting state.
99
+ * The index bound matters because the index keys a `SparseMap` whose backing
100
+ * array grows to `index` length — an unvalidated crafted u32 (up to ~4.29e9)
101
+ * would allocate multi-GB (#494). */
102
+ export declare function restoreSparseStores(stores: readonly SparseComponentStore[], bytes: Uint8Array): void;
103
+ /** Read-only validation of a `snapshotSparseStores` buffer against the live
104
+ * registry, WITHOUT mutating any store (#789). Mirrors `restoreSparseStores`'s
105
+ * shape/field-identity/index-bounds/frame checks so `Store.restoreInto` can fail
106
+ * closed on a sparse-registration mismatch BEFORE the dense mount overwrites live
107
+ * column data. Throws `SparseRestoreError` on any mismatch / malformed buffer. */
108
+ export declare function validateSparseStores(stores: readonly SparseComponentStore[], bytes: Uint8Array): void;
109
+ export {};
110
+ //# sourceMappingURL=sparse_store.d.ts.map
@@ -0,0 +1,110 @@
1
+ import { Brand, TypedArrayTag } from '../../type_primitives/index.js';
2
+ import { ComponentSchema } from './component.js';
3
+ /** Sparse-component handle id. A separate id space from `ComponentID` — it
4
+ * indexes `Store`'s `sparseStores`, never the archetype mask, which is the
5
+ * mechanism by which sparse components escape the 128-bit identity cap. */
6
+ export type SparseComponentID = Brand<number, "sparse_component_id">;
7
+ declare const __sparseSchema: unique symbol;
8
+ export type SparseComponentDef<S extends ComponentSchema = ComponentSchema> = SparseComponentID & {
9
+ readonly [__sparseSchema]: S;
10
+ };
11
+ /** Recover a sparse def's schema type — the sparse sibling of `SchemaOf`
12
+ * (component.ts), used by the typed `SystemContext` sparse surface. */
13
+ export type SparseSchemaOf<D> = D extends SparseComponentDef<infer S extends ComponentSchema> ? S : never;
14
+ /** One sparse component's membership + data. Pure data structure — the `Store`
15
+ * owns liveness checks and dev-mode error throwing; this class only knows
16
+ * entity indices and field rows. */
17
+ export declare class SparseComponentStore {
18
+ /** entity index → field-value row (length = field count; `[]` for a tag). */
19
+ private readonly _data;
20
+ readonly fieldNames: string[];
21
+ readonly fieldTypes: TypedArrayTag[];
22
+ readonly fieldIndex: Record<string, number>;
23
+ constructor(fieldNames: string[], fieldTypes: TypedArrayTag[]);
24
+ /** Number of entities holding this sparse component. */
25
+ get size(): number;
26
+ /** Live entity indices that hold this component (dense, iteration order is
27
+ * SparseMap insertion/swap order — NOT canonical). Used by the hot query
28
+ * integration path (#469); for the determinism surface use
29
+ * `canonicalIndices` instead. */
30
+ get indices(): readonly number[];
31
+ /** Live entity indices in **canonical** (ascending) order — the determinism
32
+ * ordering for `stateHash` + snapshot/restore (ADR-0011, #470). The native
33
+ * `indices` getter is insertion/swap order and would make two worlds with
34
+ * identical contents reached by different add/remove histories diverge, so
35
+ * the cold determinism paths sort here. Allocates a sorted copy each call;
36
+ * never call it on the hot query path. Indices are 20-bit entity indices,
37
+ * so the subtraction comparator can't overflow. */
38
+ canonicalIndices(): number[];
39
+ /** The field-value row for `index` (length = field count; `[]` for a tag),
40
+ * or `undefined` if `index` isn't a member. Read-only view for the
41
+ * determinism paths (`stateHash`, snapshot); mutate via `setField`. */
42
+ getRow(index: number): readonly number[] | undefined;
43
+ /** Drop all membership + data. Restore path only — `restoreSparseStores`
44
+ * repopulates a cleared store from snapshot bytes. */
45
+ clear(): void;
46
+ /** Insert the positional field-value `row` for `index`, taking ownership of
47
+ * the array. Restore path only; bypasses the name→index mapping `setRow`
48
+ * does, because snapshot bytes are already positional. */
49
+ setRawRow(index: number, row: number[]): void;
50
+ has(index: number): boolean;
51
+ /** Insert or overwrite the row for `index`, building it from `values`.
52
+ * Fields absent from `values` default to 0; a tag stores `[]`. */
53
+ setRow(index: number, values: Record<string, number>): void;
54
+ /** Drop `index`'s membership + data. Returns whether it was present. */
55
+ remove(index: number): boolean;
56
+ /** Read one field, or `undefined` if `index` doesn't hold this component. */
57
+ getField(index: number, fieldIdx: number): number | undefined;
58
+ /** Write one field. Returns `false` (no-op) if `index` isn't a member. */
59
+ setField(index: number, fieldIdx: number, value: number): boolean;
60
+ }
61
+ export declare class SparseRestoreError extends Error {
62
+ constructor(message: string);
63
+ }
64
+ /** Serialize a registry of sparse stores into a self-contained byte buffer —
65
+ * the **sparse half** of a world snapshot (the dense half is the SAB snapshot,
66
+ * `snapshotColumnStore`). Members are emitted in canonical (ascending
67
+ * entity-index) order so the bytes are independent of insertion / removal
68
+ * history: two worlds with identical sparse contents reached by different
69
+ * mutation orders serialize byte-for-byte the same (#470).
70
+ *
71
+ * Layout (all integers little-endian, to match the dense SAB snapshot and stay
72
+ * architecture-independent):
73
+ *
74
+ * u32 storeCount
75
+ * repeat storeCount times:
76
+ * u32 fieldCount
77
+ * u32 schemaHash
78
+ * u32 memberCount
79
+ * repeat memberCount times (canonical entity-index order):
80
+ * u32 entityIndex
81
+ * f64 × fieldCount (the positional field row; none for a tag)
82
+ *
83
+ * `fieldCount` is redundant with the registered schema but is written so
84
+ * `restoreSparseStores` can reject a snapshot whose shape doesn't match the
85
+ * stores it's restoring into; `schemaHash` (a `schemaFingerprint` over the
86
+ * field names + types) goes further and rejects a buffer whose shape matches
87
+ * field-for-field but whose field **identity** doesn't (#494). */
88
+ export declare function snapshotSparseStores(stores: readonly SparseComponentStore[]): Uint8Array;
89
+ /** Repopulate already-registered sparse stores from `snapshotSparseStores`
90
+ * bytes, giving full-equality round-trip (membership + data). The `stores`
91
+ * registry must already exist with the same shape the snapshot was taken from
92
+ * — restore replays data into a world whose sparse components are registered
93
+ * in the same order (the registration is code, not snapshot state). Each store
94
+ * is cleared first, so restoring is idempotent and drops any pre-existing rows.
95
+ *
96
+ * Throws `SparseRestoreError` on any shape or identity mismatch (store count,
97
+ * field count, schema-hash field identity, an entity index past `MAX_INDEX`,
98
+ * or a truncated / over-long buffer) rather than silently corrupting state.
99
+ * The index bound matters because the index keys a `SparseMap` whose backing
100
+ * array grows to `index` length — an unvalidated crafted u32 (up to ~4.29e9)
101
+ * would allocate multi-GB (#494). */
102
+ export declare function restoreSparseStores(stores: readonly SparseComponentStore[], bytes: Uint8Array): void;
103
+ /** Read-only validation of a `snapshotSparseStores` buffer against the live
104
+ * registry, WITHOUT mutating any store (#789). Mirrors `restoreSparseStores`'s
105
+ * shape/field-identity/index-bounds/frame checks so `Store.restoreInto` can fail
106
+ * closed on a sparse-registration mismatch BEFORE the dense mount overwrites live
107
+ * column data. Throws `SparseRestoreError` on any mismatch / malformed buffer. */
108
+ export declare function validateSparseStores(stores: readonly SparseComponentStore[], bytes: Uint8Array): void;
109
+ export {};
110
+ //# sourceMappingURL=sparse_store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sparse_store.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/sparse_store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;KA0BK;AAEL,OAAO,EAAE,KAAK,EAAa,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD;;2EAE2E;AAC3E,MAAM,MAAM,iBAAiB,GAAG,KAAK,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;AAOrE,OAAO,CAAC,MAAM,cAAc,EAAE,OAAO,MAAM,CAAC;AAE5C,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,IAAI,iBAAiB,GAAG;IACjG,QAAQ,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;CAC7B,CAAC;AAEF;uEACuE;AACvE,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,CAAC,SAAS,kBAAkB,CAAC,MAAM,CAAC,SAAS,eAAe,CAAC,GAC1F,CAAC,GACD,KAAK,CAAC;AAET;;oCAEoC;AACpC,qBAAa,oBAAoB;IAChC,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD,SAAgB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrC,SAAgB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5C,SAAgB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAEvC,UAAU,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE;IAQ7D,wDAAwD;IACxD,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;;qCAGiC;IACjC,IAAW,OAAO,IAAI,SAAS,MAAM,EAAE,CAEtC;IAED;;;;;;uDAMmD;IAC5C,gBAAgB,IAAI,MAAM,EAAE;IAInC;;2EAEuE;IAChE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS;IAI3D;0DACsD;IAC/C,KAAK,IAAI,IAAI;IAIpB;;8DAE0D;IACnD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI;IAI7C,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIlC;sEACkE;IAC3D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAUlE,wEAAwE;IACjE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIrC,6EAA6E;IACtE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKpE,0EAA0E;IACnE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;CAMxE;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI3B;AAuCD;;;;;;;;;;;;;;;;;;;;;;;kEAuBkE;AAClE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,oBAAoB,EAAE,GAAG,UAAU,CAuCxF;AAED;;;;;;;;;;;;qCAYqC;AACrC,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,SAAS,oBAAoB,EAAE,EACvC,KAAK,EAAE,UAAU,GACf,IAAI,CAkEN;AAED;;;;kFAIkF;AAClF,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,SAAS,oBAAoB,EAAE,EACvC,KAAK,EAAE,UAAU,GACf,IAAI,CA4DN"}