@happyvertical/smrt-web 0.51.32 → 0.51.34
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/__typechecks__/webmcp-tool-definition.d.ts +2 -0
- package/dist/__typechecks__/webmcp-tool-definition.d.ts.map +1 -0
- package/dist/ai.d.ts +330 -358
- package/dist/ai.d.ts.map +1 -0
- package/dist/capability-classification.d.ts +89 -0
- package/dist/capability-classification.d.ts.map +1 -0
- package/dist/capability.d.ts +191 -0
- package/dist/capability.d.ts.map +1 -0
- package/dist/data-query.d.ts +121 -0
- package/dist/data-query.d.ts.map +1 -0
- package/dist/data-surface-actions.d.ts +118 -0
- package/dist/data-surface-actions.d.ts.map +1 -0
- package/dist/durable-store.d.ts +88 -0
- package/dist/durable-store.d.ts.map +1 -0
- package/dist/index.d.ts +468 -2245
- package/dist/index.d.ts.map +1 -0
- package/dist/intents.d.ts +273 -300
- package/dist/intents.d.ts.map +1 -0
- package/dist/internal.d.ts +15 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/offline/durable-queue.d.ts +171 -0
- package/dist/offline/durable-queue.d.ts.map +1 -0
- package/dist/offline/engine.d.ts +359 -0
- package/dist/offline/engine.d.ts.map +1 -0
- package/dist/offline/leader.d.ts +57 -0
- package/dist/offline/leader.d.ts.map +1 -0
- package/dist/offline/types.d.ts +232 -0
- package/dist/offline/types.d.ts.map +1 -0
- package/dist/offline.d.ts +258 -0
- package/dist/offline.d.ts.map +1 -0
- package/dist/persistence/snapshot-store.d.ts +121 -0
- package/dist/persistence/snapshot-store.d.ts.map +1 -0
- package/dist/persistence.d.ts +157 -0
- package/dist/persistence.d.ts.map +1 -0
- package/dist/remote-query.d.ts +61 -0
- package/dist/remote-query.d.ts.map +1 -0
- package/dist/sse-client.d.ts +182 -0
- package/dist/sse-client.d.ts.map +1 -0
- package/dist/update-state/meta-store.d.ts +66 -0
- package/dist/update-state/meta-store.d.ts.map +1 -0
- package/dist/update-state.d.ts +115 -0
- package/dist/update-state.d.ts.map +1 -0
- package/dist/webmcp-tool-names.d.ts +106 -112
- package/dist/webmcp-tool-names.d.ts.map +1 -0
- package/dist/webmcp.d.ts +193 -653
- package/dist/webmcp.d.ts.map +1 -0
- package/package.json +4 -4
package/dist/ai.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one capability classification rule this package applies, extracted so
|
|
3
|
+
* every declaration site in smrt-web shares a single implementation (#2587,
|
|
4
|
+
* #2588).
|
|
5
|
+
*
|
|
6
|
+
* Two sites consume it today: `webmcp.ts` (canonical definitions trusted
|
|
7
|
+
* through it directly, and its legacy CRUD switch's fail-closed default
|
|
8
|
+
* branch) and `intents.ts` (a declared view intent, which is never a CRUD
|
|
9
|
+
* verb and so resolves through the declaration rule alone). Keeping the rule
|
|
10
|
+
* here rather than private to `webmcp.ts` is what lets the intent path be a
|
|
11
|
+
* dependency-free module that never pulls the client-data engine.
|
|
12
|
+
*
|
|
13
|
+
* This module structurally mirrors `CapabilityEffect` / `CapabilityDeclaration`
|
|
14
|
+
* / `CapabilityClassification` in `@happyvertical/smrt-types` rather than
|
|
15
|
+
* importing them — this package's dependency-DAG guardrails keep it free of
|
|
16
|
+
* every `@happyvertical/*` dependency (see AGENTS.md "No inter-smrt
|
|
17
|
+
* dependencies"), the same reason `data-query.ts` mirrors that package's
|
|
18
|
+
* bounded query envelope structurally instead of importing it.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Browser/agent-visible effect classification for a capability. `'read'`
|
|
22
|
+
* never mutates; `'write'` mutates within the application; `'destructive'`
|
|
23
|
+
* may remove or irreversibly change data.
|
|
24
|
+
*/
|
|
25
|
+
export type WebMcpToolEffect = 'read' | 'write' | 'destructive';
|
|
26
|
+
/** Every valid {@link WebMcpToolEffect}, in exposure-breadth order. */
|
|
27
|
+
export declare const WEBMCP_TOOL_EFFECTS: readonly WebMcpToolEffect[];
|
|
28
|
+
/**
|
|
29
|
+
* An author-supplied, partial classification. Any omitted field resolves
|
|
30
|
+
* through the fail-closed rule on {@link resolveDeclaredCapability}, never
|
|
31
|
+
* through a CRUD- or name-based guess.
|
|
32
|
+
*/
|
|
33
|
+
export interface WebMcpCapabilityDeclaration {
|
|
34
|
+
effect?: WebMcpToolEffect;
|
|
35
|
+
idempotent?: boolean;
|
|
36
|
+
openWorld?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/** A fully resolved classification. */
|
|
39
|
+
export interface WebMcpCapabilityClassification {
|
|
40
|
+
effect: WebMcpToolEffect;
|
|
41
|
+
/**
|
|
42
|
+
* Derived, never declared: every non-read effect is annotated destructive
|
|
43
|
+
* to the browser, so a `write` capability cannot claim the MCP
|
|
44
|
+
* additive-only guarantee.
|
|
45
|
+
*/
|
|
46
|
+
destructive: boolean;
|
|
47
|
+
idempotent: boolean;
|
|
48
|
+
openWorld: boolean;
|
|
49
|
+
}
|
|
50
|
+
/** The MCP-shaped annotation set a resolved classification emits. */
|
|
51
|
+
export interface WebMcpCapabilityAnnotations {
|
|
52
|
+
readOnlyHint: boolean;
|
|
53
|
+
destructiveHint: boolean;
|
|
54
|
+
idempotentHint: boolean;
|
|
55
|
+
openWorldHint: boolean;
|
|
56
|
+
untrustedContentHint: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve a declared capability with no CRUD/action-based guess — the shared
|
|
60
|
+
* fail-closed default documented on `CapabilityClassification` in
|
|
61
|
+
* `@happyvertical/smrt-types` (#2587): an omitted or invalid `effect`
|
|
62
|
+
* resolves to `'destructive'`, an omitted `idempotent` to `false`, an
|
|
63
|
+
* omitted `openWorld` to `true`. Each field defaults independently: a
|
|
64
|
+
* declared `effect: 'read'` does NOT imply `idempotent: true`.
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveDeclaredCapability(declared: WebMcpCapabilityDeclaration): WebMcpCapabilityClassification;
|
|
67
|
+
/**
|
|
68
|
+
* The browser annotations a resolved classification is finally registered
|
|
69
|
+
* with. `destructiveHint` carries the DERIVED `destructive` flag, so a
|
|
70
|
+
* `write` capability is annotated destructive exactly like a generated
|
|
71
|
+
* custom model action declared `effect: 'write'`.
|
|
72
|
+
*/
|
|
73
|
+
export declare function capabilityAnnotations(classification: WebMcpCapabilityClassification): WebMcpCapabilityAnnotations;
|
|
74
|
+
/**
|
|
75
|
+
* Encode a resolved classification as the INPUT hints
|
|
76
|
+
* `registerWebMcpBespokeTool` decodes (`bespokeDeclaredSemantics`), so a
|
|
77
|
+
* capability resolved here survives that registrar's own re-resolution
|
|
78
|
+
* unchanged.
|
|
79
|
+
*
|
|
80
|
+
* This is deliberately NOT {@link capabilityAnnotations}. That function emits
|
|
81
|
+
* the derived `destructive` flag, and `destructiveHint: true` is the first
|
|
82
|
+
* check the registrar makes — round-tripping it would silently upgrade every
|
|
83
|
+
* `write` capability to `destructive`. On the input side `destructiveHint`
|
|
84
|
+
* means "the author declared the destructive EFFECT", and `false` selects the
|
|
85
|
+
* `write` bucket; the registrar re-emits it as `true` on its way to the
|
|
86
|
+
* browser.
|
|
87
|
+
*/
|
|
88
|
+
export declare function capabilityDeclarationHints(classification: WebMcpCapabilityClassification): WebMcpCapabilityAnnotations;
|
|
89
|
+
//# sourceMappingURL=capability-classification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-classification.d.ts","sourceRoot":"","sources":["../src/capability-classification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;AAEhE,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,EAAE,SAAS,gBAAgB,EAI1D,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,uCAAuC;AACvC,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,gBAAgB,CAAC;IACzB;;;;OAIG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,qEAAqE;AACrE,MAAM,WAAW,2BAA2B;IAC1C,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,2BAA2B,GACpC,8BAA8B,CAYhC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,8BAA8B,GAC7C,2BAA2B,CAQ7B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,8BAA8B,GAC7C,2BAA2B,CAQ7B"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @happyvertical/smrt-web — capability extension seam (#1755).
|
|
3
|
+
*
|
|
4
|
+
* A capability is a small plug-in that hooks the {@link createSmrtCollection}
|
|
5
|
+
* lifecycle so a follow-on client slice — the offline outbox (#1762),
|
|
6
|
+
* persistence (#1764), or live SSE invalidation (#1763-client) — can live in
|
|
7
|
+
* its OWN module instead of contending on `index.ts`. The factory runs the six
|
|
8
|
+
* hooks below at fixed points; a collection with no capabilities is
|
|
9
|
+
* byte-for-byte the collection of today (the no-op guarantee).
|
|
10
|
+
*
|
|
11
|
+
* ## The engine boundary is sacred
|
|
12
|
+
*
|
|
13
|
+
* Every type here is expressed ENTIRELY in existing SMRT-owned terms
|
|
14
|
+
* (`SmrtWebCollectionDefinition`, `SmrtCrudFetchers`, `SmrtWebRow`, plain TS).
|
|
15
|
+
* No `@tanstack/*` type — no `QueryClient`, no engine `Collection` — appears on
|
|
16
|
+
* the capability surface, so the build's `.d.ts` boundary check stays green and
|
|
17
|
+
* the engine stays swappable. A capability that genuinely needs deeper engine
|
|
18
|
+
* access reaches it through the existing `getEngineCollection()` unknown-bridge
|
|
19
|
+
* from inside its own module — NEVER by widening these types.
|
|
20
|
+
*
|
|
21
|
+
* These types intentionally import nothing from `./index.ts` beyond the
|
|
22
|
+
* SMRT-owned contracts they name, so the seam is reviewable and unit-testable on
|
|
23
|
+
* its own (see {@link runWrapMutation}).
|
|
24
|
+
*/
|
|
25
|
+
import type { SmrtCrudFetchers, SmrtWebCollectionDefinition, SmrtWebRow, SmrtWebSubscription } from './index.js';
|
|
26
|
+
/**
|
|
27
|
+
* The context every capability hook receives — a stable, engine-free view of
|
|
28
|
+
* the collection being built. All fields are the exact values the factory uses
|
|
29
|
+
* internally (the resolved cache key/id, the same fetchers), so a capability
|
|
30
|
+
* keys its own storage or subscriptions off the identical discriminators.
|
|
31
|
+
*/
|
|
32
|
+
export interface SmrtWebCapabilityContext<TData extends object = object> {
|
|
33
|
+
/** The generated definition this collection materializes. */
|
|
34
|
+
readonly definition: SmrtWebCollectionDefinition<TData>;
|
|
35
|
+
/** The CRUD fetchers the collection persists through. */
|
|
36
|
+
readonly fetchers: SmrtCrudFetchers;
|
|
37
|
+
/**
|
|
38
|
+
* The `queryKey` segments the collection's reads use — a LIVE view: from
|
|
39
|
+
* `onAttach`/`warmStart` onward it is the final key (including every
|
|
40
|
+
* capability-contributed segment); read during `contributeCacheKey` it omits
|
|
41
|
+
* that capability's own not-yet-applied segment. Treat as read-only.
|
|
42
|
+
*/
|
|
43
|
+
readonly cacheKey: readonly string[];
|
|
44
|
+
/** The engine-collection id string (mirrors {@link cacheKey}). */
|
|
45
|
+
readonly cacheId: string;
|
|
46
|
+
/**
|
|
47
|
+
* Enter the SAME relationship-derived invalidation the factory runs after a
|
|
48
|
+
* settled mutation. A capability calls this to refetch this collection and its
|
|
49
|
+
* manifest-related collections in response to an EXTERNAL trigger (e.g. an SSE
|
|
50
|
+
* message) without reaching into the engine.
|
|
51
|
+
*/
|
|
52
|
+
invalidate(): void;
|
|
53
|
+
/**
|
|
54
|
+
* A snapshot of the collection's current rows as plain public DTOs — the same
|
|
55
|
+
* projection as {@link SmrtWebCollection.toArray}, so the engine's virtual
|
|
56
|
+
* props never cross the boundary. The persistence slice (#1764) reads this in
|
|
57
|
+
* its write-back to serialize the current cache to disk. Populated by the real
|
|
58
|
+
* factory; a hand-built test context may omit it, so callers guard for its
|
|
59
|
+
* presence.
|
|
60
|
+
*
|
|
61
|
+
* SAFE ONLY FROM `onAttach` ONWARD. The factory's implementation closes over
|
|
62
|
+
* the engine collection, which is constructed AFTER `contributeCacheKey` and
|
|
63
|
+
* `warmStart` run — calling this from those earlier hooks would throw
|
|
64
|
+
* (temporal-dead-zone). Read rows from `onAttach`, `onSettled`, or an external
|
|
65
|
+
* trigger, never during construction.
|
|
66
|
+
*/
|
|
67
|
+
snapshot?(): ReadonlyArray<SmrtWebRow<TData>>;
|
|
68
|
+
/**
|
|
69
|
+
* Subscribe to the collection's change notifications — the same stream as
|
|
70
|
+
* {@link SmrtWebCollection.subscribeChanges} (plain-DTO payloads). The
|
|
71
|
+
* persistence slice (#1764) wires its debounced write-back here in `onAttach`
|
|
72
|
+
* and detaches in `teardown`. Engine-free by construction: the payload is
|
|
73
|
+
* `unknown` (the capability only needs the change SIGNAL, then re-reads via
|
|
74
|
+
* {@link snapshot}), so no engine type crosses the seam. Populated by the real
|
|
75
|
+
* factory; a hand-built test context may omit it.
|
|
76
|
+
*
|
|
77
|
+
* SAFE ONLY FROM `onAttach` ONWARD (same reason as {@link snapshot}): it closes
|
|
78
|
+
* over the engine collection built after the pre-construction hooks.
|
|
79
|
+
*/
|
|
80
|
+
subscribe?(callback: (changes: unknown) => void): SmrtWebSubscription;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* A single mutation described in SMRT-owned terms — handed to
|
|
84
|
+
* {@link SmrtWebCapability.wrapMutation} and {@link SmrtWebCapability.onSettled}
|
|
85
|
+
* so a capability can inspect or intercept a write without touching the engine's
|
|
86
|
+
* transaction type.
|
|
87
|
+
*/
|
|
88
|
+
export interface SmrtWebMutationEnvelope {
|
|
89
|
+
/** Which mutation kind this describes. */
|
|
90
|
+
readonly kind: 'insert' | 'update' | 'delete';
|
|
91
|
+
/** The row key: the client-local id on insert, else the target row's id. */
|
|
92
|
+
readonly key: string;
|
|
93
|
+
/**
|
|
94
|
+
* The write payload: the full row on insert, the changed fields on update,
|
|
95
|
+
* and an empty object on delete (the key carries the target).
|
|
96
|
+
*/
|
|
97
|
+
readonly data: Record<string, unknown>;
|
|
98
|
+
/**
|
|
99
|
+
* The server `updated_at` / `updatedAt` value the mutation is based on, when
|
|
100
|
+
* known. Update/delete handlers capture this from the original row so offline
|
|
101
|
+
* replay can preserve the sync/apply conflict guard even when the write
|
|
102
|
+
* payload only carries changed fields (or no fields for delete).
|
|
103
|
+
*/
|
|
104
|
+
readonly baseUpdatedAt?: string;
|
|
105
|
+
}
|
|
106
|
+
/** The outcome handed to {@link SmrtWebCapability.wrapMutation}. */
|
|
107
|
+
export type WrapMutationOutcome = {
|
|
108
|
+
handled: true;
|
|
109
|
+
result: unknown;
|
|
110
|
+
} | {
|
|
111
|
+
handled: false;
|
|
112
|
+
} | undefined;
|
|
113
|
+
/** The settle outcome handed to {@link SmrtWebCapability.onSettled}. */
|
|
114
|
+
export type MutationSettleOutcome = {
|
|
115
|
+
ok: true;
|
|
116
|
+
result: unknown;
|
|
117
|
+
} | {
|
|
118
|
+
ok: false;
|
|
119
|
+
error: unknown;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* A capability plugged into {@link createSmrtCollection}. Every hook is
|
|
123
|
+
* optional; a capability implements only the points its slice needs. Hooks fire
|
|
124
|
+
* in these fixed places, and capabilities run in ARRAY ORDER:
|
|
125
|
+
*
|
|
126
|
+
* - `contributeCacheKey` — ONCE, before the engine collection is constructed.
|
|
127
|
+
* - `warmStart` — ONCE, before the first read (seeds the cache).
|
|
128
|
+
* - `wrapMutation` — per mutation, BEFORE the fetcher, with a chance to handle
|
|
129
|
+
* the write itself (offline).
|
|
130
|
+
* - `onSettled` — per mutation, AFTER it settles (success AND fetcher-throw).
|
|
131
|
+
* - `onAttach` — ONCE, right after the engine collection is constructed; the
|
|
132
|
+
* ONLY place a capability registers an external (non-mutation) trigger such as
|
|
133
|
+
* an SSE subscription.
|
|
134
|
+
* - `teardown` — in `cleanup()`, after the engine's own cleanup.
|
|
135
|
+
*/
|
|
136
|
+
export interface SmrtWebCapability<TData extends object = object> {
|
|
137
|
+
/** Diagnostic name (e.g. `'offline-outbox'`). */
|
|
138
|
+
readonly name: string;
|
|
139
|
+
/**
|
|
140
|
+
* Contribute extra cache-key segments so this capability can partition the
|
|
141
|
+
* collection's cache (e.g. an outbox variant). Runs ONCE, before construction;
|
|
142
|
+
* returned segments are appended to the collection's cache key/id. Return
|
|
143
|
+
* `undefined` (or omit) to contribute nothing.
|
|
144
|
+
*/
|
|
145
|
+
contributeCacheKey?(ctx: SmrtWebCapabilityContext<TData>): string[] | undefined;
|
|
146
|
+
/**
|
|
147
|
+
* Provide rows to seed the cache before the first read — the persistence
|
|
148
|
+
* slice's rehydrate-from-disk path. Runs ONCE, before construction. NOTE:
|
|
149
|
+
* caller-supplied `initialData` (fresher same-request SSR truth) WINS over any
|
|
150
|
+
* capability `warmStart`. Return `undefined` to contribute no seed.
|
|
151
|
+
*/
|
|
152
|
+
warmStart?(ctx: SmrtWebCapabilityContext<TData>): Promise<SmrtWebRow<TData>[] | undefined> | SmrtWebRow<TData>[] | undefined;
|
|
153
|
+
/**
|
|
154
|
+
* Intercept a mutation BEFORE its fetcher runs. Return `{ handled: true,
|
|
155
|
+
* result }` to take over the write (the fetcher is skipped and `result`
|
|
156
|
+
* reconciles the optimistic row — the offline path); return `{ handled: false
|
|
157
|
+
* }` or `undefined` to fall through to the real fetcher. With multiple
|
|
158
|
+
* capabilities the FIRST `{ handled: true }` wins and later capabilities'
|
|
159
|
+
* `wrapMutation` are skipped.
|
|
160
|
+
*/
|
|
161
|
+
wrapMutation?(envelope: SmrtWebMutationEnvelope, ctx: SmrtWebCapabilityContext<TData>): Promise<WrapMutationOutcome> | WrapMutationOutcome;
|
|
162
|
+
/**
|
|
163
|
+
* Observe a mutation after it settles — on BOTH a successful persist and a
|
|
164
|
+
* fetcher throw (before the optimistic rollback propagates). Never swallows
|
|
165
|
+
* the error: a thrown fetcher error still rolls the transaction back.
|
|
166
|
+
*/
|
|
167
|
+
onSettled?(envelope: SmrtWebMutationEnvelope, outcome: MutationSettleOutcome, ctx: SmrtWebCapabilityContext<TData>): void;
|
|
168
|
+
/**
|
|
169
|
+
* Run ONCE, right after the engine collection is constructed. The ONLY hook
|
|
170
|
+
* where a capability wires an external trigger (SSE subscription, focus
|
|
171
|
+
* listener) — `ctx.invalidate()` is callable here.
|
|
172
|
+
*/
|
|
173
|
+
onAttach?(ctx: SmrtWebCapabilityContext<TData>): void;
|
|
174
|
+
/** Run inside `cleanup()`, AFTER the engine's own cleanup. Awaited if async. */
|
|
175
|
+
teardown?(ctx: SmrtWebCapabilityContext<TData>): void | Promise<void>;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Run the `wrapMutation` hook across `capabilities` in array order for one
|
|
179
|
+
* mutation, short-circuiting on the FIRST capability that returns `{ handled:
|
|
180
|
+
* true }` (later capabilities' `wrapMutation` are then skipped). A capability
|
|
181
|
+
* that returns `{ handled: false }`, `undefined`, or omits the hook declines,
|
|
182
|
+
* and the next is tried. When every capability declines, resolves `{ handled:
|
|
183
|
+
* false }` so the factory falls through to the real fetcher.
|
|
184
|
+
*/
|
|
185
|
+
export declare function runWrapMutation<TData extends object>(capabilities: readonly SmrtWebCapability<TData>[], envelope: SmrtWebMutationEnvelope, ctx: SmrtWebCapabilityContext<TData>): Promise<{
|
|
186
|
+
handled: true;
|
|
187
|
+
result: unknown;
|
|
188
|
+
} | {
|
|
189
|
+
handled: false;
|
|
190
|
+
}>;
|
|
191
|
+
//# sourceMappingURL=capability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser transport for the canonical bounded data-query envelope (#2444).
|
|
3
|
+
*
|
|
4
|
+
* This is a textual structural mirror of `@happyvertical/smrt-types` rather
|
|
5
|
+
* than an import: smrt-web deliberately has no inter-SMRT dependencies. The
|
|
6
|
+
* authenticated server adapter owns allowlist, authorization, fingerprint,
|
|
7
|
+
* and byte-limit enforcement. This module gives browser callers a stable
|
|
8
|
+
* request/result shape and rejects malformed response envelopes before they
|
|
9
|
+
* reach a mounted surface.
|
|
10
|
+
*/
|
|
11
|
+
export type SmrtWebDataQueryScalar = string | number | boolean | null;
|
|
12
|
+
export type SmrtWebDataQueryFilterOperator = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'notIn' | 'like';
|
|
13
|
+
export type SmrtWebDataQueryFilter = {
|
|
14
|
+
kind: 'condition';
|
|
15
|
+
field: string;
|
|
16
|
+
operator: SmrtWebDataQueryFilterOperator;
|
|
17
|
+
value: SmrtWebDataQueryScalar | SmrtWebDataQueryScalar[];
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'all' | 'any';
|
|
20
|
+
filters: SmrtWebDataQueryFilter[];
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'not';
|
|
23
|
+
filter: SmrtWebDataQueryFilter;
|
|
24
|
+
};
|
|
25
|
+
export interface SmrtWebDataQueryRequest {
|
|
26
|
+
version: 1;
|
|
27
|
+
requestId: string;
|
|
28
|
+
mode: 'rows' | 'count' | 'facets';
|
|
29
|
+
projection?: string[];
|
|
30
|
+
filter?: SmrtWebDataQueryFilter;
|
|
31
|
+
sort?: Array<{
|
|
32
|
+
field: string;
|
|
33
|
+
direction: 'asc' | 'desc';
|
|
34
|
+
}>;
|
|
35
|
+
page?: {
|
|
36
|
+
kind: 'offset';
|
|
37
|
+
offset: number;
|
|
38
|
+
limit: number;
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'cursor';
|
|
41
|
+
after?: string;
|
|
42
|
+
limit: number;
|
|
43
|
+
};
|
|
44
|
+
consistency?: {
|
|
45
|
+
mode: 'eventual' | 'snapshot';
|
|
46
|
+
asOf?: string;
|
|
47
|
+
};
|
|
48
|
+
facets?: Array<{
|
|
49
|
+
field: string;
|
|
50
|
+
limit: number;
|
|
51
|
+
}>;
|
|
52
|
+
}
|
|
53
|
+
export type SmrtWebDataQueryTotal = {
|
|
54
|
+
kind: 'exact' | 'estimated';
|
|
55
|
+
value: number;
|
|
56
|
+
asOf?: string;
|
|
57
|
+
} | {
|
|
58
|
+
kind: 'unavailable';
|
|
59
|
+
reason?: string;
|
|
60
|
+
};
|
|
61
|
+
export interface SmrtWebDataQueryFacetResult {
|
|
62
|
+
field: string;
|
|
63
|
+
values: Array<{
|
|
64
|
+
value: SmrtWebDataQueryScalar;
|
|
65
|
+
count: number;
|
|
66
|
+
}>;
|
|
67
|
+
truncated: boolean;
|
|
68
|
+
}
|
|
69
|
+
export interface SmrtWebDataQueryResult {
|
|
70
|
+
version: 1;
|
|
71
|
+
requestId: string;
|
|
72
|
+
queryFingerprint: string;
|
|
73
|
+
identityField: string;
|
|
74
|
+
rows: Array<Record<string, unknown>>;
|
|
75
|
+
page?: {
|
|
76
|
+
kind: 'offset';
|
|
77
|
+
limit: number;
|
|
78
|
+
offset: number;
|
|
79
|
+
hasMore: boolean;
|
|
80
|
+
} | {
|
|
81
|
+
kind: 'cursor';
|
|
82
|
+
limit: number;
|
|
83
|
+
nextCursor?: string;
|
|
84
|
+
hasMore: boolean;
|
|
85
|
+
};
|
|
86
|
+
total: SmrtWebDataQueryTotal;
|
|
87
|
+
facets?: SmrtWebDataQueryFacetResult[];
|
|
88
|
+
freshness: {
|
|
89
|
+
state: 'fresh' | 'stale' | 'unknown';
|
|
90
|
+
asOf?: string;
|
|
91
|
+
};
|
|
92
|
+
warnings: string[];
|
|
93
|
+
truncated: boolean;
|
|
94
|
+
}
|
|
95
|
+
/** Browser transport seam; REST, WebMCP, and test transports share it. */
|
|
96
|
+
export interface SmrtWebDataQueryTransport {
|
|
97
|
+
query(request: SmrtWebDataQueryRequest, options?: {
|
|
98
|
+
signal?: AbortSignal;
|
|
99
|
+
}): Promise<unknown>;
|
|
100
|
+
}
|
|
101
|
+
/** Mirrors core's hard output limits without adding an inter-SMRT dependency. */
|
|
102
|
+
export declare const MAX_SMRT_WEB_DATA_QUERY_RESULT_BYTES = 10000000;
|
|
103
|
+
export declare const MAX_SMRT_WEB_DATA_QUERY_ROWS = 1000;
|
|
104
|
+
export declare const MAX_SMRT_WEB_DATA_QUERY_FACETS = 20;
|
|
105
|
+
export declare const MAX_SMRT_WEB_DATA_QUERY_FACET_VALUES = 1000;
|
|
106
|
+
export declare const MAX_SMRT_WEB_DATA_QUERY_WARNINGS = 100;
|
|
107
|
+
export declare const MAX_SMRT_WEB_DATA_QUERY_PAGE_LIMIT = 1000;
|
|
108
|
+
export declare const MAX_SMRT_WEB_DATA_QUERY_OFFSET = 1000000;
|
|
109
|
+
export declare const MAX_SMRT_WEB_DATA_QUERY_CONTAINER_ITEMS = 1000;
|
|
110
|
+
export declare const MAX_SMRT_WEB_DATA_QUERY_STRING_LENGTH = 65536;
|
|
111
|
+
/**
|
|
112
|
+
* Check the server-produced, normalized result envelope before a browser
|
|
113
|
+
* surface consumes it. This validates portable shape only; the server's core
|
|
114
|
+
* normalizer remains the authorization, projection, and query-policy boundary.
|
|
115
|
+
*/
|
|
116
|
+
export declare function normalizeSmrtWebDataQueryResult(value: unknown): SmrtWebDataQueryResult;
|
|
117
|
+
/** Run a browser transport and return the defensive normalized envelope. */
|
|
118
|
+
export declare function executeSmrtWebDataQuery(transport: SmrtWebDataQueryTransport, request: SmrtWebDataQueryRequest, options?: {
|
|
119
|
+
signal?: AbortSignal;
|
|
120
|
+
}): Promise<SmrtWebDataQueryResult>;
|
|
121
|
+
//# sourceMappingURL=data-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-query.d.ts","sourceRoot":"","sources":["../src/data-query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser transport for bounded data-surface action envelopes.
|
|
3
|
+
*
|
|
4
|
+
* This structurally mirrors smrt-types without importing another SMRT package.
|
|
5
|
+
* The server remains responsible for authority, descriptor allowlists, and
|
|
6
|
+
* confirmation-token validation; this boundary only rejects malformed replies.
|
|
7
|
+
*/
|
|
8
|
+
import type { OutboxCommand, OutboxCommandResult, OutboxCommandTransport } from './offline/types.js';
|
|
9
|
+
export type SmrtWebDataSurfaceJsonPrimitive = string | number | boolean | null;
|
|
10
|
+
export type SmrtWebDataSurfaceJsonValue = SmrtWebDataSurfaceJsonPrimitive | SmrtWebDataSurfaceJsonValue[] | {
|
|
11
|
+
[key: string]: SmrtWebDataSurfaceJsonValue;
|
|
12
|
+
};
|
|
13
|
+
export interface SmrtWebDataSurfaceIdentity {
|
|
14
|
+
surfaceId: string;
|
|
15
|
+
kind: 'table' | 'list' | 'report' | 'custom';
|
|
16
|
+
subject?: {
|
|
17
|
+
type: string;
|
|
18
|
+
id: string;
|
|
19
|
+
label?: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export type SmrtWebDataSurfaceSelection = {
|
|
23
|
+
scope: 'current-page';
|
|
24
|
+
} | {
|
|
25
|
+
scope: 'explicit-ids';
|
|
26
|
+
rowIds: Array<string | number>;
|
|
27
|
+
} | {
|
|
28
|
+
scope: 'all-matching';
|
|
29
|
+
queryFingerprint: string;
|
|
30
|
+
};
|
|
31
|
+
export interface SmrtWebDataSurfaceActionRequest {
|
|
32
|
+
version: 1;
|
|
33
|
+
requestId: string;
|
|
34
|
+
identity: SmrtWebDataSurfaceIdentity;
|
|
35
|
+
actionId: string;
|
|
36
|
+
phase: 'preview' | 'apply';
|
|
37
|
+
expectedRevision: number;
|
|
38
|
+
/** Required by the server for apply; retries with the same key replay safely. */
|
|
39
|
+
idempotencyKey?: string;
|
|
40
|
+
selection: SmrtWebDataSurfaceSelection;
|
|
41
|
+
payload?: SmrtWebDataSurfaceJsonValue;
|
|
42
|
+
confirmationToken?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface SmrtWebDataSurfaceActionResult {
|
|
45
|
+
version: 1;
|
|
46
|
+
requestId: string;
|
|
47
|
+
identity: SmrtWebDataSurfaceIdentity;
|
|
48
|
+
actionId: string;
|
|
49
|
+
phase: 'preview' | 'apply';
|
|
50
|
+
ok: boolean;
|
|
51
|
+
reason?: string;
|
|
52
|
+
confirmationToken?: string;
|
|
53
|
+
details?: {
|
|
54
|
+
[key: string]: SmrtWebDataSurfaceJsonValue;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export interface SmrtWebDataSurfaceActionTransport {
|
|
58
|
+
action(request: SmrtWebDataSurfaceActionRequest, options?: {
|
|
59
|
+
signal?: AbortSignal;
|
|
60
|
+
}): Promise<unknown>;
|
|
61
|
+
}
|
|
62
|
+
export declare const MAX_SMRT_WEB_DATA_SURFACE_ACTION_RESULT_BYTES = 1000000;
|
|
63
|
+
export declare const MAX_SMRT_WEB_DATA_SURFACE_ACTION_IDENTIFIER_LENGTH = 256;
|
|
64
|
+
export declare const MAX_SMRT_WEB_DATA_SURFACE_ACTION_JSON_DEPTH = 16;
|
|
65
|
+
export declare const MAX_SMRT_WEB_DATA_SURFACE_ACTION_CONTAINER_ITEMS = 1000;
|
|
66
|
+
/** Fail closed before an action result reaches browser state. */
|
|
67
|
+
export declare function normalizeSmrtWebDataSurfaceActionResult(value: unknown): SmrtWebDataSurfaceActionResult;
|
|
68
|
+
export declare function executeSmrtWebDataSurfaceAction(transport: SmrtWebDataSurfaceActionTransport, request: SmrtWebDataSurfaceActionRequest, options?: {
|
|
69
|
+
signal?: AbortSignal;
|
|
70
|
+
}): Promise<SmrtWebDataSurfaceActionResult>;
|
|
71
|
+
/**
|
|
72
|
+
* The replay-time request for {@link dataSurfaceActionCommandTransport}: every
|
|
73
|
+
* action-request field except those the adapter owns — `version`, `phase`,
|
|
74
|
+
* `requestId`, `idempotencyKey`, and `confirmationToken`.
|
|
75
|
+
*/
|
|
76
|
+
export type SmrtWebDataSurfaceActionCommandRequest = Omit<SmrtWebDataSurfaceActionRequest, 'version' | 'phase' | 'requestId' | 'idempotencyKey' | 'confirmationToken'>;
|
|
77
|
+
export interface SmrtWebDataSurfaceActionCommandTransportOptions {
|
|
78
|
+
/** The same action transport the mounted surface uses online. */
|
|
79
|
+
transport: SmrtWebDataSurfaceActionTransport;
|
|
80
|
+
/**
|
|
81
|
+
* Build the action request for a queued write at its FIRST replay attempt,
|
|
82
|
+
* so it carries the surface's `expectedRevision` as of replay rather than
|
|
83
|
+
* capture. The built request is pinned durably to the write and reused on
|
|
84
|
+
* every later attempt (including after a reload): the server fingerprints
|
|
85
|
+
* the request per idempotency key, so a resend after a lost response must be
|
|
86
|
+
* identical to replay the recorded result instead of `idempotency_conflict`.
|
|
87
|
+
*/
|
|
88
|
+
request: (command: OutboxCommand) => SmrtWebDataSurfaceActionCommandRequest | Promise<SmrtWebDataSurfaceActionCommandRequest>;
|
|
89
|
+
/**
|
|
90
|
+
* Run `preview` first and apply with its `confirmationToken` — for actions
|
|
91
|
+
* whose server adapter requires confirmation. Default false (apply only).
|
|
92
|
+
* The token is pinned before apply; a retry applies with it directly (the
|
|
93
|
+
* server replays a completed result) and previews again only when the token
|
|
94
|
+
* turns out unusable.
|
|
95
|
+
*/
|
|
96
|
+
preview?: boolean;
|
|
97
|
+
/** Map a non-throwing result onto an outbox outcome. Default below. */
|
|
98
|
+
classify?: (result: SmrtWebDataSurfaceActionResult) => OutboxCommandResult;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Default outcome mapping for a data-surface action result. `ok` → applied; a
|
|
102
|
+
* transient server reason → retryable `write_failed`; an authentication reason
|
|
103
|
+
* → pause for re-auth; a stale revision/preview → `conflict` (a RESOLVED
|
|
104
|
+
* outcome the app rebases from); anything else — including `denied` — is a
|
|
105
|
+
* terminal rejection surfaced as `failed`.
|
|
106
|
+
*/
|
|
107
|
+
export declare function classifySmrtWebDataSurfaceActionResult(result: SmrtWebDataSurfaceActionResult): OutboxCommandResult;
|
|
108
|
+
/**
|
|
109
|
+
* An {@link OutboxCommandTransport} that replays a queued write as a
|
|
110
|
+
* data-surface action `apply` (optionally preceded by `preview`) through the
|
|
111
|
+
* surface's own server adapter — its authority, allowlist, and principal
|
|
112
|
+
* scoping stay on the server path (#3021). The outbox's durable idempotency
|
|
113
|
+
* key becomes the action's `idempotencyKey`, so a resend after a lost response
|
|
114
|
+
* replays the server's recorded result instead of applying twice. Malformed or
|
|
115
|
+
* mismatched replies throw, which the outbox treats as retryable.
|
|
116
|
+
*/
|
|
117
|
+
export declare function dataSurfaceActionCommandTransport(options: SmrtWebDataSurfaceActionCommandTransportOptions): OutboxCommandTransport;
|
|
118
|
+
//# sourceMappingURL=data-surface-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-surface-actions.d.ts","sourceRoot":"","sources":["../src/data-surface-actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @happyvertical/smrt-web — shared durable-store foundation (#1755).
|
|
3
|
+
*
|
|
4
|
+
* The ONE SMRT-layer namespacing + wipe registry that the future offline
|
|
5
|
+
* outbox (#1762) and persistence (#1764) slices both build on. Pure bookkeeping
|
|
6
|
+
* — ZERO client-data-engine (`@tanstack/*`) imports — so it stays inside the
|
|
7
|
+
* engine-absorption boundary and ships now, before either consumer exists, so
|
|
8
|
+
* the two slices agree on it from day one.
|
|
9
|
+
*
|
|
10
|
+
* Why a SMRT-layer registry rather than one storage engine: TanStack DB
|
|
11
|
+
* persistence (SQLite-WASM / OPFS) and `@tanstack/offline-transactions`
|
|
12
|
+
* (IndexedDB) are SEPARATE storage engines. There is no single primitive that
|
|
13
|
+
* spans both, so the shared foundation lives one level up — a deterministic
|
|
14
|
+
* namespace both slices key their own storage under, plus a registry so
|
|
15
|
+
* {@link wipeDurableStore} can clear BOTH through one call without the outbox
|
|
16
|
+
* and persistence modules importing each other. A logout / tenant-switch wipes
|
|
17
|
+
* every durable artifact for a namespace in one place.
|
|
18
|
+
*
|
|
19
|
+
* Nothing in this package calls these yet — the seam ships ahead of its
|
|
20
|
+
* consumers by design (see PRD #1755).
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* The identity a durable namespace is derived from. Combining the API base with
|
|
24
|
+
* the tenant + identity + manifest hash means a logout, a tenant switch, or a
|
|
25
|
+
* schema change each land on a DIFFERENT namespace, so durable artifacts are
|
|
26
|
+
* never reused across those boundaries.
|
|
27
|
+
*
|
|
28
|
+
* `manifestHash` is supplied by the caller (its source is #1764's call — a
|
|
29
|
+
* schema-shape digest); this module is source-agnostic and treats it as an
|
|
30
|
+
* opaque discriminator.
|
|
31
|
+
*/
|
|
32
|
+
export interface DurableStoreKey {
|
|
33
|
+
/** API base path the durable data was fetched against (e.g. `/api/v1`). */
|
|
34
|
+
apiBase: string;
|
|
35
|
+
/** Active tenant id, if any — absent means the single-tenant / global scope. */
|
|
36
|
+
tenantId?: string;
|
|
37
|
+
/** Authenticated identity id, if any — absent means anonymous. */
|
|
38
|
+
identityId?: string;
|
|
39
|
+
/** Opaque schema-shape digest; a change forces a fresh namespace. */
|
|
40
|
+
manifestHash: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Compute the deterministic storage namespace for a {@link DurableStoreKey}.
|
|
44
|
+
* The same key always yields the same string; **any differing segment yields a
|
|
45
|
+
* different one** (injective) — this is critical because the namespace IS the
|
|
46
|
+
* tenant/identity/api isolation + wipe boundary, so a collision would reuse or
|
|
47
|
+
* wipe durable data ACROSS those boundaries.
|
|
48
|
+
*
|
|
49
|
+
* Injectivity is guaranteed three ways: every segment is `encodeURIComponent`-
|
|
50
|
+
* encoded, so a raw `:` in a value becomes `%3A` and can never be mistaken for a
|
|
51
|
+
* separator; an ABSENT `tenantId` / `identityId` maps to the empty string while
|
|
52
|
+
* a PRESENT value is prefixed with `_` (so undefined→``, ``→`_`, `x`→`_x`) — so
|
|
53
|
+
* an explicitly-EMPTY id no longer collides with "no id", nor does a real id of
|
|
54
|
+
* `-`. Both future slices key their own storage primitive (IndexedDB store name,
|
|
55
|
+
* OPFS path, …) under this string.
|
|
56
|
+
*/
|
|
57
|
+
export declare function durableStoreNamespace(key: DurableStoreKey): string;
|
|
58
|
+
/**
|
|
59
|
+
* A durable artifact registered under a namespace — the outbox queue (#1762) or
|
|
60
|
+
* a persisted collection store (#1764). Each owns its storage engine and
|
|
61
|
+
* exposes only a `clear()` so {@link wipeDurableStore} can tear it down without
|
|
62
|
+
* knowing which engine backs it.
|
|
63
|
+
*/
|
|
64
|
+
export interface DurableResource {
|
|
65
|
+
/** Which slice owns this artifact — for diagnostics and selective sweeps. */
|
|
66
|
+
readonly kind: 'outbox' | 'persisted-collection';
|
|
67
|
+
/** Drop this artifact's durable storage. Best-effort; may reject. */
|
|
68
|
+
clear(): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Register a durable artifact under a namespace so {@link wipeDurableStore} can
|
|
72
|
+
* later clear it. Returns an unregister function that removes just this
|
|
73
|
+
* resource — call it when the artifact is disposed on its own (before any
|
|
74
|
+
* namespace-wide wipe) so it is not cleared twice.
|
|
75
|
+
*/
|
|
76
|
+
export declare function registerDurableResource(namespace: string, resource: DurableResource): () => void;
|
|
77
|
+
/**
|
|
78
|
+
* Clear every durable artifact registered under `namespace`, then drop the
|
|
79
|
+
* namespace. This is the single teardown point a logout / tenant-switch calls:
|
|
80
|
+
* it fans out across BOTH the outbox and persistence slices via the registry,
|
|
81
|
+
* so neither module needs to import the other.
|
|
82
|
+
*
|
|
83
|
+
* Best-effort: a resource whose `clear()` rejects does not abort the sweep —
|
|
84
|
+
* every registered resource is still cleared (a wipe is a teardown, not a
|
|
85
|
+
* transaction). A safe no-op on an unknown or empty namespace.
|
|
86
|
+
*/
|
|
87
|
+
export declare function wipeDurableStore(namespace: string): Promise<void>;
|
|
88
|
+
//# sourceMappingURL=durable-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durable-store.d.ts","sourceRoot":"","sources":["../src/durable-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAOlE;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,sBAAsB,CAAC;IACjD,qEAAqE;IACrE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AASD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,GACxB,MAAM,IAAI,CAcZ;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYvE"}
|