tinybase 8.0.0-beta.0 → 8.0.0-beta.2

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 (264) hide show
  1. package/@types/index.d.ts +1 -0
  2. package/@types/mergeable-store/with-schemas/index.d.ts +1 -1
  3. package/@types/middleware/index.d.ts +1181 -0
  4. package/@types/middleware/with-schemas/index.d.ts +1495 -0
  5. package/@types/omni/index.d.ts +1 -0
  6. package/@types/omni/with-schemas/index.d.ts +1 -0
  7. package/@types/store/index.d.ts +0 -1
  8. package/@types/with-schemas/index.d.ts +1 -0
  9. package/agents.md +33 -11
  10. package/checkpoints/index.js +20 -20
  11. package/checkpoints/with-schemas/index.js +20 -20
  12. package/common/index.js +3 -2
  13. package/common/with-schemas/index.js +3 -2
  14. package/index.js +632 -215
  15. package/indexes/index.js +13 -12
  16. package/indexes/with-schemas/index.js +13 -12
  17. package/mergeable-store/index.js +498 -197
  18. package/mergeable-store/with-schemas/index.js +498 -197
  19. package/metrics/index.js +13 -12
  20. package/metrics/with-schemas/index.js +13 -12
  21. package/middleware/index.js +169 -0
  22. package/middleware/with-schemas/index.js +169 -0
  23. package/min/checkpoints/index.js +1 -1
  24. package/min/checkpoints/index.js.gz +0 -0
  25. package/min/checkpoints/with-schemas/index.js +1 -1
  26. package/min/checkpoints/with-schemas/index.js.gz +0 -0
  27. package/min/common/index.js +1 -1
  28. package/min/common/index.js.gz +0 -0
  29. package/min/common/with-schemas/index.js +1 -1
  30. package/min/common/with-schemas/index.js.gz +0 -0
  31. package/min/index.js +1 -1
  32. package/min/index.js.gz +0 -0
  33. package/min/indexes/index.js +1 -1
  34. package/min/indexes/index.js.gz +0 -0
  35. package/min/indexes/with-schemas/index.js +1 -1
  36. package/min/indexes/with-schemas/index.js.gz +0 -0
  37. package/min/mergeable-store/index.js +1 -1
  38. package/min/mergeable-store/index.js.gz +0 -0
  39. package/min/mergeable-store/with-schemas/index.js +1 -1
  40. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  41. package/min/metrics/index.js +1 -1
  42. package/min/metrics/index.js.gz +0 -0
  43. package/min/metrics/with-schemas/index.js +1 -1
  44. package/min/metrics/with-schemas/index.js.gz +0 -0
  45. package/min/middleware/index.js +1 -0
  46. package/min/middleware/index.js.gz +0 -0
  47. package/min/middleware/with-schemas/index.js +1 -0
  48. package/min/middleware/with-schemas/index.js.gz +0 -0
  49. package/min/omni/index.js +1 -1
  50. package/min/omni/index.js.gz +0 -0
  51. package/min/omni/with-schemas/index.js +1 -1
  52. package/min/omni/with-schemas/index.js.gz +0 -0
  53. package/min/persisters/index.js +1 -1
  54. package/min/persisters/index.js.gz +0 -0
  55. package/min/persisters/persister-automerge/index.js +1 -1
  56. package/min/persisters/persister-automerge/index.js.gz +0 -0
  57. package/min/persisters/persister-automerge/with-schemas/index.js +1 -1
  58. package/min/persisters/persister-automerge/with-schemas/index.js.gz +0 -0
  59. package/min/persisters/persister-browser/index.js +1 -1
  60. package/min/persisters/persister-browser/index.js.gz +0 -0
  61. package/min/persisters/persister-browser/with-schemas/index.js +1 -1
  62. package/min/persisters/persister-browser/with-schemas/index.js.gz +0 -0
  63. package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
  64. package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
  65. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
  66. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
  67. package/min/persisters/persister-durable-object-sql-storage/index.js +1 -1
  68. package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
  69. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -1
  70. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
  71. package/min/persisters/persister-durable-object-storage/index.js +1 -1
  72. package/min/persisters/persister-durable-object-storage/index.js.gz +0 -0
  73. package/min/persisters/persister-durable-object-storage/with-schemas/index.js +1 -1
  74. package/min/persisters/persister-durable-object-storage/with-schemas/index.js.gz +0 -0
  75. package/min/persisters/persister-electric-sql/index.js +1 -1
  76. package/min/persisters/persister-electric-sql/index.js.gz +0 -0
  77. package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
  78. package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
  79. package/min/persisters/persister-expo-sqlite/index.js +1 -1
  80. package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
  81. package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
  82. package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
  83. package/min/persisters/persister-file/index.js +1 -1
  84. package/min/persisters/persister-file/index.js.gz +0 -0
  85. package/min/persisters/persister-file/with-schemas/index.js +1 -1
  86. package/min/persisters/persister-file/with-schemas/index.js.gz +0 -0
  87. package/min/persisters/persister-indexed-db/index.js +1 -1
  88. package/min/persisters/persister-indexed-db/index.js.gz +0 -0
  89. package/min/persisters/persister-indexed-db/with-schemas/index.js +1 -1
  90. package/min/persisters/persister-indexed-db/with-schemas/index.js.gz +0 -0
  91. package/min/persisters/persister-libsql/index.js +1 -1
  92. package/min/persisters/persister-libsql/index.js.gz +0 -0
  93. package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
  94. package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
  95. package/min/persisters/persister-partykit-client/index.js +1 -1
  96. package/min/persisters/persister-partykit-client/index.js.gz +0 -0
  97. package/min/persisters/persister-partykit-client/with-schemas/index.js +1 -1
  98. package/min/persisters/persister-partykit-client/with-schemas/index.js.gz +0 -0
  99. package/min/persisters/persister-partykit-server/index.js +1 -1
  100. package/min/persisters/persister-partykit-server/index.js.gz +0 -0
  101. package/min/persisters/persister-partykit-server/with-schemas/index.js +1 -1
  102. package/min/persisters/persister-partykit-server/with-schemas/index.js.gz +0 -0
  103. package/min/persisters/persister-pglite/index.js +1 -1
  104. package/min/persisters/persister-pglite/index.js.gz +0 -0
  105. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  106. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  107. package/min/persisters/persister-postgres/index.js +1 -1
  108. package/min/persisters/persister-postgres/index.js.gz +0 -0
  109. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  110. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  111. package/min/persisters/persister-powersync/index.js +1 -1
  112. package/min/persisters/persister-powersync/index.js.gz +0 -0
  113. package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
  114. package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
  115. package/min/persisters/persister-react-native-mmkv/index.js +1 -1
  116. package/min/persisters/persister-react-native-mmkv/index.js.gz +0 -0
  117. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js +1 -1
  118. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js.gz +0 -0
  119. package/min/persisters/persister-react-native-sqlite/index.js +1 -1
  120. package/min/persisters/persister-react-native-sqlite/index.js.gz +0 -0
  121. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js +1 -1
  122. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js.gz +0 -0
  123. package/min/persisters/persister-remote/index.js +1 -1
  124. package/min/persisters/persister-remote/index.js.gz +0 -0
  125. package/min/persisters/persister-remote/with-schemas/index.js +1 -1
  126. package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
  127. package/min/persisters/persister-sqlite-bun/index.js +1 -1
  128. package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
  129. package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
  130. package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
  131. package/min/persisters/persister-sqlite-wasm/index.js +1 -1
  132. package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
  133. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
  134. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
  135. package/min/persisters/persister-sqlite3/index.js +1 -1
  136. package/min/persisters/persister-sqlite3/index.js.gz +0 -0
  137. package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
  138. package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
  139. package/min/persisters/persister-yjs/index.js +1 -1
  140. package/min/persisters/persister-yjs/index.js.gz +0 -0
  141. package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
  142. package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
  143. package/min/persisters/with-schemas/index.js +1 -1
  144. package/min/persisters/with-schemas/index.js.gz +0 -0
  145. package/min/queries/index.js +1 -1
  146. package/min/queries/index.js.gz +0 -0
  147. package/min/queries/with-schemas/index.js +1 -1
  148. package/min/queries/with-schemas/index.js.gz +0 -0
  149. package/min/relationships/index.js +1 -1
  150. package/min/relationships/index.js.gz +0 -0
  151. package/min/relationships/with-schemas/index.js +1 -1
  152. package/min/relationships/with-schemas/index.js.gz +0 -0
  153. package/min/store/index.js +1 -1
  154. package/min/store/index.js.gz +0 -0
  155. package/min/store/with-schemas/index.js +1 -1
  156. package/min/store/with-schemas/index.js.gz +0 -0
  157. package/min/synchronizers/index.js +1 -1
  158. package/min/synchronizers/index.js.gz +0 -0
  159. package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
  160. package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
  161. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
  162. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
  163. package/min/synchronizers/synchronizer-local/index.js +1 -1
  164. package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
  165. package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
  166. package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
  167. package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
  168. package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
  169. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
  170. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
  171. package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
  172. package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
  173. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
  174. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
  175. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
  176. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
  177. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
  178. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
  179. package/min/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
  180. package/min/synchronizers/synchronizer-ws-server-simple/index.js.gz +0 -0
  181. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
  182. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js.gz +0 -0
  183. package/min/synchronizers/with-schemas/index.js +1 -1
  184. package/min/synchronizers/with-schemas/index.js.gz +0 -0
  185. package/min/ui-react-inspector/index.js +1 -1
  186. package/min/ui-react-inspector/index.js.gz +0 -0
  187. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  188. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  189. package/min/with-schemas/index.js +1 -1
  190. package/min/with-schemas/index.js.gz +0 -0
  191. package/omni/index.js +667 -232
  192. package/omni/with-schemas/index.js +667 -232
  193. package/package.json +55 -19
  194. package/persisters/index.js +29 -12
  195. package/persisters/persister-automerge/index.js +17 -9
  196. package/persisters/persister-automerge/with-schemas/index.js +17 -9
  197. package/persisters/persister-browser/index.js +34 -10
  198. package/persisters/persister-browser/with-schemas/index.js +34 -10
  199. package/persisters/persister-cr-sqlite-wasm/index.js +29 -12
  200. package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +29 -12
  201. package/persisters/persister-durable-object-sql-storage/index.js +29 -12
  202. package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +29 -12
  203. package/persisters/persister-durable-object-storage/index.js +24 -17
  204. package/persisters/persister-durable-object-storage/with-schemas/index.js +24 -17
  205. package/persisters/persister-electric-sql/index.js +29 -12
  206. package/persisters/persister-electric-sql/with-schemas/index.js +29 -12
  207. package/persisters/persister-expo-sqlite/index.js +29 -12
  208. package/persisters/persister-expo-sqlite/with-schemas/index.js +29 -12
  209. package/persisters/persister-file/index.js +34 -10
  210. package/persisters/persister-file/with-schemas/index.js +34 -10
  211. package/persisters/persister-indexed-db/index.js +17 -9
  212. package/persisters/persister-indexed-db/with-schemas/index.js +17 -9
  213. package/persisters/persister-libsql/index.js +29 -12
  214. package/persisters/persister-libsql/with-schemas/index.js +29 -12
  215. package/persisters/persister-partykit-client/index.js +44 -11
  216. package/persisters/persister-partykit-client/with-schemas/index.js +44 -11
  217. package/persisters/persister-partykit-server/index.js +39 -4
  218. package/persisters/persister-partykit-server/with-schemas/index.js +39 -4
  219. package/persisters/persister-pglite/index.js +29 -12
  220. package/persisters/persister-pglite/with-schemas/index.js +29 -12
  221. package/persisters/persister-postgres/index.js +29 -12
  222. package/persisters/persister-postgres/with-schemas/index.js +29 -12
  223. package/persisters/persister-powersync/index.js +29 -12
  224. package/persisters/persister-powersync/with-schemas/index.js +29 -12
  225. package/persisters/persister-react-native-mmkv/index.js +17 -9
  226. package/persisters/persister-react-native-mmkv/with-schemas/index.js +17 -9
  227. package/persisters/persister-react-native-sqlite/index.js +29 -12
  228. package/persisters/persister-react-native-sqlite/with-schemas/index.js +29 -12
  229. package/persisters/persister-remote/index.js +17 -9
  230. package/persisters/persister-remote/with-schemas/index.js +17 -9
  231. package/persisters/persister-sqlite-bun/index.js +29 -12
  232. package/persisters/persister-sqlite-bun/with-schemas/index.js +29 -12
  233. package/persisters/persister-sqlite-wasm/index.js +29 -12
  234. package/persisters/persister-sqlite-wasm/with-schemas/index.js +29 -12
  235. package/persisters/persister-sqlite3/index.js +29 -12
  236. package/persisters/persister-sqlite3/with-schemas/index.js +29 -12
  237. package/persisters/persister-yjs/index.js +19 -11
  238. package/persisters/persister-yjs/with-schemas/index.js +19 -11
  239. package/persisters/with-schemas/index.js +29 -12
  240. package/queries/index.js +16 -20
  241. package/queries/with-schemas/index.js +16 -20
  242. package/readme.md +21 -13
  243. package/relationships/index.js +13 -12
  244. package/relationships/with-schemas/index.js +13 -12
  245. package/releases.md +59 -43
  246. package/store/index.js +479 -192
  247. package/store/with-schemas/index.js +479 -192
  248. package/synchronizers/index.js +17 -9
  249. package/synchronizers/synchronizer-broadcast-channel/index.js +17 -9
  250. package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +17 -9
  251. package/synchronizers/synchronizer-local/index.js +19 -11
  252. package/synchronizers/synchronizer-local/with-schemas/index.js +19 -11
  253. package/synchronizers/synchronizer-ws-client/index.js +31 -10
  254. package/synchronizers/synchronizer-ws-client/with-schemas/index.js +31 -10
  255. package/synchronizers/synchronizer-ws-server/index.js +34 -13
  256. package/synchronizers/synchronizer-ws-server/with-schemas/index.js +34 -13
  257. package/synchronizers/synchronizer-ws-server-durable-object/index.js +31 -10
  258. package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +31 -10
  259. package/synchronizers/synchronizer-ws-server-simple/index.js +11 -10
  260. package/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +11 -10
  261. package/synchronizers/with-schemas/index.js +17 -9
  262. package/ui-react-inspector/index.js +475 -193
  263. package/ui-react-inspector/with-schemas/index.js +475 -193
  264. package/with-schemas/index.js +632 -215
