Skip to content

Commit 0cd4582

Browse files
committed
docs(objectql): align the two docblocks with the shipped per-row vocabulary, add the changeset
Follow-up to the same two sites after merging PR #18625 (card #17975), the sibling prose repair that landed in this package. - Both sites now use the package's shipped spelling for the dispatch model: per matched row, on the single-record shape, ADR-0058 Addendum II D1/D2. - The second site no longer names the opt-in `dispatchUnscopedMultiWrite` dispatch. `wrapDeclarativeHook` is applied at registration (`hook-binder.ts:221`), but no metadata binding can set that flag today, so naming it as an absence case this function observes would be a claim that cannot be shown to be reachable. The truthful statement — any update-shaped context whose prior row is not in hand — is true by construction. - Adds the `patch` changeset: the first docblock is emitted verbatim onto the exported `hookRecordState` declaration in the published `.d.ts`. Prose only: no behaviour change, no assertion change. Claude-Session: https://claude.ai/code/session_01CqmCgU5RGDoJYhHUMVp2af Co-authored-by: Claude <noreply@anthropic.com>
1 parent ba2e3da commit 0cd4582

2 files changed

Lines changed: 43 additions & 10 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
'@objectstack/objectql': patch
3+
---
4+
5+
docs(objectql): the hook-wrapper docblocks state the per-row `before*` contract (#18331)
6+
7+
Two docblocks in `hook-wrappers.ts` stated the RETIRED batch model in the
8+
present tense: `pickRecordPayload`'s said a predicate (`multi: true`) bulk
9+
update's `before*` dispatch "still fires once for the batch with no prior row",
10+
and `pickPreviousPayload`'s "when `previous` is ABSENT" list named that same
11+
dispatch as an absence case because "it fires ONCE for N matched rows".
12+
13+
Ruling #16074 / ADR-0058 Addendum II (clauses D1/D2) retired that model, and the
14+
engine already implements the replacement: `dispatchPerRowBeforeHooks` dispatches
15+
`before*` once per matched row on the single-record shape and binds that row's
16+
pre-image (`previous: coerceBooleanFields(schema, row)`). So both phases of a
17+
predicate write now merge, materialise and bind `previous` exactly as a
18+
single-record write does; what remains unbound is any update-shaped context
19+
whose prior row is not in hand, which is what the second docblock now says.
20+
21+
This is published text, not an internal comment. Measured against the shipped
22+
`@objectstack/objectql@17.4.0` tarball: the first docblock is emitted verbatim
23+
onto the exported `hookRecordState` declaration (`dist/util-Dw5ZTIII.d.ts:8039`,
24+
and the matching `.d.mts`), reachable from both the `.` and `./core`
25+
entrypoints, so every consumer's editor surfaces the retired sentence on hover.
26+
The second docblock does NOT ship — `pickPreviousPayload` is module-private and
27+
appears in `dist/` only as an `{@link}` reference — but it is the source a
28+
maintainer reads, and two docblocks one screen apart stating opposite contracts
29+
is the drift this repairs.
30+
31+
No behaviour change and no assertion change: prose only.
32+
33+
Graded `patch`: the act moves published PROSE. It adds no exported symbol, no
34+
key and no accepted value — the accept set was widened by PR #17249 in
35+
`@objectstack/spec`, not here — so this PR declares no clause ② (`Clause-②: no`).

packages/objectql/src/hook-wrappers.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,7 +1084,7 @@ function declaredFieldsFor(ctx: HookContext): Record<string, unknown> | undefine
10841084
* `before*` dispatch since #5574 (ADR-0058 Addendum II, D1/D2): both carry the
10851085
* row's prior state, so both merge and materialise like any single-record
10861086
* write — which is exactly what "`record` is the row's real state, not the
1087-
* bare payload" means (#4862). A context whose prior row was never read keeps
1087+
* bare payload" means (#4862). A context whose prior row is not in hand keeps
10881088
* its payload exactly as it is rather than gaining `null`s that contradict
10891089
* stored state.
10901090
*
@@ -1175,15 +1175,13 @@ function pickRecordPayload(ctx: HookContext): any {
11751175
* identifier from the CEL scope. Same here:
11761176
* - **insert** — there is no prior state, so `previous` is unbound and any
11771177
* reference to it is an author error, reported as such;
1178-
* - **a `before*` dispatch that names no row** — the opt-in
1179-
* `dispatchUnscopedMultiWrite` one, fired once for a `multi: true` write
1180-
* carrying no caller predicate at all: with no row there is no single
1181-
* prior record to bind, so `previous` stays unbound rather than being
1182-
* invented. A predicate (`multi: true`) bulk write is NOT this case — it
1183-
* dispatches both phases per matched row (`after*` since #5038, `before*`
1184-
* since #5574, ADR-0058 Addendum II D1/D2), each binding the row's own
1185-
* pre-image, so a transition condition reads exactly as it does on a
1186-
* single-record write.
1178+
* - **any update-shaped context whose prior row is not in hand** — with no
1179+
* row there is no single prior record to bind, so `previous` stays unbound
1180+
* rather than being invented. A predicate (`multi: true`) bulk write is no
1181+
* longer one of these: since #5574 (ADR-0058 Addendum II, D1/D2) it
1182+
* dispatches BOTH phases per matched row — `after*` since #5038 — each
1183+
* context binding that row's own pre-image, so a transition condition
1184+
* reads exactly as it does on a single-record write.
11871185
* Binding `null`/`{}` instead would make `previous.x == null` answer "yes"
11881186
* for a record whose prior state is simply unknown — a fabricated fact, the
11891187
* one thing materialisation is careful never to do.

0 commit comments

Comments
 (0)