Skip to content

Commit c6f98a3

Browse files
committed
[middleware] Remove didSetRow
1 parent c845e77 commit c6f98a3

7 files changed

Lines changed: 2 additions & 548 deletions

File tree

site/guides/04_using_middleware.md

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ console.log(store.getValue('shopName'));
3333

3434
## Available Callbacks
3535

36-
A Middleware object supports 15 different callbacks that you can register. Each
36+
A Middleware object supports 14 different callbacks that you can register. Each
3737
callback is passed relevant parameters for the operation, and can return a
3838
value. The meaning of this return value depends on the type of callback:
3939

@@ -42,9 +42,6 @@ value. The meaning of this return value depends on the type of callback:
4242
If the function returns undefined (or void), the operation is cancelled.
4343
* For `willDel*` callbacks, the return value is a boolean that indicates whether
4444
the delete operation should proceed (true) or be cancelled (false).
45-
* For `didSetRow`, the return value is the final Row state to apply. Return
46-
`newRow` to accept, a different `Row` to replace, `oldRow` to revert, or an
47-
empty object to delete. See below for more details.
4845

4946
The full list of `willSet*` callbacks you can register is as follows:
5047

@@ -59,15 +56,6 @@ The full list of `willSet*` callbacks you can register is as follows:
5956
| willSetValue | valueId, value | When setValue is called. | Value or undefined |
6057
| willApplyChanges | changes | When applyChanges is called. | Changes or undefined |
6158

62-
There is also one special `did*` callback that is called at the end of the
63-
transaction - after all `will*` callbacks have settled and before any listeners
64-
are called. This gives you a chance to inspect or validate the final state of a
65-
Row for a specific table:
66-
67-
| Callback | Parameters | Called | Return |
68-
| --------- | ------------------------------ | ---------------------------------------------- | ------ |
69-
| didSetRow | tableId, rowId, oldRow, newRow | After all row changes settle in a transaction. | Row |
70-
7159
Finally, the full list of `willDel*` callbacks you can register is as follows:
7260

7361
| Callback | Parameters | Called | Return |
@@ -199,55 +187,6 @@ console.log(store.getCell('pets', 'fido', 'slug'));
199187
In the example above, both the original `setCell` call and the listener's
200188
`setCell` call pass through the uppercase middleware.
201189

202-
## Post-Transaction Row Callback
203-
204-
The `will*` callbacks fire synchronously as each write happens. Sometimes you
205-
want to inspect or validate a Row *after* all the dust has settled — after every
206-
cell change in a transaction has been applied and the Row is in its final state.
207-
That's what `didSetRow` is for.
208-
209-
`addDidSetRowCallback` is **table-scoped**: you register it for a specific
210-
table, so there is zero overhead for tables you don't care about.
211-
212-
```js
213-
const store2 = createStore();
214-
const middleware2 = createMiddleware(store2);
215-
216-
middleware2.addDidSetRowCallback('pets', (tableId, rowId, oldRow, newRow) => {
217-
// Require 'species' — revert rows that don't have it
218-
return 'species' in newRow ? newRow : oldRow;
219-
});
220-
221-
store2.setRow('pets', 'fido', {species: 'dog', name: 'Fido'});
222-
console.log(store2.getRow('pets', 'fido'));
223-
// -> {species: 'dog', name: 'Fido'}
224-
225-
store2.setRow('pets', 'nemo', {name: 'Nemo'});
226-
console.log(store2.getRow('pets', 'nemo'));
227-
// -> {}
228-
```
229-
230-
The callback receives `oldRow` (the Row as it was at the start of the
231-
transaction), and `newRow` (the Row as it is now, after all cell writes).
232-
233-
The callback needs to return the Row that should be the final state of the Row
234-
after any corrections. Return:
235-
236-
- `newRow` to accept the changes.
237-
- a different `Row` to replace the final state.
238-
- `oldRow` to revert all changes to the Row.
239-
- an empty object to delete the Row.
240-
241-
Unlike `willSet*` callbacks, the `didSetRow` chain never short-circuits: all
242-
registered callbacks for the table always run, each receiving the Row returned
243-
by the previous one.
244-
245-
Because `didSetRow` fires *after* mutating listeners, `newRow` reflects the
246-
truly final state of the Row — including any writes those listeners made.
247-
248-
Also note that multiple cell changes to the same Row within one transaction
249-
produce only one `didSetRow` call, not one per cell.
250-
251190
## Middleware And Schemas
252191

