@happyvertical/smrt-web 0.43.2 → 0.43.4

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.
package/dist/index.d.ts CHANGED
@@ -15,7 +15,7 @@ export declare function buildListQuery(params?: Record<string, unknown>): string
15
15
  * instead of resolving with them. Typed/legacy 4xx detail is retained; 5xx
16
16
  * failures stay opaque and payload-free.
17
17
  */
18
- export declare function createDefinitionFetchers(definition: SmrtWebCollectionDefinition<object>, basePath?: string, fetchFn?: typeof fetch): SmrtCrudFetchers;
18
+ export declare function createDefinitionFetchers(definition: Pick<SmrtWebCollectionDefinition<object>, 'name' | 'endpoint'>, basePath?: string, fetchFn?: typeof fetch): SmrtCrudFetchers;
19
19
 
20
20
  /**
21
21
  * Create a typed client collection over a generated SMRT collection definition
@@ -131,6 +131,14 @@ export declare function createSmrtWebClient(): SmrtWebClient;
131
131
  */
132
132
  export declare function createSmrtWebEventSubscriber(config: SmrtWebEventSubscriberConfig): SmrtWebEventSubscriber;
133
133
 
134
+ /**
135
+ * Create a query controller over one SMRT collection. Query rows stay in a
136
+ * separate keyed cache; the collection's full list is never loaded.
137
+ */
138
+ export declare function createSmrtWebQuery<TData extends object>(_collection: SmrtWebCollection<TData>, transport: SmrtWebQueryTransport, options?: {
139
+ staleTimeMs?: number;
140
+ }): SmrtWebQuery<TData>;
141
+
134
142
  /**
135
143
  * Create the framework-free `updateAvailable` primitive. Kicks off async
136
144
  * contract detection immediately (compare running vs. persisted manifest hash);
@@ -242,6 +250,17 @@ export declare function getEngineCollection<TData extends object>(handle: SmrtWe
242
250
  */
243
251
  export declare function getOutboxHandle(namespace: string): OutboxHandle | undefined;
244
252
 
253
+ /**
254
+ * Invalidate materialized collection caches through the opaque SMRT client.
255
+ *
256
+ * This is the public cache-coherence seam for transports that execute a write
257
+ * without constructing a {@link SmrtWebCollection} (for example, a tool-only
258
+ * WebMCP definition). Matching is by collection name across every scope on the
259
+ * shared client, mirroring settled collection mutations: over-invalidation is
260
+ * safe, while leaving a related page cache stale is not.
261
+ */
262
+ export declare function invalidateSmrtWebCollections(client: SmrtWebClient, collectionNames: readonly string[]): void;
263
+
245
264
  /**
246
265
  * A thin per-collection capability that subscribes THIS collection to live
247
266
  * signals for its `tableName`. On attach it registers `ctx.invalidate` (the
@@ -525,9 +544,9 @@ export declare function registerDurableResource(namespace: string, resource: Dur
525
544
  * @returns a disposer that deregisters all tools this call registered. On a
526
545
  * browser without WebMCP the call is a no-op and the disposer is inert.
527
546
  */
528
- export declare function registerWebMcpTools(definitions: SmrtWebCollectionDefinition[], options?: RegisterWebMcpToolsOptions): () => void;
547
+ export declare function registerWebMcpTools(definitions: readonly WebMcpRegistrationDefinition[], options?: RegisterWebMcpToolsOptions): WebMcpRegistrationDisposer;
529
548
 