@@ -0,0 +1,1495 @@
1
+ /**
2
+ * The middleware module of the TinyBase project provides the ability to
3
+ * intercept and validate incoming writes to Store objects.
4
+ *
5
+ * The main entry point to this module is the createMiddleware function, which
6
+ * returns a new Middleware object. From there, you can register hooks that are
7
+ * called before data is written to the Store.
8
+ * @packageDocumentation
9
+ * @module middleware
10
+ * @since v8.0.0
11
+ */
12
+ import type {
13
+ CellIdFromSchema,
14
+ TableIdFromSchema,
15
+ ValueIdFromSchema,
16
+ } from '../../_internal/store/with-schemas/index.d.ts';
17
+ import type {Id} from '../../common/with-schemas/index.d.ts';
18
+ import type {
19
+ Cell,
20
+ Changes,
21
+ Content,
22
+ OptionalSchemas,
23
+ OptionalTablesSchema,
24
+ OptionalValuesSchema,
25
+ Row,
26
+ Store,
27
+ Table,
28
+ Tables,
29
+ Value,
30
+ Values,
31
+ } from '../../store/with-schemas/index.d.ts';
32
+
33
+ /**
34
+ * The WillSetContentCallback type describes a function that is called before
35
+ * Content is set in the Store.
36
+ *
37
+ * This has schema-based typing. The following is a simplified representation:
38
+ *
39
+ * ```ts override
40
+ * (content: Content) => Content | undefined;
41
+ * ```
42
+ *
43
+ * The callback receives the Content (a [Tables, Values] tuple) that is about to
44
+ * be set. It can return the Content (possibly transformed) to allow the write,
45
+ * or `undefined` to prevent the Content from being set.
46
+ *
47
+ * Multiple WillSetContentCallback functions can be registered and they will be
48
+ * called sequentially, the Content being updated successively. If any callback
49
+ * returns `undefined`, the chain short-circuits and the Content will not be
50
+ * set.
51
+ * @param content The Content about to be set.
52
+ * @returns The Content to use (possibly transformed), or `undefined` to prevent
53
+ * the write.
54
+ * @category Callback
55
+ * @since v8.0.0
56
+ */
57
+ export type WillSetContentCallback<Schemas extends OptionalSchemas> = (
58
+ content: Content<Schemas>,
59
+ ) => Content<Schemas> | undefined;
60
+
61
+ /**
62
+ * The WillSetTablesCallback type describes a function that is called before
63
+ * Tables are set in the Store.
64
+ *
65
+ * This has schema-based typing. The following is a simplified representation:
66
+ *
67
+ * ```ts override
68
+ * (tables: Tables) => Tables | undefined;
69
+ * ```
70
+ *
71
+ * The callback receives the Tables object that is about to be set. It can
72
+ * return the Tables (possibly transformed) to allow the write, or `undefined`
73
+ * to prevent the Tables from being set.
74
+ *
75
+ * Multiple WillSetTablesCallback functions can be registered and they will be
76
+ * called sequentially, the Tables being updated successively. If any callback
77
+ * returns `undefined`, the chain short-circuits and the Tables will not be set.
78
+ * @param tables The Tables object about to be set.
79
+ * @returns The Tables to use (possibly transformed), or `undefined` to prevent
80
+ * the write.
81
+ * @category Callback
82
+ * @since v8.0.0
83
+ */
84
+ export type WillSetTablesCallback<Schema extends OptionalTablesSchema> = (
85
+ tables: Tables<Schema>,
86
+ ) => Tables<Schema> | undefined;
87
+
88
+ /**
89
+ * The WillSetTableCallback type describes a function that is called before a
90
+ * Table is set in the Store.
91
+ *
92
+ * This has schema-based typing. The following is a simplified representation:
93
+ *
94
+ * ```ts override
95
+ * (
96
+ * tableId: Id,
97
+ * table: Table,
98
+ * ) => Table | undefined;
99
+ * ```
100
+ *
101
+ * The callback receives the table Id and the Table object that is about to be
102
+ * set. It can return the Table (possibly transformed) to allow the write, or
103
+ * `undefined` to prevent the Table from being set.
104
+ *
105
+ * Multiple WillSetTableCallback functions can be registered and they will be
106
+ * called sequentially, the Table being updated successively. If any callback
107
+ * returns `undefined`, the chain short-circuits and the Table will not be set.
108
+ * @param tableId The Id of the Table being set.
109
+ * @param table The Table object about to be set.
110
+ * @returns The Table to use (possibly transformed), or `undefined` to prevent
111
+ * the write.
112
+ * @category Callback
113
+ * @since v8.0.0
114
+ */
115
+ export type WillSetTableCallback<
116
+ Schema extends OptionalTablesSchema,
117
+ Params extends any[] = TableIdFromSchema<Schema> extends infer TableId
118
+ ? TableId extends TableIdFromSchema<Schema>
119
+ ? [tableId: TableId, table: Table<Schema, TableId>]
120
+ : never
121
+ : never,
122
+ > = (
123
+ ...params: Params | [tableId: never, table: never]
124
+ ) => Params[1] | undefined;
125
+
126
+ /**
127
+ * The WillSetRowCallback type describes a function that is called before a Row
128
+ * is set in the Store.
129
+ *
130
+ * This has schema-based typing. The following is a simplified representation:
131
+ *
132
+ * ```ts override
133
+ * (
134
+ * tableId: Id,
135
+ * rowId: Id,
136
+ * row: Row,
137
+ * ) => Row | undefined;
138
+ * ```
139
+ *
140
+ * The callback receives the table Id, row Id, and the Row object that is about
141
+ * to be set. It can return the Row (possibly transformed) to allow the write,
142
+ * or `undefined` to prevent the Row from being set.
143
+ *
144
+ * Multiple WillSetRowCallback functions can be registered and they will be
145
+ * called sequentially, the Row being updated successively. If any callback
146
+ * returns `undefined`, the chain short-circuits and the Row will not be set.
147
+ * @param tableId The Id of the Table being written to.
148
+ * @param rowId The Id of the Row being set.
149
+ * @param row The Row object about to be set.
150
+ * @returns The Row to use (possibly transformed), or `undefined` to prevent the
151
+ * write.
152
+ * @category Callback
153
+ * @since v8.0.0
154
+ */
155
+ export type WillSetRowCallback<
156
+ Schema extends OptionalTablesSchema,
157
+ Params extends any[] = TableIdFromSchema<Schema> extends infer TableId
158
+ ? TableId extends TableIdFromSchema<Schema>
159
+ ? [tableId: TableId, rowId: Id, row: Row<Schema, TableId>]
160
+ : never
161
+ : never,
162
+ > = (
163
+ ...params: Params | [tableId: never, rowId: never, row: never]
164
+ ) => Params[2] | undefined;
165
+
166
+ /**
167
+ * The WillSetCellCallback type describes a function that is called before a
168
+ * Cell is set in the Store.
169
+ *
170
+ * This has schema-based typing. The following is a simplified representation:
171
+ *
172
+ * ```ts override
173
+ * (
174
+ * tableId: Id,
175
+ * rowId: Id,
176
+ * cellId: Id,
177
+ * cell: Cell,
178
+ * ) => CellOrUndefined;
179
+ * ```
180
+ *
181
+ * The callback receives the table Id, row Id, cell Id, and the Cell value that
182
+ * is about to be set. It can return the Cell value (possibly transformed) to
183
+ * allow the write, or `undefined` to prevent the Cell from being set.
184
+ *
185
+ * Multiple WillSetCellCallback functions can be registered and they will be
186
+ * called sequentially, the Cell value being updated successively. If any
187
+ * callback returns `undefined`, the chain short-circuits and the Cell will not
188
+ * be set.
189
+ * @param tableId The Id of the Table being written to.
190
+ * @param rowId The Id of the Row being written to.
191
+ * @param cellId The Id of the Cell being set.
192
+ * @param cell The Cell value about to be set.
193
+ * @returns The Cell value to use (possibly transformed), or `undefined` to
194
+ * prevent the write.
195
+ * @category Callback
196
+ * @since v8.0.0
197
+ */
198
+ export type WillSetCellCallback<
199
+ Schema extends OptionalTablesSchema,
200
+ Params extends any[] = TableIdFromSchema<Schema> extends infer TableId
201
+ ? TableId extends TableIdFromSchema<Schema>
202
+ ? CellIdFromSchema<Schema, TableId> extends infer CellId
203
+ ? CellId extends CellIdFromSchema<Schema, TableId>
204
+ ? [
205
+ tableId: TableId,
206
+ rowId: Id,
207
+ cellId: CellId,
208
+ cell: Cell<Schema, TableId, CellId>,
209
+ ]
210
+ : never
211
+ : never
212
+ : never
213
+ : never,
214
+ > = (
215
+ ...params: Params | [tableId: never, rowId: never, cellId: never, cell: never]
216
+ ) => Params[3] | undefined;
217
+
218
+ /**
219
+ * The WillSetValuesCallback type describes a function that is called before
220
+ * Values are set in the Store.
221
+ *
222
+ * This has schema-based typing. The following is a simplified representation:
223
+ *
224
+ * ```ts override
225
+ * (values: Values) => Values | undefined;
226
+ * ```
227
+ *
228
+ * The callback receives the Values object that is about to be set. It can
229
+ * return the Values (possibly transformed) to allow the write, or `undefined`
230
+ * to prevent the Values from being set.
231
+ *
232
+ * Multiple WillSetValuesCallback functions can be registered and they will be
233
+ * called sequentially, the Values being updated successively. If any callback
234
+ * returns `undefined`, the chain short-circuits and the Values will not be set.
235
+ * @param values The Values object about to be set.
236
+ * @returns The Values to use (possibly transformed), or `undefined` to prevent
237
+ * the write.
238
+ * @category Callback
239
+ * @since v8.0.0
240
+ */
241
+ export type WillSetValuesCallback<Schema extends OptionalValuesSchema> = (
242
+ values: Values<Schema>,
243
+ ) => Values<Schema> | undefined;
244
+
245
+ /**
246
+ * The WillSetValueCallback type describes a function that is called before a
247
+ * Value is set in the Store.
248
+ *
249
+ * This has schema-based typing. The following is a simplified representation:
250
+ *
251
+ * ```ts override
252
+ * (
253
+ * valueId: Id,
254
+ * value: Value,
255
+ * ) => ValueOrUndefined;
256
+ * ```
257
+ *
258
+ * The callback receives the value Id and the Value that is about to be set. It
259
+ * can return the Value (possibly transformed) to allow the write, or
260
+ * `undefined` to prevent the Value from being set.
261
+ *
262
+ * Multiple WillSetValueCallback functions can be registered and they will be
263
+ * called sequentially, the Value being updated successively. If any callback
264
+ * returns `undefined`, the chain short-circuits and the Value will not be set.
265
+ * @param valueId The Id of the Value being set.
266
+ * @param value The Value about to be set.
267
+ * @returns The Value to use (possibly transformed), or `undefined` to prevent
268
+ * the write.
269
+ * @category Callback
270
+ * @since v8.0.0
271
+ */
272
+ export type WillSetValueCallback<
273
+ Schema extends OptionalValuesSchema,
274
+ Params extends any[] = ValueIdFromSchema<Schema> extends infer ValueId
275
+ ? ValueId extends ValueIdFromSchema<Schema>
276
+ ? [valueId: ValueId, value: Value<Schema, ValueId>]
277
+ : never
278
+ : never,
279
+ > = (
280
+ ...params: Params | [valueId: never, value: never]
281
+ ) => Params[1] | undefined;
282
+
283
+ /**
284
+ * The WillDelTablesCallback type describes a function that is called before all
285
+ * Tables are deleted from the Store.
286
+ *
287
+ * The callback takes no parameters. It returns `true` to allow the deletion, or
288
+ * `false` to prevent it.
289
+ *
290
+ * Multiple WillDelTablesCallback functions can be registered and they will be
291
+ * called sequentially. If any callback returns `false`, the chain
292
+ * short-circuits and the Tables will not be deleted.
293
+ * @returns `true` to allow the deletion, `false` to prevent it.
294
+ * @category Callback
295
+ * @since v8.0.0
296
+ */
297
+ export type WillDelTablesCallback = () => boolean;
298
+
299
+ /**
300
+ * The WillDelTableCallback type describes a function that is called before a
301
+ * Table is deleted from the Store.
302
+ *
303
+ * This has schema-based typing. The following is a simplified representation:
304
+ *
305
+ * ```ts override
306
+ * (tableId: Id) => boolean;
307
+ * ```
308
+ *
309
+ * The callback receives the table Id of the Table about to be deleted. It
310
+ * returns `true` to allow the deletion, or `false` to prevent it.
311
+ *
312
+ * Multiple WillDelTableCallback functions can be registered and they will be
313
+ * called sequentially. If any callback returns `false`, the chain
314
+ * short-circuits and the Table will not be deleted.
315
+ * @param tableId The Id of the Table being deleted.
316
+ * @returns `true` to allow the deletion, `false` to prevent it.
317
+ * @category Callback
318
+ * @since v8.0.0
319
+ */
320
+ export type WillDelTableCallback<
321
+ Schema extends OptionalTablesSchema,
322
+ Params extends any[] = TableIdFromSchema<Schema> extends infer TableId
323
+ ? TableId extends TableIdFromSchema<Schema>
324
+ ? [tableId: TableId]
325
+ : never
326
+ : never,
327
+ > = (...params: Params | [tableId: never]) => boolean;
328
+
329
+ /**
330
+ * The WillDelRowCallback type describes a function that is called before a Row
331
+ * is deleted from the Store.
332
+ *
333
+ * This has schema-based typing. The following is a simplified representation:
334
+ *
335
+ * ```ts override
336
+ * (tableId: Id, rowId: Id) => boolean;
337
+ * ```
338
+ *
339
+ * The callback receives the table Id and row Id of the Row about to be deleted.
340
+ * It returns `true` to allow the deletion, or `false` to prevent it.
341
+ *
342
+ * Multiple WillDelRowCallback functions can be registered and they will be
343
+ * called sequentially. If any callback returns `false`, the chain
344
+ * short-circuits and the Row will not be deleted.
345
+ * @param tableId The Id of the Table containing the Row.
346
+ * @param rowId The Id of the Row being deleted.
347
+ * @returns `true` to allow the deletion, `false` to prevent it.
348
+ * @category Callback
349
+ * @since v8.0.0
350
+ */
351
+ export type WillDelRowCallback<
352
+ Schema extends OptionalTablesSchema,
353
+ Params extends any[] = TableIdFromSchema<Schema> extends infer TableId
354
+ ? TableId extends TableIdFromSchema<Schema>
355
+ ? [tableId: TableId, rowId: Id]
356
+ : never
357
+ : never,
358
+ > = (...params: Params | [tableId: never, rowId: never]) => boolean;
359
+
360
+ /**
361
+ * The WillDelCellCallback type describes a function that is called before a
362
+ * Cell is deleted from the Store.
363
+ *
364
+ * This has schema-based typing. The following is a simplified representation:
365
+ *
366
+ * ```ts override
367
+ * (
368
+ * tableId: Id,
369
+ * rowId: Id,
370
+ * cellId: Id,
371
+ * ) => boolean;
372
+ * ```
373
+ *
374
+ * The callback receives the table Id, row Id, and cell Id of the Cell about to
375
+ * be deleted. It returns `true` to allow the deletion, or `false` to prevent
376
+ * it.
377
+ *
378
+ * Multiple WillDelCellCallback functions can be registered and they will be
379
+ * called sequentially. If any callback returns `false`, the chain
380
+ * short-circuits and the Cell will not be deleted.
381
+ * @param tableId The Id of the Table containing the Cell.
382
+ * @param rowId The Id of the Row containing the Cell.
383
+ * @param cellId The Id of the Cell being deleted.
384
+ * @returns `true` to allow the deletion, `false` to prevent it.
385
+ * @category Callback
386
+ * @since v8.0.0
387
+ */
388
+ export type WillDelCellCallback<
389
+ Schema extends OptionalTablesSchema,
390
+ Params extends any[] = TableIdFromSchema<Schema> extends infer TableId
391
+ ? TableId extends TableIdFromSchema<Schema>
392
+ ? CellIdFromSchema<Schema, TableId> extends infer CellId
393
+ ? CellId extends CellIdFromSchema<Schema, TableId>
394
+ ? [tableId: TableId, rowId: Id, cellId: CellId]
395
+ : never
396
+ : never
397
+ : never
398
+ : never,
399
+ > = (
400
+ ...params: Params | [tableId: never, rowId: never, cellId: never]
401
+ ) => boolean;
402
+
403
+ /**
404
+ * The WillDelValuesCallback type describes a function that is called before all
405
+ * Values are deleted from the Store.
406
+ *
407
+ * The callback takes no parameters. It returns `true` to allow the deletion, or
408
+ * `false` to prevent it.
409
+ *
410
+ * Multiple WillDelValuesCallback functions can be registered and they will be
411
+ * called sequentially. If any callback returns `false`, the chain
412
+ * short-circuits and the Values will not be deleted.
413
+ * @returns `true` to allow the deletion, `false` to prevent it.
414
+ * @category Callback
415
+ * @since v8.0.0
416
+ */
417
+ export type WillDelValuesCallback = () => boolean;
418
+
419
+ /**
420
+ * The WillDelValueCallback type describes a function that is called before a
421
+ * Value is deleted from the Store.
422
+ *
423
+ * This has schema-based typing. The following is a simplified representation:
424
+ *
425
+ * ```ts override
426
+ * (valueId: Id) => boolean;
427
+ * ```
428
+ *
429
+ * The callback receives the value Id of the Value about to be deleted. It
430
+ * returns `true` to allow the deletion, or `false` to prevent it.
431
+ *
432
+ * Multiple WillDelValueCallback functions can be registered and they will be
433
+ * called sequentially. If any callback returns `false`, the chain
434
+ * short-circuits and the Value will not be deleted.
435
+ * @param valueId The Id of the Value being deleted.
436
+ * @returns `true` to allow the deletion, `false` to prevent it.
437
+ * @category Callback
438
+ * @since v8.0.0
439
+ */
440
+ export type WillDelValueCallback<
441
+ Schema extends OptionalValuesSchema,
442
+ Params extends any[] = ValueIdFromSchema<Schema> extends infer ValueId
443
+ ? ValueId extends ValueIdFromSchema<Schema>
444
+ ? [valueId: ValueId]
445
+ : never
446
+ : never,
447
+ > = (...params: Params | [valueId: never]) => boolean;
448
+
449
+ /**
450
+ * The WillApplyChangesCallback type describes a function that is called before
451
+ * Changes are applied to the Store.
452
+ *
453
+ * This has schema-based typing. The following is a simplified representation:
454
+ *
455
+ * ```ts override
456
+ * (
457
+ * changes: Changes,
458
+ * ) => Changes | undefined;
459
+ * ```
460
+ *
461
+ * The callback receives the Changes object that is about to be applied. It can
462
+ * return the Changes (possibly transformed) to allow the write, or `undefined`
463
+ * to prevent the Changes from being applied.
464
+ *
465
+ * Multiple WillApplyChangesCallback functions can be registered and they will
466
+ * be called sequentially, the Changes being updated successively. If any
467
+ * callback returns `undefined`, the chain short-circuits and the Changes will
468
+ * not be applied.
469
+ * @param changes The Changes about to be applied.
470
+ * @returns The Changes to use (possibly transformed), or `undefined` to prevent
471
+ * the write.
472
+ * @category Callback
473
+ * @since v8.0.0
474
+ */
475
+ export type WillApplyChangesCallback<Schemas extends OptionalSchemas> = (
476
+ changes: Changes<Schemas>,
477
+ ) => Changes<Schemas> | undefined;
478
+
479
+ /**
480
+ * The DidSetRowCallback type describes a function called after a Row is changed
481
+ * during a transaction, and after mutator listeners have fired.
482
+ *
483
+ * This has schema-based typing. The following is a simplified representation:
484
+ *
485
+ * ```ts override
486
+ * (
487
+ * tableId: Id,
488
+ * rowId: Id,
489
+ * oldRow: Row,
490
+ * newRow: Row,
491
+ * ) => Row;
492
+ * ```
493
+ *
494
+ * Unlike the `willSet*` callbacks, which intercept writes as they happen,
495
+ * `didSetRow` fires once per touched Row after all cell writes in the
496
+ * transaction have completed. This means multiple cell changes to the same Row
497
+ * within a single transaction result in just one `didSetRow` call, with the
498
+ * full before-transaction and after-transaction Row states.
499
+ *
500
+ * The callback receives the Table Id, Row Id, the Row as it was at the start of
501
+ * the transaction (`oldRow`), and the Row as it is now (`newRow`). It must
502
+ * return a Row:
503
+ *
504
+ * - `newRow` to accept the changes.
505
+ * - a different `Row` to replace the final state.
506
+ * - `oldRow` to revert all changes to the Row.
507
+ * - an empty object to delete the Row.
508
+ *
509
+ * Multiple DidSetRowCallback functions can be registered for the same table and
510
+ * they will be called sequentially, each receiving the Row returned by the
511
+ * previous callback. The chain never short-circuits: all registered callbacks
512
+ * always run.
513
+ *
514
+ * Note that `addDidSetRowCallback` is table-scoped: you must specify the table
515
+ * Id when registering. Callbacks are only invoked for rows in the specified
516
+ * table, keeping overhead to zero for other tables.
517
+ * @param tableId The Id of the Table containing the changed Row.
518
+ * @param rowId The Id of the Row that was changed.
519
+ * @param oldRow The Row as it was at the start of the transaction.
520
+ * @param newRow The Row as it is now, after all cell writes including those
521
+ * made by mutating listeners.
522
+ * @returns The Row to use as the final state.
523
+ * @category Callback
524
+ * @since v8.0.0
525
+ */
526
+ export type DidSetRowCallback<
527
+ Schema extends OptionalTablesSchema,
528
+ TableId extends TableIdFromSchema<Schema>,
529
+ > = (
530
+ tableId: TableId,
531
+ rowId: Id,
532
+ oldRow: Row<Schema, TableId>,
533
+ newRow: Row<Schema, TableId>,
534
+ ) => Row<Schema, TableId>;
535
+
536
+ /**
537
+ * A Middleware object lets you intercept and validate writes to a Store.
538
+ *
539
+ * This is useful for enforcing business rules, data validation, or
540
+ * transformation logic before data is persisted in the Store.
541
+ *
542
+ * Create a Middleware object easily with the createMiddleware function.
543
+ * @example
544
+ * This example shows a very simple lifecycle of a Middleware object: from
545
+ * creation, to getting the Store reference, and then destroying it.
546
+ *
547
+ * ```js
548
+ * import {createMiddleware, createStore} from 'tinybase';
549
+ *
550
+ * const store = createStore();
551
+ * const middleware = createMiddleware(store);
552
+ *
553
+ * console.log(middleware.getStore() == store);
554
+ * // -> true
555
+ *
556
+ * middleware.destroy();
557
+ * ```
558
+ * @category Middleware
559
+ * @since v8.0.0
560
+ */
561
+ export interface Middleware<in out Schemas extends OptionalSchemas> {
562
+ /**
563
+ * The getStore method returns a reference to the underlying Store that is
564
+ * backing this Middleware object.
565
+ * @returns A reference to the Store.
566
+ * @example
567
+ * This example creates a Middleware object against a newly-created Store and
568
+ * then gets its reference in order to update its data.
569
+ *
570
+ * This has schema-based typing. The following is a simplified representation:
571
+ *
572
+ * ```ts override
573
+ * getStore(): Store;
574
+ * ```
575
+ *
576
+ * ```js
577
+ * import {createMiddleware, createStore} from 'tinybase';
578
+ *
579
+ * const middleware = createMiddleware(createStore());
580
+ * console.log(middleware.getStore().getTables());
581
+ * // -> {}
582
+ * middleware.destroy();
583
+ * ```
584
+ * @category Getter
585
+ * @since v8.0.0
586
+ */
587
+ getStore(): Store<Schemas>;
588
+
589
+ /**
590
+ * The addWillSetContentCallback method registers a WillSetContentCallback
591
+ * that will be called before Content is set in the Store.
592
+ *
593
+ * This has schema-based typing. The following is a simplified representation:
594
+ *
595
+ * ```ts override
596
+ * addWillSetContentCallback(callback: WillSetContentCallback): Middleware;
597
+ * ```
598
+ *
599
+ * The callback can transform the Content or return `undefined` to prevent the
600
+ * write. Multiple callbacks can be registered and they are called
601
+ * sequentially, each receiving the (possibly transformed) Content from the
602
+ * previous callback.
603
+ * @param callback The WillSetContentCallback to register.
604
+ * @returns A reference to the Middleware object, for chaining.
605
+ * @example
606
+ * This example registers a callback that prevents setting Content with
607
+ * empty Tables in the pet store.
608
+ *
609
+ * ```js
610
+ * import {createMiddleware, createStore} from 'tinybase';
611
+ *
612
+ * const store = createStore();
613
+ * const middleware = createMiddleware(store);
614
+ *
615
+ * middleware.addWillSetContentCallback(([tables, values]) =>
616
+ * Object.keys(tables).length > 0 ? [tables, values] : undefined,
617
+ * );
618
+ *
619
+ * store.setContent([{}, {open: true}]);
620
+ * console.log(store.getContent());
621
+ * // -> [{}, {}]
622
+ *
623
+ * store.setContent([{pets: {fido: {species: 'dog'}}}, {}]);
624
+ * console.log(store.getContent());
625
+ * // -> [{pets: {fido: {species: 'dog'}}}, {}]
626
+ *
627
+ * middleware.destroy();
628
+ * ```
629
+ * @category Configuration
630
+ * @since v8.0.0
631
+ */
632
+ addWillSetContentCallback(
633
+ callback: WillSetContentCallback<Schemas>,
634
+ ): Middleware<Schemas>;
635
+
636
+ /**
637
+ * The addWillSetTablesCallback method registers a WillSetTablesCallback that
638
+ * will be called before Tables are set in the Store.
639
+ *
640
+ * This has schema-based typing. The following is a simplified representation:
641
+ *
642
+ * ```ts override
643
+ * addWillSetTablesCallback(callback: WillSetTablesCallback): Middleware;
644
+ * ```
645
+ *
646
+ * The callback can transform the Tables or return `undefined` to prevent the
647
+ * write. Multiple callbacks can be registered and they are called
648
+ * sequentially, each receiving the (possibly transformed) tables from the
649
+ * previous callback.
650
+ * @param callback The WillSetTablesCallback to register.
651
+ * @returns A reference to the Middleware object, for chaining.
652
+ * @example
653
+ * This example registers a callback that upper-cases all string Cell values
654
+ * when entire Tables are set in the pet store.
655
+ *
656
+ * ```js
657
+ * import {createMiddleware, createStore} from 'tinybase';
658
+ *
659
+ * const store = createStore();
660
+ * const middleware = createMiddleware(store);
661
+ *
662
+ * middleware.addWillSetTablesCallback((tables) =>
663
+ * Object.fromEntries(
664
+ * Object.entries(tables).map(([tableId, table]) => [
665
+ * tableId,
666
+ * Object.fromEntries(
667
+ * Object.entries(table).map(([rowId, row]) => [
668
+ * rowId,
669
+ * Object.fromEntries(
670
+ * Object.entries(row).map(([k, v]) => [
671
+ * k,
672
+ * typeof v === 'string' ? v.toUpperCase() : v,
673
+ * ]),
674
+ * ),
675
+ * ]),
676
+ * ),
677
+ * ]),
678
+ * ),
679
+ * );
680
+ *
681
+ * store.setTables({pets: {fido: {species: 'dog'}, felix: {species: 'cat'}}});
682
+ * console.log(store.getTables());
683
+ * // -> {pets: {fido: {species: 'DOG'}, felix: {species: 'CAT'}}}
684
+ *
685
+ * middleware.destroy();
686
+ * ```
687
+ * @example
688
+ * This example registers a callback that prevents setting any Tables that
689
+ * include a 'banned' table.
690
+ *
691
+ * ```js
692
+ * import {createMiddleware, createStore} from 'tinybase';
693
+ *
694
+ * const store = createStore();
695
+ * const middleware = createMiddleware(store);
696
+ *
697
+ * middleware.addWillSetTablesCallback((tables) =>
698
+ * 'banned' in tables ? undefined : tables,
699
+ * );
700
+ *
701
+ * store.setTables({banned: {r1: {c1: 1}}, pets: {fido: {species: 'dog'}}});
702
+ * console.log(store.getTables());
703
+ * // -> {}
704
+ *
705
+ * middleware.destroy();
706
+ * ```
707
+ * @category Configuration
708
+ * @since v8.0.0
709
+ */
710
+ addWillSetTablesCallback(
711
+ callback: WillSetTablesCallback<Schemas[0]>,
712
+ ): Middleware<Schemas>;
713
+
714
+ /**
715
+ * The addWillSetTableCallback method registers a WillSetTableCallback that
716
+ * will be called before any Table is set in the Store.
717
+ *
718
+ * This has schema-based typing. The following is a simplified representation:
719
+ *
720
+ * ```ts override
721
+ * addWillSetTableCallback(callback: WillSetTableCallback): Middleware;
722
+ * ```
723
+ *
724
+ * The callback can transform the Table or return `undefined` to prevent the
725
+ * write. Multiple callbacks can be registered and they are called
726
+ * sequentially, each receiving the (possibly transformed) table from the
727
+ * previous callback.
728
+ * @param callback The WillSetTableCallback to register.
729
+ * @returns A reference to the Middleware object, for chaining.
730
+ * @example
731
+ * This example registers a callback that upper-cases string Cell values in
732
+ * rows set to the 'pets' table.
733
+ *
734
+ * ```js
735
+ * import {createMiddleware, createStore} from 'tinybase';
736
+ *
737
+ * const store = createStore();
738
+ * const middleware = createMiddleware(store);
739
+ *
740
+ * middleware.addWillSetTableCallback((tableId, table) =>
741
+ * tableId === 'pets'
742
+ * ? Object.fromEntries(
743
+ * Object.entries(table).map(([rowId, row]) => [
744
+ * rowId,
745
+ * Object.fromEntries(
746
+ * Object.entries(row).map(([k, v]) => [
747
+ * k,
748
+ * typeof v === 'string' ? v.toUpperCase() : v,
749
+ * ]),
750
+ * ),
751
+ * ]),
752
+ * )
753
+ * : table,
754
+ * );
755
+ *
756
+ * store.setTable('pets', {fido: {species: 'dog'}, felix: {species: 'cat'}});
757
+ * console.log(store.getTable('pets'));
758
+ * // -> {fido: {species: 'DOG'}, felix: {species: 'CAT'}}
759
+ *
760
+ * middleware.destroy();
761
+ * ```
762
+ * @example
763
+ * This example registers a callback that prevents writes to the 'species'
764
+ * table.
765
+ *
766
+ * ```js
767
+ * import {createMiddleware, createStore} from 'tinybase';
768
+ *
769
+ * const store = createStore();
770
+ * const middleware = createMiddleware(store);
771
+ *
772
+ * middleware.addWillSetTableCallback((tableId, table) =>
773
+ * tableId === 'species' ? undefined : table,
774
+ * );
775
+ *
776
+ * store.setTable('species', {dog: {legs: 4, sound: 'woof'}});
777
+ * console.log(store.getTables());
778
+ * // -> {}
779
+ *
780
+ * middleware.destroy();
781
+ * ```
782
+ * @category Configuration
783
+ * @since v8.0.0
784
+ */
785
+ addWillSetTableCallback(
786
+ callback: WillSetTableCallback<Schemas[0]>,
787
+ ): Middleware<Schemas>;
788
+
789
+ /**
790
+ * The addWillSetRowCallback method registers a WillSetRowCallback that will
791
+ * be called before any Row is set in the Store.
792
+ *
793
+ * This has schema-based typing. The following is a simplified representation:
794
+ *
795
+ * ```ts override
796
+ * addWillSetRowCallback(callback: WillSetRowCallback): Middleware;
797
+ * ```
798
+ *
799
+ * The callback can transform the Row or return `undefined` to prevent the
800
+ * write. Multiple callbacks can be registered and they are called
801
+ * sequentially, each receiving the (possibly transformed) row from the
802
+ * previous callback.
803
+ * @param callback The WillSetRowCallback to register.
804
+ * @returns A reference to the Middleware object, for chaining.
805
+ * @example
806
+ * This example registers a callback that upper-cases string Cell values in
807
+ * rows set to the 'pets' table.
808
+ *
809
+ * ```js
810
+ * import {createMiddleware, createStore} from 'tinybase';
811
+ *
812
+ * const store = createStore();
813
+ * const middleware = createMiddleware(store);
814
+ *
815
+ * middleware.addWillSetRowCallback((tableId, _rowId, row) =>
816
+ * tableId === 'pets'
817
+ * ? Object.fromEntries(
818
+ * Object.entries(row).map(([k, v]) => [
819
+ * k,
820
+ * typeof v === 'string' ? v.toUpperCase() : v,
821
+ * ]),
822
+ * )
823
+ * : row,
824
+ * );
825
+ *
826
+ * store.setRow('pets', 'fido', {species: 'dog', legs: 4});
827
+ * console.log(store.getRow('pets', 'fido'));
828
+ * // -> {species: 'DOG', legs: 4}
829
+ *
830
+ * middleware.destroy();
831
+ * ```
832
+ * @example
833
+ * This example registers a callback that prevents writes to the 'species'
834
+ * table.
835
+ *
836
+ * ```js
837
+ * import {createMiddleware, createStore} from 'tinybase';
838
+ *
839
+ * const store = createStore();
840
+ * const middleware = createMiddleware(store);
841
+ *
842
+ * middleware.addWillSetRowCallback((tableId, _rowId, row) =>
843
+ * tableId === 'species' ? undefined : row,
844
+ * );
845
+ *
846
+ * store.setRow('species', 'dog', {legs: 4, sound: 'woof'});
847
+ * console.log(store.getTables());
848
+ * // -> {}
849
+ *
850
+ * middleware.destroy();
851
+ * ```
852
+ * @category Configuration
853
+ * @since v8.0.0
854
+ */
855
+ addWillSetRowCallback(
856
+ callback: WillSetRowCallback<Schemas[0]>,
857
+ ): Middleware<Schemas>;
858
+
859
+ /**
860
+ * The addWillSetCellCallback method registers a WillSetCellCallback that will
861
+ * be called before any Cell is set in the Store.
862
+ *
863
+ * This has schema-based typing. The following is a simplified representation:
864
+ *
865
+ * ```ts override
866
+ * addWillSetCellCallback(callback: WillSetCellCallback): Middleware;
867
+ * ```
868
+ *
869
+ * The callback can transform the Cell value or return `undefined` to prevent
870
+ * the write. Multiple callbacks can be registered and they are called
871
+ * sequentially, each receiving the (possibly transformed) value from the
872
+ * previous callback.
873
+ * @param callback The WillSetCellCallback to register.
874
+ * @returns A reference to the Middleware object, for chaining.
875
+ * @example
876
+ * This example registers a callback that upper-cases string Cell values in
877
+ * the 'pets' table.
878
+ *
879
+ * ```js
880
+ * import {createMiddleware, createStore} from 'tinybase';
881
+ *
882
+ * const store = createStore();
883
+ * const middleware = createMiddleware(store);
884
+ *
885
+ * middleware.addWillSetCellCallback((tableId, rowId, cellId, cell) =>
886
+ * tableId === 'pets' && typeof cell === 'string'
887
+ * ? cell.toUpperCase()
888
+ * : cell,
889
+ * );
890
+ *
891
+ * store.setCell('pets', 'fido', 'species', 'dog');
892
+ * console.log(store.getCell('pets', 'fido', 'species'));
893
+ * // -> 'DOG'
894
+ *
895
+ * middleware.destroy();
896
+ * ```
897
+ * @example
898
+ * This example registers a callback that prevents writes to the 'species'
899
+ * table.
900
+ *
901
+ * ```js
902
+ * import {createMiddleware, createStore} from 'tinybase';
903
+ *
904
+ * const store = createStore();
905
+ * const middleware = createMiddleware(store);
906
+ *
907
+ * middleware.addWillSetCellCallback((tableId, _rowId, _cellId, cell) =>
908
+ * tableId === 'species' ? undefined : cell,
909
+ * );
910
+ *
911
+ * store.setCell('species', 'dog', 'legs', 4);
912
+ * console.log(store.getTables());
913
+ * // -> {}
914
+ *
915
+ * middleware.destroy();
916
+ * ```
917
+ * @category Configuration
918
+ * @since v8.0.0
919
+ */
920
+ addWillSetCellCallback(
921
+ callback: WillSetCellCallback<Schemas[0]>,
922
+ ): Middleware<Schemas>;
923
+
924
+ /**
925
+ * The addWillSetValuesCallback method registers a WillSetValuesCallback that
926
+ * will be called before Values are set in the Store.
927
+ *
928
+ * This has schema-based typing. The following is a simplified representation:
929
+ *
930
+ * ```ts override
931
+ * addWillSetValuesCallback(callback: WillSetValuesCallback): Middleware;
932
+ * ```
933
+ *
934
+ * The callback can transform the Values or return `undefined` to prevent the
935
+ * write. Multiple callbacks can be registered and they are called
936
+ * sequentially, each receiving the (possibly transformed) values from the
937
+ * previous callback.
938
+ * @param callback The WillSetValuesCallback to register.
939
+ * @returns A reference to the Middleware object, for chaining.
940
+ * @example
941
+ * This example registers a callback that upper-cases all string Values in the
942
+ * pet store's settings.
943
+ *
944
+ * ```js
945
+ * import {createMiddleware, createStore} from 'tinybase';
946
+ *
947
+ * const store = createStore();
948
+ * const middleware = createMiddleware(store);
949
+ *
950
+ * middleware.addWillSetValuesCallback((values) =>
951
+ * Object.fromEntries(
952
+ * Object.entries(values).map(([k, v]) => [
953
+ * k,
954
+ * typeof v === 'string' ? v.toUpperCase() : v,
955
+ * ]),
956
+ * ),
957
+ * );
958
+ *
959
+ * store.setValues({storeName: 'happy pets', limit: 50});
960
+ * console.log(store.getValues());
961
+ * // -> {storeName: 'HAPPY PETS', limit: 50}
962
+ *
963
+ * middleware.destroy();
964
+ * ```
965
+ * @example
966
+ * This example registers a callback that prevents setting Values when the pet
967
+ * store is 'closed'.
968
+ *
969
+ * ```js
970
+ * import {createMiddleware, createStore} from 'tinybase';
971
+ *
972
+ * const store = createStore();
973
+ * const middleware = createMiddleware(store);
974
+ *
975
+ * middleware.addWillSetValuesCallback((values) =>
976
+ * 'closed' in values ? undefined : values,
977
+ * );
978
+ *
979
+ * store.setValues({closed: true, storeName: 'happy pets'});
980
+ * console.log(store.getValues());
981
+ * // -> {}
982
+ *
983
+ * middleware.destroy();
984
+ * ```
985
+ * @category Configuration
986
+ * @since v8.0.0
987
+ */
988
+ addWillSetValuesCallback(
989
+ callback: WillSetValuesCallback<Schemas[1]>,
990
+ ): Middleware<Schemas>;
991
+
992
+ /**
993
+ * The addWillSetValueCallback method registers a WillSetValueCallback that
994
+ * will be called before any Value is set in the Store.
995
+ *
996
+ * This has schema-based typing. The following is a simplified representation:
997
+ *
998
+ * ```ts override
999
+ * addWillSetValueCallback(callback: WillSetValueCallback): Middleware;
1000
+ * ```
1001
+ *
1002
+ * The callback can transform the Value or return `undefined` to prevent the
1003
+ * write. Multiple callbacks can be registered and they are called
1004
+ * sequentially, each receiving the (possibly transformed) value from the
1005
+ * previous callback.
1006
+ * @param callback The WillSetValueCallback to register.
1007
+ * @returns A reference to the Middleware object, for chaining.
1008
+ * @example
1009
+ * This example registers a callback that clamps the 'limit' Value to the
1010
+ * maximum capacity of the pet store.
1011
+ *
1012
+ * ```js
1013
+ * import {createMiddleware, createStore} from 'tinybase';
1014
+ *
1015
+ * const store = createStore();
1016
+ * const middleware = createMiddleware(store);
1017
+ *
1018
+ * middleware.addWillSetValueCallback((valueId, value) =>
1019
+ * valueId === 'limit' && typeof value === 'number'
1020
+ * ? Math.min(50, Math.max(0, value))
1021
+ * : value,
1022
+ * );
1023
+ *
1024
+ * store.setValue('limit', 100);
1025
+ * console.log(store.getValue('limit'));
1026
+ * // -> 50
1027
+ *
1028
+ * middleware.destroy();
1029
+ * ```
1030
+ * @category Configuration
1031
+ * @since v8.0.0
1032
+ */
1033
+ addWillSetValueCallback(
1034
+ callback: WillSetValueCallback<Schemas[1]>,
1035
+ ): Middleware<Schemas>;
1036
+
1037
+ /**
1038
+ * The addWillDelTablesCallback method registers a WillDelTablesCallback that
1039
+ * will be called before all Tables are deleted from the Store.
1040
+ *
1041
+ * This has schema-based typing. The following is a simplified representation:
1042
+ *
1043
+ * ```ts override
1044
+ * addWillDelTablesCallback(callback: WillDelTablesCallback): Middleware;
1045
+ * ```
1046
+ *
1047
+ * The callback returns `true` to allow the deletion or `false` to prevent it.
1048
+ * Multiple callbacks can be registered and they are called sequentially. If
1049
+ * any callback returns `false`, the deletion is prevented.
1050
+ * @param callback The WillDelTablesCallback to register.
1051
+ * @returns A reference to the Middleware object, for chaining.
1052
+ * @example
1053
+ * This example registers a callback that prevents deleting all Tables from
1054
+ * the pet store.
1055
+ *
1056
+ * ```js
1057
+ * import {createMiddleware, createStore} from 'tinybase';
1058
+ *
1059
+ * const store = createStore();
1060
+ * const middleware = createMiddleware(store);
1061
+ *
1062
+ * store.setTables({pets: {fido: {species: 'dog'}, felix: {species: 'cat'}}});
1063
+ *
1064
+ * middleware.addWillDelTablesCallback(() => false);
1065
+ *
1066
+ * store.delTables();
1067
+ * console.log(store.getTables());
1068
+ * // -> {pets: {fido: {species: 'dog'}, felix: {species: 'cat'}}}
1069
+ *
1070
+ * middleware.destroy();
1071
+ * ```
1072
+ * @category Configuration
1073
+ * @since v8.0.0
1074
+ */
1075
+ addWillDelTablesCallback(
1076
+ callback: WillDelTablesCallback,
1077
+ ): Middleware<Schemas>;
1078
+
1079
+ /**
1080
+ * The addWillDelTableCallback method registers a WillDelTableCallback that
1081
+ * will be called before any Table is deleted from the Store.
1082
+ *
1083
+ * This has schema-based typing. The following is a simplified representation:
1084
+ *
1085
+ * ```ts override
1086
+ * addWillDelTableCallback(callback: WillDelTableCallback): Middleware;
1087
+ * ```
1088
+ *
1089
+ * The callback returns `true` to allow the deletion or `false` to prevent it.
1090
+ * Multiple callbacks can be registered and they are called sequentially. If
1091
+ * any callback returns `false`, the deletion is prevented.
1092
+ * @param callback The WillDelTableCallback to register.
1093
+ * @returns A reference to the Middleware object, for chaining.
1094
+ * @example
1095
+ * This example registers a callback that prevents deleting the 'pets' table
1096
+ * from the pet store.
1097
+ *
1098
+ * ```js
1099
+ * import {createMiddleware, createStore} from 'tinybase';
1100
+ *
1101
+ * const store = createStore();
1102
+ * const middleware = createMiddleware(store);
1103
+ *
1104
+ * store.setTable('pets', {fido: {species: 'dog'}, felix: {species: 'cat'}});
1105
+ *
1106
+ * middleware.addWillDelTableCallback((tableId) => tableId !== 'pets');
1107
+ *
1108
+ * store.delTable('pets');
1109
+ * console.log(store.getTable('pets'));
1110
+ * // -> {fido: {species: 'dog'}, felix: {species: 'cat'}}
1111
+ *
1112
+ * middleware.destroy();
1113
+ * ```
1114
+ * @category Configuration
1115
+ * @since v8.0.0
1116
+ */
1117
+ addWillDelTableCallback(
1118
+ callback: WillDelTableCallback<Schemas[0]>,
1119
+ ): Middleware<Schemas>;
1120
+
1121
+ /**
1122
+ * The addWillDelRowCallback method registers a WillDelRowCallback that will
1123
+ * be called before any Row is deleted from the Store.
1124
+ *
1125
+ * This has schema-based typing. The following is a simplified representation:
1126
+ *
1127
+ * ```ts override
1128
+ * addWillDelRowCallback(callback: WillDelRowCallback): Middleware;
1129
+ * ```
1130
+ *
1131
+ * The callback returns `true` to allow the deletion or `false` to prevent it.
1132
+ * Multiple callbacks can be registered and they are called sequentially. If
1133
+ * any callback returns `false`, the deletion is prevented.
1134
+ * @param callback The WillDelRowCallback to register.
1135
+ * @returns A reference to the Middleware object, for chaining.
1136
+ * @example
1137
+ * This example registers a callback that prevents deleting rows from the
1138
+ * 'pets' table.
1139
+ *
1140
+ * ```js
1141
+ * import {createMiddleware, createStore} from 'tinybase';
1142
+ *
1143
+ * const store = createStore();
1144
+ * const middleware = createMiddleware(store);
1145
+ *
1146
+ * store.setRow('pets', 'fido', {species: 'dog', legs: 4});
1147
+ *
1148
+ * middleware.addWillDelRowCallback((tableId) => tableId !== 'pets');
1149
+ *
1150
+ * store.delRow('pets', 'fido');
1151
+ * console.log(store.getRow('pets', 'fido'));
1152
+ * // -> {species: 'dog', legs: 4}
1153
+ *
1154
+ * middleware.destroy();
1155
+ * ```
1156
+ * @category Configuration
1157
+ * @since v8.0.0
1158
+ */
1159
+ addWillDelRowCallback(
1160
+ callback: WillDelRowCallback<Schemas[0]>,
1161
+ ): Middleware<Schemas>;
1162
+
1163
+ /**
1164
+ * The addWillDelCellCallback method registers a WillDelCellCallback that will
1165
+ * be called before any Cell is deleted from the Store.
1166
+ *
1167
+ * This has schema-based typing. The following is a simplified representation:
1168
+ *
1169
+ * ```ts override
1170
+ * addWillDelCellCallback(callback: WillDelCellCallback): Middleware;
1171
+ * ```
1172
+ *
1173
+ * The callback returns `true` to allow the deletion or `false` to prevent it.
1174
+ * Multiple callbacks can be registered and they are called sequentially. If
1175
+ * any callback returns `false`, the deletion is prevented.
1176
+ * @param callback The WillDelCellCallback to register.
1177
+ * @returns A reference to the Middleware object, for chaining.
1178
+ * @example
1179
+ * This example registers a callback that prevents deleting cells from the
1180
+ * 'pets' table.
1181
+ *
1182
+ * ```js
1183
+ * import {createMiddleware, createStore} from 'tinybase';
1184
+ *
1185
+ * const store = createStore();
1186
+ * const middleware = createMiddleware(store);
1187
+ *
1188
+ * store.setCell('pets', 'fido', 'species', 'dog');
1189
+ *
1190
+ * middleware.addWillDelCellCallback((tableId) => tableId !== 'pets');
1191
+ *
1192
+ * store.delCell('pets', 'fido', 'species', true);
1193
+ * console.log(store.getCell('pets', 'fido', 'species'));
1194
+ * // -> 'dog'
1195
+ *
1196
+ * middleware.destroy();
1197
+ * ```
1198
+ * @category Configuration
1199
+ * @since v8.0.0
1200
+ */
1201
+ addWillDelCellCallback(
1202
+ callback: WillDelCellCallback<Schemas[0]>,
1203
+ ): Middleware<Schemas>;
1204
+
1205
+ /**
1206
+ * The addWillDelValuesCallback method registers a WillDelValuesCallback that
1207
+ * will be called before all Values are deleted from the Store.
1208
+ *
1209
+ * This has schema-based typing. The following is a simplified representation:
1210
+ *
1211
+ * ```ts override
1212
+ * addWillDelValuesCallback(callback: WillDelValuesCallback): Middleware;
1213
+ * ```
1214
+ *
1215
+ * The callback returns `true` to allow the deletion or `false` to prevent it.
1216
+ * Multiple callbacks can be registered and they are called sequentially. If
1217
+ * any callback returns `false`, the deletion is prevented.
1218
+ * @param callback The WillDelValuesCallback to register.
1219
+ * @returns A reference to the Middleware object, for chaining.
1220
+ * @example
1221
+ * This example registers a callback that prevents deleting all Values from
1222
+ * the pet store.
1223
+ *
1224
+ * ```js
1225
+ * import {createMiddleware, createStore} from 'tinybase';
1226
+ *
1227
+ * const store = createStore();
1228
+ * const middleware = createMiddleware(store);
1229
+ *
1230
+ * store.setValues({storeName: 'happy pets', limit: 50});
1231
+ *
1232
+ * middleware.addWillDelValuesCallback(() => false);
1233
+ *
1234
+ * store.delValues();
1235
+ * console.log(store.getValues());
1236
+ * // -> {storeName: 'happy pets', limit: 50}
1237
+ *
1238
+ * middleware.destroy();
1239
+ * ```
1240
+ * @category Configuration
1241
+ * @since v8.0.0
1242
+ */
1243
+ addWillDelValuesCallback(
1244
+ callback: WillDelValuesCallback,
1245
+ ): Middleware<Schemas>;
1246
+
1247
+ /**
1248
+ * The addWillDelValueCallback method registers a WillDelValueCallback that
1249
+ * will be called before any Value is deleted from the Store.
1250
+ *
1251
+ * This has schema-based typing. The following is a simplified representation:
1252
+ *
1253
+ * ```ts override
1254
+ * addWillDelValueCallback(callback: WillDelValueCallback): Middleware;
1255
+ * ```
1256
+ *
1257
+ * The callback returns `true` to allow the deletion or `false` to prevent it.
1258
+ * Multiple callbacks can be registered and they are called sequentially. If
1259
+ * any callback returns `false`, the deletion is prevented.
1260
+ * @param callback The WillDelValueCallback to register.
1261
+ * @returns A reference to the Middleware object, for chaining.
1262
+ * @example
1263
+ * This example registers a callback that prevents deleting the 'storeName'
1264
+ * Value from the pet store.
1265
+ *
1266
+ * ```js
1267
+ * import {createMiddleware, createStore} from 'tinybase';
1268
+ *
1269
+ * const store = createStore();
1270
+ * const middleware = createMiddleware(store);
1271
+ *
1272
+ * store.setValue('storeName', 'happy pets');
1273
+ *
1274
+ * middleware.addWillDelValueCallback((valueId) => valueId !== 'storeName');
1275
+ *
1276
+ * store.delValue('storeName');
1277
+ * console.log(store.getValue('storeName'));
1278
+ * // -> 'happy pets'
1279
+ *
1280
+ * middleware.destroy();
1281
+ * ```
1282
+ * @category Configuration
1283
+ * @since v8.0.0
1284
+ */
1285
+ addWillDelValueCallback(
1286
+ callback: WillDelValueCallback<Schemas[1]>,
1287
+ ): Middleware<Schemas>;
1288
+
1289
+ /**
1290
+ * The addWillApplyChangesCallback method registers a WillApplyChangesCallback
1291
+ * that will be called before Changes are applied to the Store via the
1292
+ * applyChanges method.
1293
+ *
1294
+ * This has schema-based typing. The following is a simplified representation:
1295
+ *
1296
+ * ```ts override
1297
+ * addWillApplyChangesCallback(callback: WillApplyChangesCallback): Middleware;
1298
+ * ```
1299
+ *
1300
+ * This callback receives the Changes object and can return it (to allow),
1301
+ * return a modified Changes object (to transform), or return `undefined` (to
1302
+ * reject). Multiple callbacks can be registered and they are called
1303
+ * sequentially, each receiving the output of the previous. If any callback
1304
+ * returns `undefined`, all remaining callbacks are skipped and the changes
1305
+ * are rejected.
1306
+ *
1307
+ * This fires when applyChanges is called directly, or indirectly via
1308
+ * applyMergeableChanges, setMergeableContent, or merge on a MergeableStore.
1309
+ * @param callback The WillApplyChangesCallback to register.
1310
+ * @returns A reference to the Middleware object, for chaining.
1311
+ * @example
1312
+ * This example registers a callback that rejects changes containing a
1313
+ * 'secret' table.
1314
+ *
1315
+ * ```js
1316
+ * import {createMiddleware, createStore} from 'tinybase';
1317
+ *
1318
+ * const store = createStore();
1319
+ * const middleware = createMiddleware(store);
1320
+ *
1321
+ * middleware.addWillApplyChangesCallback(([changedTables, changedValues]) =>
1322
+ * changedTables['secret'] != null
1323
+ * ? undefined
1324
+ * : [changedTables, changedValues, 1],
1325
+ * );
1326
+ *
1327
+ * store.applyChanges([{pets: {fido: {species: 'dog'}}}, {}, 1]);
1328
+ * console.log(store.getRow('pets', 'fido'));
1329
+ * // -> {species: 'dog'}
1330
+ *
1331
+ * store.applyChanges([{secret: {r1: {c1: 'v1'}}}, {}, 1]);
1332
+ * console.log(store.getTable('secret'));
1333
+ * // -> {}
1334
+ *
1335
+ * middleware.destroy();
1336
+ * ```
1337
+ * @category Configuration
1338
+ * @since v8.0.0
1339
+ */
1340
+ addWillApplyChangesCallback(
1341
+ callback: WillApplyChangesCallback<Schemas>,
1342
+ ): Middleware<Schemas>;
1343
+
1344
+ /**
1345
+ * The addDidSetRowCallback method registers a DidSetRowCallback for a
1346
+ * specific table that will be called after any Row in that table is changed
1347
+ * during a transaction, after mutator listeners have fired.
1348
+ *
1349
+ * This has schema-based typing. The following is a simplified representation:
1350
+ *
1351
+ * ```ts override
1352
+ * addDidSetRowCallback(tableId: Id, callback: DidSetRowCallback): Middleware;
1353
+ * ```
1354
+ *
1355
+ * Unlike `willSetRow`, which fires synchronously during each write, this
1356
+ * callback fires once per changed Row after all cell writes in the
1357
+ * transaction have landed. Multiple cell changes to the same Row within a
1358
+ * transaction produce a single callback with the full before/after Row
1359
+ * states.
1360
+ *
1361
+ * The callback receives `oldRow` (the Row at the start of the transaction)
1362
+ * and `newRow` (the Row after all writes). Return `newRow` to accept, a
1363
+ * different `Row` to replace, `oldRow` to revert, or an empty object to
1364
+ * delete.
1365
+ * @param tableId The Id of the Table to watch.
1366
+ * @param callback The DidSetRowCallback to register.
1367
+ * @returns A reference to the Middleware object, for chaining.
1368
+ * @example
1369
+ * This example registers a callback that validates the 'pets' table,
1370
+ * reverting any row that ends up without a required 'species' cell.
1371
+ *
1372
+ * ```js
1373
+ * import {createMiddleware, createStore} from 'tinybase';
1374
+ *
1375
+ * const store = createStore();
1376
+ * const middleware = createMiddleware(store);
1377
+ *
1378
+ * middleware.addDidSetRowCallback('pets', (_tableId, _rowId, oldRow, newRow) =>
1379
+ * 'species' in newRow ? newRow : oldRow,
1380
+ * );
1381
+ *
1382
+ * store.setRow('pets', 'fido', {species: 'dog', name: 'Fido'});
1383
+ * console.log(store.getRow('pets', 'fido'));
1384
+ * // -> {species: 'dog', name: 'Fido'}
1385
+ *
1386
+ * store.setRow('pets', 'nemo', {name: 'Nemo'});
1387
+ * console.log(store.getRow('pets', 'nemo'));
1388
+ * // -> {}
1389
+ *
1390
+ * middleware.destroy();
1391
+ * ```
1392
+ * @example
1393
+ * This example shows that multiple cell changes in one transaction result in
1394
+ * a single didSetRow callback with the full before/after row states.
1395
+ *
1396
+ * ```js
1397
+ * import {createMiddleware, createStore} from 'tinybase';
1398
+ *
1399
+ * const store = createStore();
1400
+ * const middleware = createMiddleware(store);
1401
+ *
1402
+ * const seen = [];
1403
+ * middleware.addDidSetRowCallback('pets', (_tableId, rowId, oldRow, newRow) => {
1404
+ * seen.push({rowId, oldRow: {...oldRow}, newRow: {...newRow}});
1405
+ * return newRow;
1406
+ * });
1407
+ *
1408
+ * store.transaction(() => {
1409
+ * store.setCell('pets', 'fido', 'name', 'Fido');
1410
+ * store.setCell('pets', 'fido', 'species', 'dog');
1411
+ * });
1412
+ * console.log(seen.length);
1413
+ * // -> 1
1414
+ * console.log(seen[0].rowId);
1415
+ * // -> 'fido'
1416
+ * console.log(seen[0].newRow);
1417
+ * // -> {name: 'Fido', species: 'dog'}
1418
+ *
1419
+ * middleware.destroy();
1420
+ * ```
1421
+ * @category Configuration
1422
+ * @since v8.0.0
1423
+ */
1424
+ addDidSetRowCallback<TableId extends TableIdFromSchema<Schemas[0]>>(
1425
+ tableId: TableId,
1426
+ callback: DidSetRowCallback<Schemas[0], TableId>,
1427
+ ): Middleware<Schemas>;
1428
+
1429
+ /**
1430
+ * The destroy method should be called when this Middleware object is no
1431
+ * longer used. It removes all hooks and listeners from the Store, and
1432
+ * unregisters the Middleware from the Store.
1433
+ * @example
1434
+ * This example creates a Middleware object against a newly-created Store and
1435
+ * then destroys it.
1436
+ *
1437
+ * ```js
1438
+ * import {createMiddleware, createStore} from 'tinybase';
1439
+ *
1440
+ * const store = createStore();
1441
+ * const middleware = createMiddleware(store);
1442
+ * middleware.destroy();
1443
+ * ```
1444
+ * @category Lifecycle
1445
+ * @since v8.0.0
1446
+ */
1447
+ destroy(): void;
1448
+ }
1449
+
1450
+ /**
1451
+ * The createMiddleware function creates a Middleware object, and is the main
1452
+ * entry point into the middleware module.
1453
+ *
1454
+ * This has schema-based typing. The following is a simplified representation:
1455
+ *
1456
+ * ```ts override
1457
+ * createMiddleware(store: Store): Middleware;
1458
+ * ```
1459
+ *
1460
+ * A given Store can only have one Middleware object associated with it. If you
1461
+ * call this function twice on the same Store, your second call will return a
1462
+ * reference to the Middleware object created by the first.
1463
+ * @param store The Store for which to register the Middleware.
1464
+ * @returns A reference to the new Middleware object.
1465
+ * @example
1466
+ * This example creates a Middleware object.
1467
+ *
1468
+ * ```js
1469
+ * import {createMiddleware, createStore} from 'tinybase';
1470
+ *
1471
+ * const store = createStore();
1472
+ * const middleware = createMiddleware(store);
1473
+ * console.log(middleware.getStore() == store);
1474
+ * // -> true
1475
+ * middleware.destroy();
1476
+ * ```
1477
+ * @example
1478
+ * This example creates a Middleware object, and calls the method a second time
1479
+ * for the same Store to return the same object.
1480
+ *
1481
+ * ```js
1482
+ * import {createMiddleware, createStore} from 'tinybase';
1483
+ *
1484
+ * const store = createStore();
1485
+ * const middleware = createMiddleware(store);
1486
+ * console.log(middleware === createMiddleware(store));
1487
+ * // -> true
1488
+ * middleware.destroy();
1489
+ * ```
1490
+ * @category Creation
1491
+ * @since v8.0.0
1492
+ */
1493
+ export function createMiddleware<Schemas extends OptionalSchemas>(
1494
+ store: Store<Schemas>,
1495
+ ): Middleware<Schemas>;