253192
The callbacks are called after the schema has been applied to the data. So, for

src/@types/middleware/docs.js

Lines changed: 0 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -262,43 +262,6 @@
262262
* @since v8.0.0
263263
*/
264264
/// WillApplyChangesCallback
265-
/**
266-
* The DidSetRowCallback type describes a function called after a Row is changed
267-
* during a transaction, and after mutator listeners have fired.
268-
*
269-
* Unlike the `willSet*` callbacks, which intercept writes as they happen,
270-
* `didSetRow` fires once per touched Row after all cell writes in the
271-
* transaction have completed. This means multiple cell changes to the same Row
272-
* within a single transaction result in just one `didSetRow` call, with the
273-
* full before-transaction and after-transaction Row states.
274-
*
275-
* The callback receives the Table Id, Row Id, the Row as it was at the start of
276-
* the transaction (`oldRow`), and the Row as it is now (`newRow`). It must
277-
* return a Row:
278-
*
279-
* - `newRow` to accept the changes.
280-
* - a different `Row` to replace the final state.
281-
* - `oldRow` to revert all changes to the Row.
282-
* - an empty object to delete the Row.
283-
*
284-
* Multiple DidSetRowCallback functions can be registered for the same table and
285-
* they will be called sequentially, each receiving the Row returned by the
286-
* previous callback. The chain never short-circuits: all registered callbacks
287-
* always run.
288-
*
289-
* Note that `addDidSetRowCallback` is table-scoped: you must specify the table
290-
* Id when registering. Callbacks are only invoked for rows in the specified
291-
* table, keeping overhead to zero for other tables.
292-
* @param tableId The Id of the Table containing the changed Row.
293-
* @param rowId The Id of the Row that was changed.
294-
* @param oldRow The Row as it was at the start of the transaction.
295-
* @param newRow The Row as it is now, after all cell writes including those
296-
* made by mutating listeners.
297-
* @returns The Row to use as the final state.
298-
* @category Callback
299-
* @since v8.0.0
300-
*/
301-
/// DidSetRowCallback
302265
/**
303266
* A Middleware object lets you intercept and validate writes to a Store.
304267
*
@@ -975,86 +938,6 @@
975938
* @since v8.0.0
976939
*/
977940
/// Middleware.addWillApplyChangesCallback
978-
/**
979-
* The addDidSetRowCallback method registers a DidSetRowCallback for a
980-
* specific table that will be called after any Row in that table is changed
981-
* during a transaction, after mutator listeners have fired.
982-
*
983-
* Unlike `willSetRow`, which fires synchronously during each write, this
984-
* callback fires once per changed Row after all cell writes in the
985-
* transaction have landed. Multiple cell changes to the same Row within a
986-
* transaction produce a single callback with the full before/after Row
987-
* states.
988-
*
989-
* The callback receives `oldRow` (the Row at the start of the transaction)
990-
* and `newRow` (the Row after all writes). Return `newRow` to accept, a
991-
* different `Row` to replace, `oldRow` to revert, or an empty object to
992-
* delete.
993-
* @param tableId The Id of the Table to watch.
994-
* @param callback The DidSetRowCallback to register.
995-
* @returns A reference to the Middleware object, for chaining.
996-
* @example
997-
* This example registers a callback that validates the 'pets' table,
998-
* reverting any row that ends up without a required 'species' cell.
999-
*
1000-
* ```js
1001-
* import {createMiddleware, createStore} from 'tinybase';
1002-
*
1003-
* const store = createStore();
1004-
* const middleware = createMiddleware(store);
1005-
*
1006-
* middleware.addDidSetRowCallback(
1007-
* 'pets',
1008-
* (_tableId, _rowId, oldRow, newRow) =>
1009-
* 'species' in newRow ? newRow : oldRow,
1010-
* );
1011-
*
1012-
* store.setRow('pets', 'fido', {species: 'dog', name: 'Fido'});
1013-
* console.log(store.getRow('pets', 'fido'));
1014-
* // -> {species: 'dog', name: 'Fido'}
1015-
*
1016-
* store.setRow('pets', 'nemo', {name: 'Nemo'});
1017-
* console.log(store.getRow('pets', 'nemo'));
1018-
* // -> {}
1019-
*
1020-
* middleware.destroy();
1021-
* ```
1022-
* @example
1023-
* This example shows that multiple cell changes in one transaction result in
1024-
* a single didSetRow callback with the full before/after row states.
1025-
*
1026-
* ```js
1027-
* import {createMiddleware, createStore} from 'tinybase';
1028-
*
1029-
* const store = createStore();
1030-
* const middleware = createMiddleware(store);
1031-
*
1032-
* const seen = [];
1033-
* middleware.addDidSetRowCallback(
1034-
* 'pets',
1035-
* (_tableId, rowId, oldRow, newRow) => {
1036-
* seen.push({rowId, oldRow: {...oldRow}, newRow: {...newRow}});
1037-
* return newRow;
1038-
* },
1039-
* );
1040-
*
1041-
* store.transaction(() => {
1042-
* store.setCell('pets', 'fido', 'name', 'Fido');
1043-
* store.setCell('pets', 'fido', 'species', 'dog');
1044-
* });
1045-
* console.log(seen.length);
1046-
* // -> 1
1047-
* console.log(seen[0].rowId);
1048-
* // -> 'fido'
1049-
* console.log(seen[0].newRow);
1050-
* // -> {name: 'Fido', species: 'dog'}
1051-
*
1052-
* middleware.destroy();
1053-
* ```
1054-
* @category Configuration
1055-
* @since v8.0.0
1056-
*/
1057-
/// Middleware.addDidSetRowCallback
1058941
/**
1059942
* The destroy method should be called when this Middleware object is no
1060943
* longer used. It removes all hooks and listeners from the Store, and

src/@types/middleware/index.d.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,6 @@ export type WillApplyChangesCallback = (
7777
changes: Changes,
7878
) => Changes | undefined;
7979

80-
/// DidSetRowCallback
81-
export type DidSetRowCallback = (
82-
tableId: Id,
83-
rowId: Id,
84-
oldRow: Row,
85-
newRow: Row,
86-
) => Row;
87-
8880
/// Middleware
8981
export interface Middleware {
9082
/// Middleware.getStore
@@ -132,9 +124,6 @@ export interface Middleware {
132124
/// Middleware.addWillApplyChangesCallback
133125
addWillApplyChangesCallback(callback: WillApplyChangesCallback): Middleware;
134126

135-
/// Middleware.addDidSetRowCallback
136-
addDidSetRowCallback(tableId: Id, callback: DidSetRowCallback): Middleware;
137-
138127
/// Middleware.destroy
139128
destroy(): void;
140129
}

src/@types/middleware/with-schemas/index.d.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -149,17 +149,6 @@ export type WillApplyChangesCallback<Schemas extends OptionalSchemas> = (
149149
changes: Changes<Schemas>,
150150
) => Changes<Schemas> | undefined;
151151

152-
/// DidSetRowCallback
153-
export type DidSetRowCallback<
154-
Schema extends OptionalTablesSchema,
155-
TableId extends TableIdFromSchema<Schema>,
156-
> = (
157-
tableId: TableId,
158-
rowId: Id,
159-
oldRow: Row<Schema, TableId>,
160-
newRow: Row<Schema, TableId>,
161-
) => Row<Schema, TableId>;
162-
163152
/// Middleware
164153
export interface Middleware<in out Schemas extends OptionalSchemas> {
165154
/// Middleware.getStore
@@ -235,12 +224,6 @@ export interface Middleware<in out Schemas extends OptionalSchemas> {
235224
callback: WillApplyChangesCallback<Schemas>,
236225
): Middleware<Schemas>;
237226

238-
/// Middleware.addDidSetRowCallback
239-
addDidSetRowCallback<TableId extends TableIdFromSchema<Schemas[0]>>(
240-
tableId: TableId,
241-
callback: DidSetRowCallback<Schemas[0], TableId>,
242-
): Middleware<Schemas>;
243-
244227
/// Middleware.destroy
245228
destroy(): void;
246229
}

src/middleware/index.ts

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type {Id} from '../@types/common/index.d.ts';
22
import type {
3-
DidSetRowCallback,
43
Middleware,
54
WillApplyChangesCallback,
65
WillDelCellCallback,
@@ -33,9 +32,8 @@ import type {
3332
} from '../@types/store/index.d.ts';
3433
import {arrayEvery, arrayPush, arrayReduce} from '../common/array.ts';
3534
import {getCreateFunction} from '../common/definable.ts';
36-
import {IdMap, mapEnsure, mapGet, mapNew} from '../common/map.ts';
3735
import {objFreeze} from '../common/obj.ts';
38-
import {ifNotUndefined, isUndefined} from '../common/other.ts';
36+
import {isUndefined} from '../common/other.ts';
3937
import {ProtectedStore} from '../store/index.ts';
4038

4139
const reduceCallbacks = (
@@ -81,7 +79,6 @@ export const createMiddleware = getCreateFunction(
8179
const willDelValuesCallbacks: WillDelValuesCallback[] = [];
8280
const willDelValueCallbacks: WillDelValueCallback[] = [];
8381
const willApplyChangesCallbacks: WillApplyChangesCallback[] = [];
84-
const didSetRowCallbacksMap: IdMap<DidSetRowCallback[]> = mapNew();
8582

8683
const willSetContent = (content: Content): Content | undefined =>
8784
reduceCallbacks(willSetContentCallbacks, content);
@@ -128,19 +125,6 @@ export const createMiddleware = getCreateFunction(
128125
const willApplyChanges = (changes: Changes): Changes | undefined =>
129126
reduceCallbacks(willApplyChangesCallbacks, changes);
130127

131-
const didSetRow = (tableId: Id, rowId: Id, oldRow: Row, newRow: Row): Row =>
132-
ifNotUndefined(
133-
mapGet(didSetRowCallbacksMap, tableId),
134-
(callbacks) =>
135-
arrayReduce(
136-
callbacks,
137-
(current: Row, callback) =>
138-
callback(tableId, rowId, oldRow, current),
139-
newRow,
140-
),
141-
() => newRow,
142-
) as Row;
143-
144128
const getStore = (): Store => store;
145129

146130
const addWillSetContentCallback = addCallback(willSetContentCallbacks);
@@ -158,17 +142,6 @@ export const createMiddleware = getCreateFunction(
158142
const addWillDelValueCallback = addCallback(willDelValueCallbacks);
159143
const addWillApplyChangesCallback = addCallback(willApplyChangesCallbacks);
160144

161-
const addDidSetRowCallback = (
162-
tableId: Id,
163-
callback: DidSetRowCallback,
164-
): Middleware =>
165-
fluent(() =>
166-
arrayPush(
167-
mapEnsure(didSetRowCallbacksMap, tableId, () => []),
168-
callback,
169-
),
170-
);
171-
172145
const destroy = (): void => {};
173146

174147
const middleware: Middleware = objFreeze({
@@ -187,7 +160,6 @@ export const createMiddleware = getCreateFunction(
187160
addWillDelValuesCallback,
188161
addWillDelValueCallback,
189162
addWillApplyChangesCallback,
190-
addDidSetRowCallback,
191163
destroy,
192164
} as Middleware);
193165

@@ -206,7 +178,6 @@ export const createMiddleware = getCreateFunction(
206178
willDelValues,
207179
willDelValue,
208180
willApplyChanges,
209-
didSetRow,
210181
);
211182

212183
return middleware;

0 commit comments

Comments
 (0)