530
- export declare interface RegisterWebMcpToolsOptions {
549
+ export declare interface RegisterWebMcpToolsOptions extends WebMcpExposurePolicy {
531
550
  /** REST base path for the fetchers (default `/api/v1`). */
532
551
  basePath?: string;
533
552
  /** Injectable fetch (tests / SSR-safe wrappers). */
@@ -542,8 +561,16 @@ export declare interface RegisterWebMcpToolsOptions {
542
561
  * without a live server.
543
562
  */
544
563
  resolveFetchers?: (definition: SmrtWebCollectionDefinition) => SmrtCrudFetchers;
564
+ /**
565
+ * Override direct REST fetchers for a canonical tool-only definition.
566
+ * Fetchers are optional because a get-only or custom-action-only model does
567
+ * not have a list or create route.
568
+ */
569
+ resolveToolFetchers?: (definition: WebMcpToolDefinition) => Partial<SmrtCrudFetchers>;
545
570
  /** Predicate to include/exclude individual tools (e.g. reads-only surfaces). */
546
571
  filter?: (definition: SmrtWebCollectionDefinition, descriptor: NonNullable<SmrtWebCollectionDefinition['toolDescriptors']>[number]) => boolean;
572
+ /** Predicate for canonical per-tool definitions. */
573
+ filterTool?: (definition: WebMcpToolDefinition) => boolean;
547
574
  }
548
575
 
549
576
  /**
@@ -1040,6 +1067,64 @@ export declare interface SmrtWebMutationEnvelope {
1040
1067
  readonly baseUpdatedAt?: string;
1041
1068
  }
1042
1069
 
1070
+ export declare interface SmrtWebQuery<TData extends object = object> {
1071
+ readonly state: SmrtWebQueryState<TData>;
1072
+ readonly request: SmrtWebDataQueryRequest | undefined;
1073
+ execute(request: SmrtWebDataQueryRequest, options?: SmrtWebQueryRunOptions): Promise<SmrtWebDataQueryResult>;
1074
+ refresh(options?: Omit<SmrtWebQueryRunOptions, 'mode' | 'force'>): Promise<SmrtWebDataQueryResult | undefined>;
1075
+ retry(): Promise<SmrtWebDataQueryResult | undefined>;
1076
+ subscribe(listener: (state: SmrtWebQueryState<TData>) => void): () => void;
1077
+ subscribeLive(): SmrtWebQueryLiveSubscription | undefined;
1078
+ invalidate(): void;
1079
+ dispose(): void;
1080
+ }
1081
+
1082
+ export declare interface SmrtWebQueryLiveSubscription {
1083
+ unsubscribe(): void;
1084
+ reconnect(): void;
1085
+ }
1086
+
1087
+ /** How a query run is allowed to affect the visible query state. */
1088
+ export declare type SmrtWebQueryMode = 'visible' | 'background' | 'prefetch' | 'silent';
1089
+
1090
+ export declare interface SmrtWebQueryPage {
1091
+ kind: 'offset' | 'cursor';
1092
+ limit: number;
1093
+ offset?: number;
1094
+ nextCursor?: string;
1095
+ hasMore: boolean;
1096
+ }
1097
+
1098
+ export declare interface SmrtWebQueryRunOptions {
1099
+ mode?: SmrtWebQueryMode;
1100
+ signal?: AbortSignal;
1101
+ /** Cancel this run after the given number of milliseconds. */
1102
+ deadlineMs?: number;
1103
+ /** Bypass the keyed cache and execute a fresh request (used by refresh). */
1104
+ force?: boolean;
1105
+ }
1106
+
1107
+ export declare interface SmrtWebQueryState<TData extends object = object> {
1108
+ readonly rows: ReadonlyArray<TData>;
1109
+ readonly page: SmrtWebQueryPage | undefined;
1110
+ readonly total: SmrtWebDataQueryResult['total'] | undefined;
1111
+ readonly loading: boolean;
1112
+ readonly refreshing: boolean;
1113
+ readonly stale: boolean;
1114
+ readonly error: unknown;
1115
+ readonly lastUpdated: number | undefined;
1116
+ readonly result: SmrtWebDataQueryResult | undefined;
1117
+ }
1118
+
1119
+ export declare interface SmrtWebQueryTransport extends SmrtWebDataQueryTransport {
1120
+ /** Subscribe to changes for this exact query, not the entire collection. */
1121
+ subscribe?(request: SmrtWebDataQueryRequest, onResult: (result: unknown) => void, options?: {
1122
+ signal?: AbortSignal;
1123
+ }): SmrtWebQueryLiveSubscription | {
1124
+ unsubscribe(): void;
1125
+ };
1126
+ }
1127
+
1043
1128
  /**
1044
1129
  * A manifest-derived edge from this collection to a sibling REST collection,
1045
1130
  * emitted by the `@happyvertical/smrt-virt-web` virtual module. When a mutation
@@ -1132,6 +1217,9 @@ export declare interface SyncStateEvent {
1132
1217
  error?: string;
1133
1218
  }
1134
1219
 
1220
+ /** Reject generated REST error envelopes while preserving opaque successes. */
1221
+ export declare function throwIfSmrtWebError(result: unknown, context: string): unknown;
1222
+
1135
1223
  /**
1136
1224
  * Normalize a generated-client item result (create/update) to a row.
1137
1225
  * `{ error }` payloads become failures — inside mutation handlers this is what
@@ -1213,6 +1301,52 @@ export declare interface UpdateStateConfig {
1213
1301
  namespace: DurableStoreKey;
1214
1302
  }
1215
1303
 
1304
+ /** Validate that an opaque cache handle came from {@link createSmrtWebClient}. */
1305
+ export declare function validateSmrtWebClient(client: SmrtWebClient): void;
1306
+
1307
+ export declare interface WebMcpExposurePolicy {
1308
+ /** Allowed effects. Omitted means read-only exposure. */
1309
+ effects?: readonly WebMcpToolEffect[];
1310
+ /** Prefix every registered tool name with `<namespace>_`. */
1311
+ namespace?: string;
1312
+ /** Optional maximum tools registered by one call. */
1313
+ maxTools?: number;
1314
+ }
1315
+
1316
+ /** Accepted legacy collection definitions and canonical per-tool definitions. */
1317
+ export declare type WebMcpRegistrationDefinition = SmrtWebCollectionDefinition | WebMcpToolDefinition;
1318
+
1319
+ /** Disposes a registration and exposes completion of browser registration. */
1320
+ export declare interface WebMcpRegistrationDisposer {
1321
+ (): void;
1322
+ /** Rejects if the browser rejects any tool; all sibling tools are aborted. */
1323
+ readonly ready: Promise<void>;
1324
+ }
1325
+
1326
+ /**
1327
+ * Canonical data-only definition for one API-backed browser tool. Unlike a
1328
+ * collection definition, this does not imply that a list route or client cache
1329
+ * exists. Generated definitions carry explicit semantics; manual legacy
1330
+ * literals may omit them and register with fail-closed defaults.
1331
+ */
1332
+ export declare interface WebMcpToolDefinition extends WebToolDescriptor {
1333
+ /** Stable definition identity is `(collection, action)`. */
1334
+ collection: string;
1335
+ /** Canonical qualified row-model identity. */
1336
+ objectRef: string;
1337
+ /** Row-model class used by the shared MCP tool vocabulary. */
1338
+ className: string;
1339
+ endpoint: string;
1340
+ idField: string;
1341
+ idType: 'uuid' | 'text';
1342
+ /** Complete generated route metadata, including CRUD actions. */
1343
+ route: SmrtWebToolRouteDescriptor;
1344
+ /** Cache-invalidation edges for materialized sibling collections. */
1345
+ relationships: SmrtWebRelationship[];
1346
+ }
1347
+
1348
+ export declare type WebMcpToolEffect = 'read' | 'write' | 'destructive';
1349
+
1216
1350
  /**
1217
1351
  * One generated collection definition: everything needed to construct a client
1218
1352
  * collection over the generated REST surface. The `_row` property is a phantom
@@ -1236,6 +1370,12 @@ export declare interface WebToolDescriptor {
1236
1370
  inputSchema: Record<string, unknown>;
1237
1371
  /** True for non-mutating reads → WebMCP `annotations.readOnlyHint`. */
1238
1372
  readOnly: boolean;
1373
+ /** Capability effect used by WebMCP exposure policy. */
1374
+ effect?: 'read' | 'write' | 'destructive';
1375
+ /** Whether repeating the tool with the same arguments is safe. */
1376
+ idempotent?: boolean;
1377
+ /** Whether the tool may interact outside the SMRT application. */
1378
+ openWorld?: boolean;
1239
1379
  /** Generated custom-route transport metadata. */
1240
1380
  route?: SmrtWebToolRouteDescriptor;
1241
1381
  }
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { A as executeSmrtWebDataQuery, C as MAX_SMRT_WEB_DATA_QUERY_FACET_VALUES, D as MAX_SMRT_WEB_DATA_QUERY_ROWS, E as MAX_SMRT_WEB_DATA_QUERY_RESULT_BYTES, M as runWrapMutation, O as MAX_SMRT_WEB_DATA_QUERY_STRING_LENGTH, S as MAX_SMRT_WEB_DATA_QUERY_FACETS, T as MAX_SMRT_WEB_DATA_QUERY_PAGE_LIMIT, _ as offlineOutbox, a as createSmrtWebClient, b as wipeDurableStore, c as unwrapItemResult, d as createUpdateState, f as createSmrtWebEventSubscriber, g as getOutboxHandle, h as persistCollection, i as createSmrtCollection, j as normalizeSmrtWebDataQueryResult, k as MAX_SMRT_WEB_DATA_QUERY_WARNINGS, l as unwrapListResult, m as DEFAULT_PERSIST_DEBOUNCE_MS, n as buildListQuery, o as getEngineCollection, p as liveInvalidation, r as createDefinitionFetchers, s as newLocalId, t as SmrtWebRequestError, u as registerWebMcpTools, v as durableStoreNamespace, w as MAX_SMRT_WEB_DATA_QUERY_OFFSET, x as MAX_SMRT_WEB_DATA_QUERY_CONTAINER_ITEMS, y as registerDurableResource } from "./chunks/src-CDdW9uYx.js";
2
- export { DEFAULT_PERSIST_DEBOUNCE_MS, MAX_SMRT_WEB_DATA_QUERY_CONTAINER_ITEMS, MAX_SMRT_WEB_DATA_QUERY_FACETS, MAX_SMRT_WEB_DATA_QUERY_FACET_VALUES, MAX_SMRT_WEB_DATA_QUERY_OFFSET, MAX_SMRT_WEB_DATA_QUERY_PAGE_LIMIT, MAX_SMRT_WEB_DATA_QUERY_RESULT_BYTES, MAX_SMRT_WEB_DATA_QUERY_ROWS, MAX_SMRT_WEB_DATA_QUERY_STRING_LENGTH, MAX_SMRT_WEB_DATA_QUERY_WARNINGS, SmrtWebRequestError, buildListQuery, createDefinitionFetchers, createSmrtCollection, createSmrtWebClient, createSmrtWebEventSubscriber, createUpdateState, durableStoreNamespace, executeSmrtWebDataQuery, getEngineCollection, getOutboxHandle, liveInvalidation, newLocalId, normalizeSmrtWebDataQueryResult, offlineOutbox, persistCollection, registerDurableResource, registerWebMcpTools, runWrapMutation, unwrapItemResult, unwrapListResult, wipeDurableStore };
1
+ import { A as MAX_SMRT_WEB_DATA_QUERY_RESULT_BYTES, C as registerDurableResource, D as MAX_SMRT_WEB_DATA_QUERY_FACET_VALUES, E as MAX_SMRT_WEB_DATA_QUERY_FACETS, F as normalizeSmrtWebDataQueryResult, I as runWrapMutation, M as MAX_SMRT_WEB_DATA_QUERY_STRING_LENGTH, N as MAX_SMRT_WEB_DATA_QUERY_WARNINGS, O as MAX_SMRT_WEB_DATA_QUERY_OFFSET, P as executeSmrtWebDataQuery, S as durableStoreNamespace, T as MAX_SMRT_WEB_DATA_QUERY_CONTAINER_ITEMS, _ as createSmrtWebQuery, a as createSmrtWebClient, b as getOutboxHandle, c as newLocalId, d as unwrapListResult, f as validateSmrtWebClient, g as liveInvalidation, h as createSmrtWebEventSubscriber, i as createSmrtCollection, j as MAX_SMRT_WEB_DATA_QUERY_ROWS, k as MAX_SMRT_WEB_DATA_QUERY_PAGE_LIMIT, l as throwIfSmrtWebError, m as createUpdateState, n as buildListQuery, o as getEngineCollection, p as registerWebMcpTools, r as createDefinitionFetchers, s as invalidateSmrtWebCollections, t as SmrtWebRequestError, u as unwrapItemResult, v as DEFAULT_PERSIST_DEBOUNCE_MS, w as wipeDurableStore, x as offlineOutbox, y as persistCollection } from "./chunks/src-n14q6RHC.js";
2
+ export { DEFAULT_PERSIST_DEBOUNCE_MS, MAX_SMRT_WEB_DATA_QUERY_CONTAINER_ITEMS, MAX_SMRT_WEB_DATA_QUERY_FACETS, MAX_SMRT_WEB_DATA_QUERY_FACET_VALUES, MAX_SMRT_WEB_DATA_QUERY_OFFSET, MAX_SMRT_WEB_DATA_QUERY_PAGE_LIMIT, MAX_SMRT_WEB_DATA_QUERY_RESULT_BYTES, MAX_SMRT_WEB_DATA_QUERY_ROWS, MAX_SMRT_WEB_DATA_QUERY_STRING_LENGTH, MAX_SMRT_WEB_DATA_QUERY_WARNINGS, SmrtWebRequestError, buildListQuery, createDefinitionFetchers, createSmrtCollection, createSmrtWebClient, createSmrtWebEventSubscriber, createSmrtWebQuery, createUpdateState, durableStoreNamespace, executeSmrtWebDataQuery, getEngineCollection, getOutboxHandle, invalidateSmrtWebCollections, liveInvalidation, newLocalId, normalizeSmrtWebDataQueryResult, offlineOutbox, persistCollection, registerDurableResource, registerWebMcpTools, runWrapMutation, throwIfSmrtWebError, unwrapItemResult, unwrapListResult, validateSmrtWebClient, wipeDurableStore };
package/dist/webmcp.d.ts CHANGED
@@ -4,9 +4,9 @@
4
4
  * @returns a disposer that deregisters all tools this call registered. On a
5
5
  * browser without WebMCP the call is a no-op and the disposer is inert.
6
6
  */
7
- export declare function registerWebMcpTools(definitions: SmrtWebCollectionDefinition[], options?: RegisterWebMcpToolsOptions): () => void;
7
+ export declare function registerWebMcpTools(definitions: readonly WebMcpRegistrationDefinition[], options?: RegisterWebMcpToolsOptions): WebMcpRegistrationDisposer;
8
8
 
9
- export declare interface RegisterWebMcpToolsOptions {
9
+ export declare interface RegisterWebMcpToolsOptions extends WebMcpExposurePolicy {
10
10
  /** REST base path for the fetchers (default `/api/v1`). */
11
11
  basePath?: string;
12
12
  /** Injectable fetch (tests / SSR-safe wrappers). */
@@ -21,8 +21,16 @@ export declare interface RegisterWebMcpToolsOptions {
21
21
  * without a live server.
22
22
  */
23
23
  resolveFetchers?: (definition: SmrtWebCollectionDefinition) => SmrtCrudFetchers;
24
+ /**
25
+ * Override direct REST fetchers for a canonical tool-only definition.
26
+ * Fetchers are optional because a get-only or custom-action-only model does
27
+ * not have a list or create route.
28
+ */
29
+ resolveToolFetchers?: (definition: WebMcpToolDefinition) => Partial<SmrtCrudFetchers>;
24
30
  /** Predicate to include/exclude individual tools (e.g. reads-only surfaces). */
25
31
  filter?: (definition: SmrtWebCollectionDefinition, descriptor: NonNullable<SmrtWebCollectionDefinition['toolDescriptors']>[number]) => boolean;
32
+ /** Predicate for canonical per-tool definitions. */
33
+ filterTool?: (definition: WebMcpToolDefinition) => boolean;
26
34
  }
27
35
 
28
36
  /**
@@ -162,6 +170,49 @@ declare interface SmrtWebToolRouteDescriptor {
162
170
  optionsBag?: boolean;
163
171
  }
164
172
 
173
+ export declare interface WebMcpExposurePolicy {
174
+ /** Allowed effects. Omitted means read-only exposure. */
175
+ effects?: readonly WebMcpToolEffect[];
176
+ /** Prefix every registered tool name with `<namespace>_`. */
177
+ namespace?: string;
178
+ /** Optional maximum tools registered by one call. */
179
+ maxTools?: number;
180
+ }
181
+
182
+ /** Accepted legacy collection definitions and canonical per-tool definitions. */
183
+ export declare type WebMcpRegistrationDefinition = SmrtWebCollectionDefinition | WebMcpToolDefinition;
184
+
185
+ /** Disposes a registration and exposes completion of browser registration. */
186
+ export declare interface WebMcpRegistrationDisposer {
187
+ (): void;
188
+ /** Rejects if the browser rejects any tool; all sibling tools are aborted. */
189
+ readonly ready: Promise<void>;
190
+ }
191
+
192
+ /**
193
+ * Canonical data-only definition for one API-backed browser tool. Unlike a
194
+ * collection definition, this does not imply that a list route or client cache
195
+ * exists. Generated definitions carry explicit semantics; manual legacy
196
+ * literals may omit them and register with fail-closed defaults.
197
+ */
198
+ declare interface WebMcpToolDefinition extends WebToolDescriptor {
199
+ /** Stable definition identity is `(collection, action)`. */
200
+ collection: string;
201
+ /** Canonical qualified row-model identity. */
202
+ objectRef: string;
203
+ /** Row-model class used by the shared MCP tool vocabulary. */
204
+ className: string;
205
+ endpoint: string;
206
+ idField: string;
207
+ idType: 'uuid' | 'text';
208
+ /** Complete generated route metadata, including CRUD actions. */
209
+ route: SmrtWebToolRouteDescriptor;
210
+ /** Cache-invalidation edges for materialized sibling collections. */
211
+ relationships: SmrtWebRelationship[];
212
+ }
213
+
214
+ export declare type WebMcpToolEffect = 'read' | 'write' | 'destructive';
215
+
165
216
  /**
166
217
  * One generated collection definition: everything needed to construct a client
167
218
  * collection over the generated REST surface. The `_row` property is a phantom
@@ -185,6 +236,12 @@ declare interface WebToolDescriptor {
185
236
  inputSchema: Record<string, unknown>;
186
237
  /** True for non-mutating reads → WebMCP `annotations.readOnlyHint`. */
187
238
  readOnly: boolean;
239
+ /** Capability effect used by WebMCP exposure policy. */
240
+ effect?: 'read' | 'write' | 'destructive';
241
+ /** Whether repeating the tool with the same arguments is safe. */
242
+ idempotent?: boolean;
243
+ /** Whether the tool may interact outside the SMRT application. */
244
+ openWorld?: boolean;
188
245
  /** Generated custom-route transport metadata. */
189
246
  route?: SmrtWebToolRouteDescriptor;
190
247
  }
package/dist/webmcp.js CHANGED
@@ -1,2 +1,2 @@
1
- import { u as registerWebMcpTools } from "./chunks/src-CDdW9uYx.js";
1
+ import { p as registerWebMcpTools } from "./chunks/src-n14q6RHC.js";
2
2
  export { registerWebMcpTools };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-web",
3
- "version": "0.43.2",
3
+ "version": "0.43.4",
4
4
  "description": "SMRT browser client data runtime: typed collection factory wrapping the client-data engine over generated REST clients",
5
5
  "author": "HappyVertical",
6
6
  "type": "module",