Skip to content

Commit 9a910c4

Browse files
os-steveclaude
andauthored
feat(spec): publish the typed hook ctx.api face — HookApi / HookObjectApi / HookQuery (#19067)
Fixes #18163 Clause-②: yes (widening) Executes batch #147 item 1, letter A — maintainer 「其他同意」 2026-09-17T14:01Z. `@objectstack/spec/data` now exports the typed hook `ctx.api` face, so a metadata app's `*.hook.ts` imports the platform's type instead of hand-declaring one. Nine additive exported names, zero runtime, no removal and no signature change. `HookApi` · `HookObjectApi` · `HookQuery` · `HookCountQuery` · `HookUpdateOptions` · `HookDeleteOptions` · `HookUpdateDoc` · `HookDoc` · `HookDriverPassthroughOptions` ```ts import type { HookApi } from '@objectstack/spec/data'; const api = ctx.api as HookApi | undefined; if (!api) return; const owner = await api.object('user').findOne({ where: { id: ctx.input.owner } }); ``` ## Measured at the engine seam, not from any app's copy The ruling's third prescription. Located by declaration site, never by a mention: | fact | declaration site | |:---|:---| | `ctx.api` is built per dispatch by `ObjectQL.buildHookApi` and is a `ScopedContext` | `packages/objectql/src/engine.ts:4716` | | `ScopedContext.object(name)` returns an `ObjectRepository` | `packages/objectql/src/engine.ts:15625` | | the repository's real method set, and that it injects `context` after the caller's spread | `packages/objectql/src/engine.ts:15420-15535` | | the engine's per-method legal option keys | `packages/objectql/src/engine.ts:519-535` | | the alias table and the fold, `filter` to `where` and `top` to `limit` | `packages/spec/src/data/data-engine.zod.ts:517,551` | | the throw on a slot whose spellings disagree | `packages/objectql/src/engine.ts:792-799` | | the type `ctx.api` already carries — `IScopedContext`, from `@objectstack/spec/contracts` | `packages/spec/src/contracts/scoped-context.ts:208` | **What the fold actually does**, which is finer than "refuses both": redundant spellings that are deep-equal collapse into `where` in silence; spellings that carry different values are irreconcilable and the engine throws, naming both. So `{ where, filter }` is a coin toss decided by whether the two happen to agree. Omitting the alias key makes it neither — `TS2353` at the authoring site. The same measurement carries `top`, the OData alias of `limit`: same slot table, same throw on a value disagreement, no expressive power of its own. Extending the ruling's `filter` instruction to `top` is this PR's reading of the same rule and is flagged in the file's own docblock as the one place contract review should decide whether the type should be wider than the ruling's letter. ## Not a second dialect of `IScopedContext` `contracts/scoped-context.ts` stays the CHECKED IMPLEMENTATION contract — `ScopedContext` and `ObjectRepository` carry `implements` clauses against it, and its query bags are deliberately loose, for the reason that file argues at length. This is the authoring half of the same seam. They cannot drift because every option shape here is an `Omit` or `Pick` over the very `Engine*Options` schemas the engine's own legal-key sets are pinned against (`engine-unknown-option.test.ts`), and `hook-api.test.ts` pins `HookApi` as assignable to `IScopedContext` in both the context and the repository position — so `ctx.api as HookApi` stays a direct cast, never `as unknown as`. Deliberately absent, each with its reason in the docblock: `context` (injected and discarded), the `cursor` / `distinct` / `upsert` tombstones, `sudo()` (the #5945 exclusion stands — `Hook.runAs: 'system'` is the declared way to run elevated), and `aggregate` / `execute` / `create` / `deleteById`. `count` is the one shape without the driver pass-through keys, because the engine forwards no bag on that method and rejects them there — engine behaviour no document states. ## Verification, all at `d3895054b2` **Reverse verification from a consumer's vantage** — a throwaway probe in a package that resolves `@objectstack/spec/data` through the exports map into the BUILT `dist`, run in two legs and then removed (worktree confirmed clean): ``` LEG A probe carries `filter` beside `where` tsc exit 2 os-hookapi-consumer-probe.ts(5,62): error TS2353: Object literal may only specify known properties, and 'filter' does not exist in type 'HookQuery'. LEG B same probe, alias key removed tsc exit 0 ``` On-disk proof was taken per leg (1 occurrence of the mutated text, then 0), so neither leg is a no-op. - `pnpm --filter @objectstack/spec typecheck` — exit 0. Three programs: the build config, `tsconfig.scripts.json`, and `check:test-typecheck`, which is what compiles the test layer. The six `@ts-expect-error` pins in `hook-api.test.ts` are therefore real: an unused directive is itself an error, so a directive that stopped catching anything turns this red. - `pnpm --filter @objectstack/spec test` — 492 files, 14311 tests, all pass. - `pnpm --filter @objectstack/spec check:generated` — all 16 artifacts up to date. - `pnpm lint` repo-wide (`eslint . --no-inline-config`) — exit 0, no narrowing claimed. - Gate families derived with `scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack` and reconciled with `--ran`: **83 derived, 79 run green, 4 NOT MEASURED.** The four are `check:doc-formula-expressions`, `check:dual-build-cjs-loads`, `check:lean-entry-closure` and `check:type-check-debt`, each exiting **3 — PREREQUISITE NOT MET**, which is the code those gates use for "nothing was measured". All four need the whole workspace built (`turbo run build` over every package); this diff's own dependency closure is empty, since `packages/spec` has no workspace dependencies. CI builds fresh and runs all four. `origin/main` moved onto the same three generated artifacts and onto `data/driver.zod.ts`, which this file reads for the pass-through keys, so the merge went through `scripts/pm/os-regen-merge.sh` and the regeneration is its own commit. Both sides survive in the regenerated artifacts: this branch's nine `Hook*` entries and main's `driverSupportsTransactions`. ## Acceptance notes - **The card's own grep is not a reading, and the premise is still true.** `grep -rhoE "export (type|interface) (HookApi|HookContext|HookObjectApi)" ... dist/data/*.d.ts` returns zero for `HookContext` too — a symbol that has always been exported from that entry point. That glob reaches exactly one file, `dist/data/index.d.ts`, which is a renamed re-export barrel (`export { k as HookContext } from '../datasource.zod-...js'`); every declaration lives in a hashed chunk one directory up, outside the glob. Re-derived with a corrected instrument that counts the barrel's export bindings: `HookContext` 1, `EngineQueryOptions` 1 (positive controls), `HookApi` / `HookObjectApi` / `HookQuery` 0 across the whole published `dist` and 0 across every package source. So the gap was real; the instrument that found it could not have told. - *noted, not filed:* nothing pins that the CLASS `ScopedContext` satisfies `HookApi`. `packages/spec` must not depend on `packages/objectql`, so that leg belongs beside `hook-input-shape-contract.test.ts` in objectql, which this card's file surface excludes. Carrier: whoever next edits `ScopedContext` or `ObjectRepository` is in `packages/objectql/src/engine.ts`, where the pin would live, and the reference app's follow-up card the ruling names is the other side of the same check. - *noted, not filed:* `IScopedContext` is reachable only from `@objectstack/spec/contracts`, so an author who wants to name the declared type of `ctx.api` alongside `HookApi` imports from two entry points. Carrier: the same follow-up card, which is the first consumer to feel it. - *noted, not filed:* `EngineTransactionInfo` and `EngineTransactionOptions` are referenced by `HookApi.transaction` but are not nameable from `./data`. Structural use needs no name and `check:entry-nameability` passes, so this is an observation, not a gap. Carrier: none — no consumer needs to spell them. ## NOT MEASURED — say it plainly The ruling names hotcrm's `src/objects/_hook-api.ts` as the acceptance fixture: it must type-check against this export with its own copy deleted. **That leg was not run.** hotcrm is not a repository this session can reach, and the ruling is explicit that its file is the fixture and not the source of truth, so nothing here was written from the card's quoted excerpts of it. The reverse verification above is the closest reachable stand-in: a real consumer, resolving through the published exports map into the built `.d.ts`, refusing `filter` and accepting the canonical shape. It is not the fixture, and it is not claimed to be. --- _Generated by [Claude Code](https://claude.ai/code/session_01AmH9bKvGoLjiY86Q4Z3og2)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 86b9000 commit 9a910c4

7 files changed

Lines changed: 784 additions & 2 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
'@objectstack/spec': minor
3+
---
4+
5+
`@objectstack/spec/data` now exports the typed hook `ctx.api` face — `HookApi`, `HookObjectApi`, `HookQuery`, `HookCountQuery`, `HookUpdateDoc`, `HookUpdateOptions`, `HookDeleteOptions`, `HookDoc` and `HookDriverPassthroughOptions` — so a metadata app's `*.hook.ts` imports the platform's type instead of hand-declaring one (#18163). The same entry additionally re-exports `EngineTransactionInfo` and `EngineTransactionOptions`, which its public declarations reference structurally: without them a consumer that imports only `@objectstack/spec/data` and emits declarations answers `TS2883: The inferred type ... cannot be named without a reference to ...`. Type-only re-exports of the declarations `@objectstack/spec/contracts` already publishes, not second declarations.
6+
7+
```ts
8+
import type { HookApi } from '@objectstack/spec/data';
9+
10+
const api = ctx.api as HookApi | undefined;
11+
if (!api) return;
12+
const owner = await api.object('user').findOne({ where: { id: ctx.input.owner } });
13+
```
14+
15+
The platform already implemented this surface; it just never published a type an app could import, so every app re-derived the engine's option vocabulary in a copy that drifts the moment the engine moves. The reference third-party app carried ~2,358 authored tokens of one in a single file, imported by 17 hook files.
16+
17+
- **The query shape is `where`-only — there is no `filter` key, deliberately.** `RPC_QUERY_ALIAS_SLOTS` declares `filter` as the alias of `where` (and `top` as the alias of `limit`); every engine entry point folds the `where` slot, collapsing redundant identical spellings and REFUSING the slot when the two spellings carry different values. So `{ where, filter }` is silent when they happen to agree and a runtime throw when they do not. Omitting the alias keys makes it neither: `TS2353: 'filter' does not exist in type 'HookQuery'`, at the authoring site.
18+
- **Not a second dialect of `IScopedContext`.** `contracts/scoped-context.ts` stays the CHECKED IMPLEMENTATION contract ObjectQL's `ScopedContext` and `ObjectRepository` carry `implements` clauses against, with its deliberately loose `Record<string, unknown>` bags. This is the authoring half of the same seam: `HookApi` is assignable to `IScopedContext`, so `ctx.api as HookApi` stays a direct cast, and nothing about the older contract changes.
19+
- **Every option shape is DERIVED, not transcribed.** Each is an `Omit`/`Pick` over the `Engine*Options` schemas that the engine's own per-method legal-key sets are pinned against, so a key added to a schema reaches the published type in the same run it reaches the engine's accepted set. `count` is the one shape without the driver pass-through keys, because the engine forwards no bag on that method and rejects them there — engine behaviour no document states, and exactly what a hand-written copy gets wrong.
20+
- **What is deliberately absent, each for a stated reason**: `context` (the repository injects it and discards a caller's), the `cursor` / `distinct` / `upsert` tombstones, `sudo()` (the #5945 exclusion stands — `Hook.runAs: 'system'` is the declared way to run elevated), and `aggregate` / `execute` / `create` / `deleteById`.
21+
22+
Additive only: eleven new exported names from `./data` (nine new declarations plus two type-only re-exports), no removal and no signature change, so nothing an existing consumer imports moves.
23+
24+
Clause-②: yes (widening)

‎packages/spec/api-surface-declarations/data.txt‎

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
# excluded: documentation drift is `check:docs`'s axis, not this one.
1313
#
1414
# entry: ./data
15-
# exported names: 833
16-
# declarations: 846
15+
# exported names: 844
16+
# declarations: 857
1717
#
1818
# GENERATED — ⛔ never hand-edited. Regenerate after a real build:
1919
# pnpm --filter @objectstack/spec build && pnpm --filter @objectstack/spec gen:api-surface-declarations
@@ -6167,6 +6167,46 @@ declare const EngineQueryOptionsSchema: z.ZodObject<{
61676167
distinct: z.ZodOptional<z.ZodNever>;
61686168
}, z.core.$strip>;
61696169

6170+
// ── EngineTransactionInfo (interface) ──
6171+
interface EngineTransactionInfo {
6172+
/**
6173+
* `true` when THIS call opened the transaction and therefore owns its
6174+
* commit/rollback; `false` when it JOINED an already-open ambient one
6175+
* (ADR-0067 D2) and some outer caller owns the outcome.
6176+
*
6177+
* The join is correct and stays — a nested `begin` would take a second
6178+
* connection (deadlocking a single-connection SQLite pool) and would not be
6179+
* covered by the outer rollback. What was missing is that the callback
6180+
* could not TELL: a joined callback's `throw` unwinds work the outer owner
6181+
* may still commit or roll back on its own terms, and guarantees phrased
6182+
* as "this whole unit rolls back together" (`batchData`'s rollback
6183+
* response, ADR-0119 D4) hold only for the owner. A callback that must not
6184+
* promise what it does not control reads `owned` and says so.
6185+
*/
6186+
owned: boolean;
6187+
}
6188+
6189+
// ── EngineTransactionOptions (interface) ──
6190+
interface EngineTransactionOptions {
6191+
/**
6192+
* Fail CLOSED when the datasource cannot give a real transaction.
6193+
*
6194+
* Default (`undefined` / `false`) keeps ADR-0119 D1's declared degrade: a
6195+
* driver without `beginTransaction` runs the callback with no transaction
6196+
* and no rollback, warning once. That degrade is right for callers who can
6197+
* live without atomicity (test doubles, in-memory drivers) and wrong for
6198+
* callers whose whole reason to open a transaction is the rollback.
6199+
*
6200+
* With `require: true` the engine THROWS instead of degrading, before the
6201+
* callback runs — so a caller that cannot tolerate losing atomicity states
6202+
* it once, at the call site, instead of re-deriving `batchData`'s probe.
6203+
* That probe is the precedent being generalized here (ADR-0119 D4, cited in
6204+
* older text as ADR-0118 D4 — see that ADR's renumbering note): an `atomic`
6205+
* request refuses rather than silently running best-effort.
6206+
*/
6207+
require?: boolean;
6208+
}
6209+
61706210
// ── EngineUpdateOptions (type) ──
61716211
type EngineUpdateOptions = z.input<typeof EngineUpdateOptionsSchema>;
61726212

@@ -14276,6 +14316,26 @@ declare const GroupByNodeSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
1427614316
// ── Hook (type) ──
1427714317
type Hook = z.input<typeof HookSchema>;
1427814318

14319+
// ── HookApi (interface) ──
14320+
interface HookApi {
14321+
/** The repository for `name`, bound to this context. */
14322+
object(name: string): HookObjectApi;
14323+
/**
14324+
* Run `callback` inside one driver transaction: committed when it returns,
14325+
* rolled back when it throws.
14326+
*
14327+
* The callback receives a NEW `HookApi` whose operations share the
14328+
* transaction handle — reach objects through THAT context (`tx.object(…)`),
14329+
* not the outer one, or the writes land outside the transaction.
14330+
*
14331+
* The second parameter is declared because the PRODUCER hands it
14332+
* unconditionally (`ScopedContext.transaction`, #5696). Contravariance keeps
14333+
* the zero- and one-argument callbacks authors actually write assignable, so
14334+
* the truthful signature is also the more permissive one.
14335+
*/
14336+
transaction<T>(callback: (trxCtx: HookApi, info: EngineTransactionInfo) => Promise<T>, opts?: EngineTransactionOptions): Promise<T>;
14337+
}
14338+
1427914339
// ── HookBody (type) ──
1428014340
type HookBody = z.input<typeof HookBodySchema>;
1428114341

@@ -14370,9 +14430,21 @@ declare const HookContextSchema: z.ZodObject<{
1437014430
}, z.core.$strip>>;
1437114431
}, z.core.$strip>;
1437214432

14433+
// ── HookCountQuery (type) ──
14434+
type HookCountQuery = Omit<EngineCountOptions, 'context'>;
14435+
14436+
// ── HookDeleteOptions (type) ──
14437+
type HookDeleteOptions = Omit<EngineDeleteOptions, 'context'> & HookDriverPassthroughOptions;
14438+
1437314439
// ── HookDispatch (type) ──
1437414440
type HookDispatch = NonNullable<HookContext['dispatch']>;
1437514441

14442+
// ── HookDoc (type) ──
14443+
type HookDoc = Record<string, unknown>;
14444+
14445+
// ── HookDriverPassthroughOptions (type) ──
14446+
type HookDriverPassthroughOptions = Pick<DriverOptions, 'transaction' | 'tenantId' | 'tenantIds' | 'timezone' | 'bypassTenantAudit' | 'preserveAudit'>;
14447+
1437614448
// ── HookEvent (const) ──
1437714449
declare const HookEvent: z.ZodEnum<{
1437814450
beforeInsert: "beforeInsert";
@@ -14388,9 +14460,51 @@ declare const HookEvent: z.ZodEnum<{
1438814460
// ── HookEventType (type) ──
1438914461
type HookEventType = z.input<typeof HookEvent>;
1439014462

14463+
// ── HookObjectApi (interface) ──
14464+
interface HookObjectApi {
14465+
/**
14466+
* Read every record the query selects.
14467+
*
14468+
* `Promise<any[]>` mirrors `IScopedObjectRepository.find` and
14469+
* `IDataEngine.find`; narrowing it here would make this face disagree with
14470+
* the two declarations it forwards through.
14471+
*/
14472+
find(query?: HookQuery): Promise<any[]>;
14473+
/** Read the ONE record the query selects, or `null`. */
14474+
findOne(query?: HookQuery): Promise<Record<string, any> | null>;
14475+
/** Count the records the query selects. */
14476+
count(query?: HookCountQuery): Promise<number>;
14477+
/** Insert one record, or an array of records. */
14478+
insert(data: HookDoc | HookDoc[]): Promise<any>;
14479+
/**
14480+
* Update records: the record for the single-record form, the affected-row
14481+
* count for the predicate form (`{ where, multi: true }`), `null` when the
14482+
* write matched nothing.
14483+
*/
14484+
update(data: HookUpdateDoc, options?: HookUpdateOptions): Promise<Record<string, any> | number | null>;
14485+
/**
14486+
* Update a single record by id — the id travels as the first argument.
14487+
*
14488+
* Answers the written record, or `null` when the id matched nothing. A falsy
14489+
* id is not a narrower answer but a REFUSAL: `0` and `''` identify no row, so
14490+
* the dispatch rejects and the call throws.
14491+
*/
14492+
updateById(id: string | number, data: HookUpdateDoc): Promise<Record<string, any> | null>;
14493+
/**
14494+
* Delete records — `{ where, multi: true }` for the predicate form.
14495+
*
14496+
* `Promise<boolean | number>` is what `IDataEngine.delete` declares, one door
14497+
* down from this method.
14498+
*/
14499+
delete(options?: HookDeleteOptions): Promise<boolean | number>;
14500+
}
14501+
1439114502
// ── HookParsed (type) ──
1439214503
type HookParsed = z.infer<typeof HookSchema>;
1439314504

14505+
// ── HookQuery (type) ──
14506+
type HookQuery = Omit<EngineQueryOptions, 'context' | 'top' | 'cursor' | 'distinct'> & HookDriverPassthroughOptions;
14507+
1439414508
// ── HookSchema (const) ──
1439514509
declare const HookSchema: z.ZodObject<{
1439614510
_lock: z.ZodOptional<z.ZodEnum<{
@@ -14484,6 +14598,12 @@ declare const HookSchema: z.ZodObject<{
1448414598
}>>;
1448514599
}, z.core.$strict>;
1448614600

14601+
// ── HookUpdateDoc (type) ──
14602+
type HookUpdateDoc = HookDoc;
14603+
14604+
// ── HookUpdateOptions (type) ──
14605+
type HookUpdateOptions = Omit<EngineUpdateOptions, 'context' | 'upsert'> & WriteObservabilityOptions & HookDriverPassthroughOptions;
14606+
1448714607
// ── IMPORT_BOOLEAN_FALSE_TOKENS (const) ──
1448814608
declare const IMPORT_BOOLEAN_FALSE_TOKENS: ReadonlySet<string>;
1448914609

‎packages/spec/api-surface/data.json‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@
238238
"EngineQueryOptions (type)",
239239
"EngineQueryOptionsParsed (type)",
240240
"EngineQueryOptionsSchema (const)",
241+
"EngineTransactionInfo (interface)",
242+
"EngineTransactionOptions (interface)",
241243
"EngineUpdateOptions (type)",
242244
"EngineUpdateOptionsSchema (const)",
243245
"EqualityOperatorSchema (const)",
@@ -337,18 +339,27 @@
337339
"GroupByNode (type)",
338340
"GroupByNodeSchema (const)",
339341
"Hook (type)",
342+
"HookApi (interface)",
340343
"HookBody (type)",
341344
"HookBodyCapability (const)",
342345
"HookBodyCapability (type)",
343346
"HookBodyParsed (type)",
344347
"HookBodySchema (const)",
345348
"HookContext (type)",
346349
"HookContextSchema (const)",
350+
"HookCountQuery (type)",
351+
"HookDeleteOptions (type)",
347352
"HookDispatch (type)",
353+
"HookDoc (type)",
354+
"HookDriverPassthroughOptions (type)",
348355
"HookEvent (const)",
349356
"HookEventType (type)",
357+
"HookObjectApi (interface)",
350358
"HookParsed (type)",
359+
"HookQuery (type)",
351360
"HookSchema (const)",
361+
"HookUpdateDoc (type)",
362+
"HookUpdateOptions (type)",
352363
"IMPORT_BOOLEAN_FALSE_TOKENS (const)",
353364
"IMPORT_BOOLEAN_TRUE_TOKENS (const)",
354365
"IMPORT_REFERENCE_TYPES (const)",

‎packages/spec/export-origins/data.json‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@
233233
"EngineQueryOptions": "src/data/data-engine.zod.ts#EngineQueryOptions (type)",
234234
"EngineQueryOptionsParsed": "src/data/data-engine.zod.ts#EngineQueryOptionsParsed (type)",
235235
"EngineQueryOptionsSchema": "src/data/data-engine.zod.ts#EngineQueryOptionsSchema (const)",
236+
"EngineTransactionInfo": "src/contracts/objectql-engine.ts#EngineTransactionInfo (interface)",
237+
"EngineTransactionOptions": "src/contracts/objectql-engine.ts#EngineTransactionOptions (interface)",
236238
"EngineUpdateOptions": "src/data/data-engine.zod.ts#EngineUpdateOptions (type)",
237239
"EngineUpdateOptionsSchema": "src/data/data-engine.zod.ts#EngineUpdateOptionsSchema (const)",
238240
"EqualityOperatorSchema": "src/data/filter.zod.ts#EqualityOperatorSchema (const)",
@@ -328,17 +330,26 @@
328330
"GroupByNode": "src/data/query.zod.ts#GroupByNode (type)",
329331
"GroupByNodeSchema": "src/data/query.zod.ts#GroupByNodeSchema (const)",
330332
"Hook": "src/data/hook.zod.ts#Hook (type)",
333+
"HookApi": "src/data/hook-api.ts#HookApi (interface)",
331334
"HookBody": "src/data/hook-body.zod.ts#HookBody (type)",
332335
"HookBodyCapability": "src/data/hook-body.zod.ts#HookBodyCapability (type)",
333336
"HookBodyParsed": "src/data/hook-body.zod.ts#HookBodyParsed (type)",
334337
"HookBodySchema": "src/data/hook-body.zod.ts#HookBodySchema (const)",
335338
"HookContext": "src/data/hook.zod.ts#HookContext (type)",
336339
"HookContextSchema": "src/data/hook.zod.ts#HookContextSchema (const)",
340+
"HookCountQuery": "src/data/hook-api.ts#HookCountQuery (type)",
341+
"HookDeleteOptions": "src/data/hook-api.ts#HookDeleteOptions (type)",
337342
"HookDispatch": "src/data/hook.zod.ts#HookDispatch (type)",
343+
"HookDoc": "src/data/hook-api.ts#HookDoc (type)",
344+
"HookDriverPassthroughOptions": "src/data/hook-api.ts#HookDriverPassthroughOptions (type)",
338345
"HookEvent": "src/data/hook.zod.ts#HookEvent (const)",
339346
"HookEventType": "src/data/hook.zod.ts#HookEventType (type)",
347+
"HookObjectApi": "src/data/hook-api.ts#HookObjectApi (interface)",
340348
"HookParsed": "src/data/hook.zod.ts#HookParsed (type)",
349+
"HookQuery": "src/data/hook-api.ts#HookQuery (type)",
341350
"HookSchema": "src/data/hook.zod.ts#HookSchema (const)",
351+
"HookUpdateDoc": "src/data/hook-api.ts#HookUpdateDoc (type)",
352+
"HookUpdateOptions": "src/data/hook-api.ts#HookUpdateOptions (type)",
342353
"IMPORT_BOOLEAN_FALSE_TOKENS": "src/data/import-coercion.ts#IMPORT_BOOLEAN_FALSE_TOKENS (const)",
343354
"IMPORT_BOOLEAN_TRUE_TOKENS": "src/data/import-coercion.ts#IMPORT_BOOLEAN_TRUE_TOKENS (const)",
344355
"IMPORT_REFERENCE_TYPES": "src/data/import-coercion.ts#IMPORT_REFERENCE_TYPES (const)",

0 commit comments

Comments
 (0)