@andco/sdk 0.0.2 → 0.0.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.
Files changed (83) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +96 -54
  3. package/dist/auth.d.ts +8 -3
  4. package/dist/auth.d.ts.map +1 -1
  5. package/dist/auth.js +32 -23
  6. package/dist/browser/controller.d.ts +55 -1
  7. package/dist/browser/controller.d.ts.map +1 -1
  8. package/dist/browser/controller.js +166 -9
  9. package/dist/browser/frame.d.ts +4 -3
  10. package/dist/browser/frame.d.ts.map +1 -1
  11. package/dist/browser/frame.js +12 -20
  12. package/dist/browser/index.d.ts +18 -6
  13. package/dist/browser/index.d.ts.map +1 -1
  14. package/dist/browser/index.js +64 -29
  15. package/dist/browser/popup.d.ts +6 -1
  16. package/dist/browser/popup.d.ts.map +1 -1
  17. package/dist/browser/popup.js +37 -8
  18. package/dist/cli/index.d.ts +4 -2
  19. package/dist/cli/index.d.ts.map +1 -1
  20. package/dist/cli/index.js +10 -3
  21. package/dist/cli/server.d.ts +5 -0
  22. package/dist/cli/server.d.ts.map +1 -1
  23. package/dist/cli/server.js +5 -0
  24. package/dist/client.d.ts +66 -19
  25. package/dist/client.d.ts.map +1 -1
  26. package/dist/client.js +125 -74
  27. package/dist/config.d.ts +2 -1
  28. package/dist/config.d.ts.map +1 -1
  29. package/dist/config.js +1 -0
  30. package/dist/credentials.d.ts +58 -4
  31. package/dist/credentials.d.ts.map +1 -1
  32. package/dist/credentials.js +0 -0
  33. package/dist/errors.d.ts +23 -21
  34. package/dist/errors.d.ts.map +1 -1
  35. package/dist/errors.js +18 -20
  36. package/dist/globals.d.ts +25 -0
  37. package/dist/globals.d.ts.map +1 -0
  38. package/dist/globals.js +15 -0
  39. package/dist/grants-api.d.ts +34 -0
  40. package/dist/grants-api.d.ts.map +1 -0
  41. package/dist/grants-api.js +48 -0
  42. package/dist/grants.d.ts +16 -0
  43. package/dist/grants.d.ts.map +1 -0
  44. package/dist/grants.js +13 -0
  45. package/dist/index.d.ts +12 -6
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +8 -2
  48. package/dist/inflight.d.ts +31 -0
  49. package/dist/inflight.d.ts.map +1 -0
  50. package/dist/inflight.js +26 -0
  51. package/dist/intents.d.ts +386 -40
  52. package/dist/intents.d.ts.map +1 -1
  53. package/dist/intents.js +712 -53
  54. package/dist/oauth.d.ts +55 -6
  55. package/dist/oauth.d.ts.map +1 -1
  56. package/dist/oauth.js +86 -57
  57. package/dist/presenter.d.ts +59 -11
  58. package/dist/presenter.d.ts.map +1 -1
  59. package/dist/presenter.js +40 -1
  60. package/dist/resource.d.ts +109 -0
  61. package/dist/resource.d.ts.map +1 -0
  62. package/dist/resource.js +151 -0
  63. package/dist/rest.d.ts +23 -4
  64. package/dist/rest.d.ts.map +1 -1
  65. package/dist/rest.js +46 -5
  66. package/dist/server/index.d.ts +3 -0
  67. package/dist/server/index.d.ts.map +1 -1
  68. package/dist/server/index.js +1 -0
  69. package/dist/server-metadata.generated.d.ts.map +1 -1
  70. package/dist/server-metadata.generated.js +8 -4
  71. package/dist/service.d.ts +109 -0
  72. package/dist/service.d.ts.map +1 -0
  73. package/dist/service.js +241 -0
  74. package/dist/session-store.d.ts +12 -4
  75. package/dist/session-store.d.ts.map +1 -1
  76. package/dist/session-store.js +64 -14
  77. package/dist/storage.d.ts +16 -23
  78. package/dist/storage.d.ts.map +1 -1
  79. package/dist/storage.js +27 -25
  80. package/dist/tokens.d.ts +46 -0
  81. package/dist/tokens.d.ts.map +1 -0
  82. package/dist/tokens.js +148 -0
  83. package/package.json +13 -3
package/dist/intents.d.ts CHANGED
@@ -1,44 +1,210 @@
1
- import { type AndCoRandomSource } from "@andco/protocol";
2
1
  import { type AndCoEventPage, type AndCoFinancialEvent, type AndCoIntent } from "@andco/protocol/transport";
3
- import { Result } from "./errors.js";
4
- import type { AndcoRest } from "./rest.js";
2
+ import type { AndcoConfig } from "./config.js";
3
+ import { AndcoError, Result } from "./errors.js";
4
+ import { type AndcoGlobals } from "./globals.js";
5
+ import type { AndcoIntentPresentation, AndcoPresenter } from "./presenter.js";
6
+ import type { AndcoGrantOptions, AndcoRest } from "./rest.js";
5
7
  export type { AndCoEventPage as AndcoEventPage, AndCoFinancialEvent as AndcoFinancialEvent, AndCoIntent as AndcoIntent, };
6
8
  /** An intent identifier, or a factory that produces one after the user activates a launcher. */
7
9
  export type AndcoIntentId = string | (() => Promise<string>);
10
+ /**
11
+ * An Intent, or its identifier. Every `andco.intents` method that names one existing Intent takes
12
+ * either, so a caller never has to remember which of the two a method wants.
13
+ */
14
+ export type AndcoIntentReference = string | {
15
+ id: string;
16
+ };
17
+ /**
18
+ * Options for {@link AndcoIntents.approve}. `grant` pins the approving Grant when the credential holds
19
+ * several (a Service); without it the Authorization Server selects one from subject and resource.
20
+ */
21
+ export type AndcoIntentApproveOptions = AndcoGrantOptions;
22
+ /** Options for {@link AndcoIntents.reject}: why, 1–280 characters, and optionally the approving Grant. */
23
+ export type AndcoIntentRejectOptions = AndcoGrantOptions & {
24
+ reason: string;
25
+ };
26
+ /** Options for {@link AndcoIntents.cancel}: why, 1–280 characters, and optionally the creating Grant. */
27
+ export type AndcoIntentCancelOptions = AndcoGrantOptions & {
28
+ reason: string;
29
+ };
30
+ /**
31
+ * What {@link AndcoIntents.present} presents: an Intent, its id, or a factory resolved only after
32
+ * the window is open — the shape that keeps a popup from being blocked when the Intent is created
33
+ * on the click itself.
34
+ */
35
+ export type AndcoIntentPresentSource<T extends {
36
+ id: string;
37
+ } = AndCoIntent> = string | T | (() => Promise<string | T>);
38
+ /** The subset of the Web Storage API a pending presentation needs. `sessionStorage` satisfies it. */
39
+ export type AndcoPresentationStorage = Pick<Storage, "getItem" | "setItem" | "removeItem">;
40
+ /** Write options for creating an Intent; reuse the same key for retries. */
8
41
  export type AndcoIntentCreateOptions = {
9
42
  /** A stable transport key. One is generated when omitted. */
10
43
  idempotencyKey?: string;
11
44
  };
45
+ /** REST lifecycle dependencies and optional capabilities for presenting an Intent. */
46
+ export type AndcoIntentsOptions = {
47
+ rest: AndcoRest;
48
+ /**
49
+ * Required to present or to build a presentation URL. A Resource Server Definition that composes
50
+ * this lifecycle without it gets creation, reads, events and subscriptions only.
51
+ */
52
+ config?: AndcoConfig;
53
+ presenter?: AndcoPresenter;
54
+ /** Platform capabilities; `crypto` sources idempotency keys and Presentation IDs. Defaults to the runtime's own. */
55
+ globals?: AndcoGlobals;
56
+ /**
57
+ * Remembers a `"redirect"` or `"newtab"` presentation until its return page reads it with
58
+ * {@link AndcoIntents.fromCallback}. Defaults to `sessionStorage` when the runtime has one.
59
+ */
60
+ presentationStorage?: AndcoPresentationStorage;
61
+ };
62
+ /** Everything a caller may vary for one Intent Presentation. */
63
+ export type AndcoIntentPresentOptions = {
64
+ /**
65
+ * `"popup"` (the default) opens a window and settles here. `"newtab"` does the same in a tab, for
66
+ * where popups are blocked. `"redirect"` replaces this document: the result never settles here and
67
+ * is read on the return page with {@link AndcoIntents.fromCallback}.
68
+ */
69
+ presentation?: AndcoIntentPresentation;
70
+ /** Exact callback Andco returns to. Defaults to the instance's registered `redirectTo`. */
71
+ returnTo?: string | URL;
72
+ /** Exact callback reached on dismissal. Defaults to `returnTo`; both must share one origin. */
73
+ errorReturnTo?: string | URL;
74
+ /** Aborting it closes the window, exactly like {@link AndcoIntentPresentationController.close}. */
75
+ signal?: AbortSignal;
76
+ };
77
+ /** Options for {@link AndcoIntents.presentationURL} and {@link AndcoIntents.presentationURLFor}. */
78
+ export type AndcoIntentURLOptions = {
79
+ presentation: AndcoIntentPresentation;
80
+ /** Exact callback Andco returns to. Defaults to the instance's registered `redirectTo`. */
81
+ returnTo?: string | URL;
82
+ /** Exact callback reached on dismissal. Defaults to `returnTo`; both must share one origin. */
83
+ errorReturnTo?: string | URL;
84
+ /**
85
+ * Generated, bound to `returnTo`'s origin, when omitted — read it back from the URL's `state`
86
+ * parameter to hand to {@link AndcoIntents.fromCallback}. Pass one only when another surface owns
87
+ * the callback, as the Hosted Intent Button does for the widget that opened its window.
88
+ */
89
+ state?: string;
90
+ };
91
+ /**
92
+ * The authoritative outcome of one Intent Presentation.
93
+ *
94
+ * `outcome` is what the window reported; `intent` is what the Resource Server says. Only the second
95
+ * one is money. They are both here because an application needs to tell "the user walked away" from
96
+ * "the user finished and it is still processing", and the read alone cannot say which.
97
+ */
98
+ export type AndcoPresentationResult<T = AndCoIntent> = {
99
+ outcome: "complete" | "dismiss";
100
+ intent: T;
101
+ };
102
+ /**
103
+ * Where one presentation is. `"navigated"` is the end of a `"redirect"`: this document is being
104
+ * replaced and its result arrives on the return page instead.
105
+ */
106
+ export type AndcoIntentPresentationStatus = "presenting" | "complete" | "dismissed" | "navigated" | "error";
107
+ /** Handle on one in-flight Intent Presentation, returned synchronously by {@link AndcoIntents.present}. */
108
+ export type AndcoIntentPresentationController<T = AndCoIntent> = {
109
+ /** Current lifecycle position; read it whenever, it never goes back. */
110
+ readonly status: AndcoIntentPresentationStatus;
111
+ /**
112
+ * Settles once the window does, with the Intent read again afterwards. Never settles for a
113
+ * successful `"redirect"`, whose document is replaced.
114
+ */
115
+ readonly result: Promise<Result<AndcoPresentationResult<T>>>;
116
+ /** Closes the window. The result then settles as a dismissal, with the Intent still read. */
117
+ close(): void;
118
+ };
119
+ /** Optional filters and checkpoint hooks for {@link AndcoIntents.subscribe}. */
120
+ export type AndcoIntentSubscribeOptions = {
121
+ /** Exact event types to deliver, such as `"transfer.succeeded"`. Every type when omitted. */
122
+ types?: readonly string[];
123
+ /** Resume after a checkpoint this Intent's subscription previously acknowledged. */
124
+ after?: string;
125
+ /** Fires after a handler succeeds, carrying the cursor that is now safe to persist. */
126
+ onCheckpoint?: (cursor: string) => void;
127
+ /** Receives transport, authorization, cursor, and handler failures. Logged when omitted. */
128
+ onError?: (error: unknown) => void;
129
+ /** Delay between polls in milliseconds. Defaults to 1000; minimum 100. */
130
+ pollIntervalMs?: number;
131
+ };
132
+ /** Polling and checkpoint callbacks for processing durable financial events. */
12
133
  export type AndcoEventSubscriptionOptions = {
13
134
  /** Resume after a checkpoint this subject's subscription previously acknowledged. */
14
135
  after?: string;
15
136
  /** Receives transport, authorization, cursor, and handler failures. */
16
137
  onError: (error: unknown) => void;
138
+ /** Fires after a handler succeeds, carrying the cursor that is now safe to persist. */
139
+ onCheckpoint?: (cursor: string) => void;
140
+ /** Delay between polls in milliseconds. Defaults to 1000; minimum 100. */
141
+ pollIntervalMs?: number;
142
+ };
143
+ /** Options for {@link AndcoIntents.watch}. */
144
+ export type AndcoIntentWatchOptions<T = AndCoIntent> = {
145
+ /** Called with every successful read, terminal or not: what a UI renders while it waits. */
146
+ onChange?: (intent: T) => void;
147
+ /** Called with every failed read, which the watch then retries. Logged when omitted. */
148
+ onError?: (error: AndcoError) => void;
149
+ /** What ends the watch. `"terminal"` — the only one today, and the default — is a status that never changes again. */
150
+ until?: "terminal";
17
151
  /**
18
- * Fires after a handler succeeds, carrying the cursor that is now safe to persist.
19
- *
20
- * Pushed rather than read off the returned object, so the return value can stay a plain function
21
- * and a caller never has to retain a subscription just to learn where it got to.
152
+ * Exact event types that also end the watch, such as `"transfer.accepted"`, answering the Intent as
153
+ * it is then. For a caller that cares about a milestone before the terminal status.
22
154
  */
23
- onCheckpoint?: (cursor: string) => void;
155
+ types?: readonly string[];
156
+ /** Aborting it stops the watch, exactly like {@link AndcoIntentWatch.stop}. */
157
+ signal?: AbortSignal;
158
+ /** Delay between reads in milliseconds. Defaults to 1000; minimum 100. */
24
159
  pollIntervalMs?: number;
25
160
  };
161
+ /** Where a watch is: `"watching"`, `"settled"` once its `result` answered, or `"stopped"` by the caller. */
162
+ export type AndcoIntentWatchStatus = "watching" | "settled" | "stopped";
163
+ /** Handle on one {@link AndcoIntents.watch}. */
164
+ export type AndcoIntentWatch<T = AndCoIntent> = {
165
+ /** Current position of the watch; it never goes back. */
166
+ readonly status: AndcoIntentWatchStatus;
167
+ /** The latest authoritative read, `null` before the first one succeeds. Kept after a stop. */
168
+ readonly intent: T | null;
169
+ /**
170
+ * The Intent once it is terminal (or a requested event type arrived). Fails with the read's own
171
+ * error for a malformed id, and with `watch_stopped` when stopped first; transient read failures
172
+ * are retried, not reported here.
173
+ */
174
+ readonly result: Promise<Result<T>>;
175
+ /** Stops reading. `result` settles with `watch_stopped` unless it already settled. */
176
+ stop(): void;
177
+ };
26
178
  /**
27
- * Creates and reads Intents under the current Grant, and observes the durable facts they produce.
179
+ * Creates, presents, reads and follows Intents under the current Grant.
28
180
  *
29
- * This is the domain-neutral Intent lifecycle only. Deposit, withdrawal, automatic charge, and the
30
- * four typed event subscriptions that used to live here now belong to the Bank Resource Server
31
- * Definition, which composes `create`, `events`, and `subscribe` exactly as a third party would —
32
- * a defect in this extension point is meant to surface in Andco's own code first.
181
+ * Every method that names an existing Intent takes the Intent or its id. Presentation is one
182
+ * controller for three shapes — popup, new tab, redirect — and the SDK always generates and checks
183
+ * the callback `state`, so an application never correlates callbacks itself.
33
184
  *
34
185
  * @example
35
186
  * ```ts
36
- * const { data: deposit } = await andco.intents.create("deposit", depositInput);
187
+ * const { data: deposit } = await bank.intents.createDeposit(input);
188
+ * const presentation = andco.intents.present(deposit, { presentation: "popup" });
189
+ * const { data } = await presentation.result;
190
+ * if (data?.outcome === "complete") refreshBalance();
37
191
  * ```
38
192
  */
39
193
  export declare class AndcoIntents {
40
194
  #private;
41
- constructor(rest: AndcoRest, crypto?: AndCoRandomSource);
195
+ constructor(options: AndcoIntentsOptions);
196
+ /**
197
+ * Whether an Intent has reached a status it never leaves: succeeded, completed, closed, cancelled,
198
+ * rejected, expired, or any `failed` status.
199
+ *
200
+ * @example
201
+ * ```ts
202
+ * if (AndcoIntents.isTerminal(intent)) stopPolling();
203
+ * ```
204
+ */
205
+ static isTerminal(intent: {
206
+ status: string;
207
+ }): boolean;
42
208
  /**
43
209
  * Creates an Intent of the given type. The exact Grant determines what it may do and where.
44
210
  *
@@ -51,39 +217,219 @@ export declare class AndcoIntents {
51
217
  * Definition names its own response type here.
52
218
  */
53
219
  create<T = AndCoIntent>(type: string, input: object, options?: AndcoIntentCreateOptions): Promise<Result<T>>;
54
- /** Reads the authoritative state of one Intent. This, not a callback, is the source of truth. */
55
- get<T = AndCoIntent>(intentId: string): Promise<Result<T>>;
56
- /** Executes an intent whose Grant permits it. Completion must still be confirmed with `get`. */
57
- execute(intentId: string): Promise<Result<void>>;
58
- /** Reads one page of durable Intent facts, replaying after an opaque checkpoint. */
59
- events(intentId: string, after?: string, signal?: AbortSignal): Promise<Result<AndCoEventPage>>;
60
220
  /**
61
- * Subscribes to a durable, paged feed of facts, reusing the Protocol Contract's paging, cursor,
62
- * checkpoint, and poll-interval reconciliation.
221
+ * Sends one already-signed Instruction: the `application/jwt` half of the same creation.
63
222
  *
64
- * Domain-neutral by design: the caller supplies both the page fetcher (`read`) and the `subject`
65
- * that scopes its cursor namespace, so nothing here assumes an Intent, an account, or any other
66
- * kind of subject. That is what lets a Resource Server Definition — the Bank one included —
67
- * compose this loop for its own event feed instead of rebuilding paging and checkpointing from
68
- * scratch, which is the one genuinely difficult piece of this surface.
223
+ * The body is the compact JWS itself, and every value the operation uses comes from its verified
224
+ * claims — nothing is read from the envelope carrying them, so `type` is only checked against the
225
+ * response here and never written into a request. No `Idempotency-Key` accompanies it either: the
226
+ * key is the `jti` inside the signature, and the server answers `400 idempotency_key_not_allowed`
227
+ * to a second candidate rather than quietly picking one.
228
+ */
229
+ createSigned<T = AndCoIntent>(type: string, instruction: string): Promise<Result<T>>;
230
+ /**
231
+ * The Andco-owned URL that presents one Intent, with its callbacks bound. Synchronous: it reads
232
+ * the Intent's own `authorization_url`, checks it belongs to the instance's interaction origin,
233
+ * and adds the four parameters Platform requires (`return_uri`, `error_return_uri`,
234
+ * `presentation`, `state`) — a bare `authorization_url` is an input, not a destination.
69
235
  *
70
- * Every subscription returns its own unsubscribe function, so binding one to a framework effect —
71
- * `useEffect`, Svelte's `$effect`, Vue's `watchEffect` — is a single line.
236
+ * Never intercepted by a native Host: it is a URL, not a presentation. Use it to redirect a payer
237
+ * from a server, or to put the link somewhere the SDK does not open itself. When only the id is at
238
+ * hand, {@link AndcoIntents.presentationURLFor} reads the Intent first.
72
239
  *
73
240
  * @example
74
241
  * ```ts
75
- * const unsubscribe = andco.intents.subscribe(
76
- * { kind: "intent", id: intentId },
77
- * (after, signal) => andco.intents.events(intentId, after, signal),
78
- * (event) => (event.type.startsWith("deposit.") ? event : null),
79
- * (event) => setDeposit(event),
80
- * { onError },
81
- * );
242
+ * const { data: url } = andco.intents.presentationURL(deposit, { presentation: "redirect", returnTo });
243
+ * return Response.redirect(url);
82
244
  * ```
83
245
  */
84
- subscribe<E extends AndCoFinancialEvent>(subject: {
85
- kind: string;
246
+ presentationURL(intent: {
247
+ authorization_url: string;
248
+ }, options: AndcoIntentURLOptions): Result<URL>;
249
+ /**
250
+ * {@link AndcoIntents.presentationURL} for a caller holding only the id: reads the Intent, then
251
+ * builds the same URL. The one asynchronous way to a presentation URL.
252
+ *
253
+ * @example
254
+ * ```ts
255
+ * const { data: url } = await andco.intents.presentationURLFor(intentId, { presentation: "popup" });
256
+ * ```
257
+ */
258
+ presentationURLFor(intentId: string, options: AndcoIntentURLOptions): Promise<Result<URL>>;
259
+ /**
260
+ * Presents one Intent and hands back a controller for it at once.
261
+ *
262
+ * `"popup"` and `"newtab"` open a window during the current user activation — call this
263
+ * synchronously from the click handler — and `result` settles when it closes, with the Intent read
264
+ * again: a callback reports that a window finished, which is not the same fact as a completed
265
+ * deposit, and a dismissal is read too because the person may have closed the window on an
266
+ * operation the bank had already accepted. Inside the first-party native Host both are presented
267
+ * by the Host instead of a window.
268
+ *
269
+ * `"redirect"` navigates this document away; `status` becomes `"navigated"` and `result` never
270
+ * settles. The return page reads the outcome with {@link AndcoIntents.fromCallback}.
271
+ *
272
+ * `state` is always generated here and checked on the way back. The source may be a factory,
273
+ * resolved only after the window is open, so creating the Intent on the click does not get the
274
+ * popup blocked.
275
+ *
276
+ * Idempotent per Intent within one Andco Instance: while a presentation of the same Intent id is
277
+ * still `"presenting"`, another call focuses the window already open and returns the SAME
278
+ * controller — never a second popup or tab, whatever options the second call carried. Once that
279
+ * presentation settles, a new call opens a new one. A `"redirect"` is unaffected, since it replaces
280
+ * the document, and a factory cannot be matched before it resolves, so it always presents.
281
+ *
282
+ * That is the window's idempotency. The Intent's own is server-side: a fixed-amount deposit or a
283
+ * transfer cannot be paid or confirmed twice however many windows reach it, whereas an open
284
+ * collection (no amount) accepts several contributions by design.
285
+ *
286
+ * @example
287
+ * ```ts
288
+ * const presentation = andco.intents.present(() => createDeposit(), { presentation: "popup" });
289
+ * cancelButton.onclick = () => presentation.close();
290
+ * const { data, error } = await presentation.result;
291
+ * if (data?.outcome === "complete") refreshBalance();
292
+ * ```
293
+ */
294
+ present<T extends {
295
+ id: string;
296
+ } = AndCoIntent>(source: AndcoIntentPresentSource<T>, options?: AndcoIntentPresentOptions): AndcoIntentPresentationController<T>;
297
+ /**
298
+ * Reads an Intent Presentation's outcome on the page its callback landed on — the return page of
299
+ * a `"redirect"`, or of a `"newtab"` whose opener is gone — then reads the Intent again.
300
+ *
301
+ * The callback's `state` must belong to a presentation this browser started with
302
+ * {@link AndcoIntents.present}; anything else is refused with `invalid_callback`, and each
303
+ * presentation is consumed once. A server that built the URL with
304
+ * {@link AndcoIntents.presentationURL} passes the `state` it kept instead.
305
+ *
306
+ * @example
307
+ * ```ts
308
+ * const { data, error } = await andco.intents.fromCallback(window.location.href);
309
+ * if (data?.outcome === "complete") showReceipt(data.intent);
310
+ * ```
311
+ */
312
+ fromCallback<T = AndCoIntent>(callbackUrl: string | URL, options?: {
313
+ state?: string;
314
+ }): Promise<Result<AndcoPresentationResult<T>>>;
315
+ /**
316
+ * Reads the authoritative state of one Intent, as the Resource Server has it right now.
317
+ *
318
+ * This, never a callback, a window message or a webhook alone, is the source of truth: a callback
319
+ * reports that a window finished, and only this read says whether money moved. Accepts the Intent
320
+ * or just its id.
321
+ *
322
+ * Typical uses: re-reading after a page reload (keep the id, call `get`, or `watch` to follow it
323
+ * on); reading once `present` resolves, which {@link AndcoIntents.present} already does for
324
+ * its own `intent`; and, on your server, confirming `status` before marking an order paid or
325
+ * shipping goods — never trust the browser's word for it.
326
+ *
327
+ * Never throws; failures arrive as `error.code`:
328
+ * - `invalid_intent_id`: the id is not a well-formed UUID; no request was made.
329
+ * - `not_found`: no such Intent for this Project, or it belongs to another one. The API answers
330
+ * the same either way so ids cannot be probed.
331
+ * - `insufficient_authorization`: the Grant does not cover reading Intents of this family.
332
+ * - network and server failures carry their own code and are safe to retry.
333
+ *
334
+ * @example
335
+ * ```ts
336
+ * const { data: intent, error } = await andco.intents.get(intentOrId);
337
+ * if (error?.code === "not_found") return showUnknownOrder();
338
+ * if (intent && AndcoIntents.isTerminal(intent)) settleOrder(intent.status);
339
+ *
340
+ * // On the server, before marking the order paid:
341
+ * const { data } = await andco.intents.get(order.intentId);
342
+ * if (data?.status === "completed") await markPaid(order);
343
+ * ```
344
+ */
345
+ get<T = AndCoIntent>(intent: AndcoIntentReference): Promise<Result<T>>;
346
+ /**
347
+ * Follows one Intent until it is terminal and answers it. The one call to re-attach to an Intent
348
+ * after a reload: keep the id, `watch` it, and the page is back where it was.
349
+ *
350
+ * Terminal means succeeded, completed, closed, cancelled, rejected, expired, or any `failed`
351
+ * status ({@link AndcoIntents.isTerminal}); the `result` then holds the Intent as the Resource
352
+ * Server has it. Built on {@link AndcoIntents.get}, which it repeats every `pollIntervalMs` — the
353
+ * authority, and the only way to notice an expiry — and on {@link AndcoIntents.subscribe}, whose
354
+ * events wake it up sooner. A read that fails is retried, so a dropped connection does not end
355
+ * the wait; a malformed id fails at once with `invalid_intent_id`.
356
+ *
357
+ * `stop()` or `signal` end it with `watch_stopped`; `intent` keeps the last read. Terminal means
358
+ * the Intent stopped changing, not that it succeeded: look at `status` before acting on money.
359
+ *
360
+ * @example
361
+ * ```ts
362
+ * const watch = andco.intents.watch(intentId);
363
+ * onUnmount(() => watch.stop());
364
+ * const { data: intent, error } = await watch.result;
365
+ * if (intent?.status === "completed") showReceipt(intent);
366
+ *
367
+ * // A milestone before the terminal status, with a deadline:
368
+ * andco.intents.watch(transfer, { types: ["transfer.accepted"], signal: AbortSignal.timeout(60_000) });
369
+ * ```
370
+ */
371
+ watch<T extends {
86
372
  id: string;
87
- }, read: (after: string | undefined, signal: AbortSignal) => Promise<Result<AndCoEventPage>>, decode: (event: AndCoFinancialEvent) => E | null, handler: (event: E) => void | Promise<void>, options: AndcoEventSubscriptionOptions): () => void;
373
+ status: string;
374
+ } = AndCoIntent & {
375
+ status: string;
376
+ }>(intent: AndcoIntentReference, options?: AndcoIntentWatchOptions<T>): AndcoIntentWatch<T>;
377
+ /**
378
+ * Approves an Intent with this credential's Grant, which must hold `approve` on the family that
379
+ * releases it (`bank_transfer` for a transfer) for the same subject, within its maximum. The
380
+ * approver may be another app than the creator: dual control is two Grants. Answers the Intent;
381
+ * accepted is not moved, so wait for `transfer.succeeded` or `transfer.failed`.
382
+ *
383
+ * Fails with `amount_out_of_grant` above the approver's maximum (the Intent stays pending for
384
+ * another approver), `interaction_required` when a person still has to pick the source, and
385
+ * `intent_expired` past its deadline.
386
+ *
387
+ * @example
388
+ * ```ts
389
+ * const approver = andco.with(approverCredentials).intents;
390
+ * await approver.approve(transfer);
391
+ * await approver.approve(transferId, { grant: grantId }); // pin the approving Grant
392
+ * ```
393
+ */
394
+ approve<T = AndCoIntent>(intent: AndcoIntentReference, options?: AndcoIntentApproveOptions): Promise<Result<T>>;
395
+ /**
396
+ * Rejects an Intent as an approver, naming why. This credential's Grant must hold `reject` on the
397
+ * family that releases it for the same subject; no maximum applies. Recorded as a Rejection, which
398
+ * the audit keeps apart from the creator's Cancellation.
399
+ *
400
+ * @example
401
+ * ```ts
402
+ * await andco.with(approverCredentials).intents.reject(transferId, { reason: "duplicated_invoice" });
403
+ * ```
404
+ */
405
+ reject<T = AndCoIntent>(intent: AndcoIntentReference, options: AndcoIntentRejectOptions): Promise<Result<T>>;
406
+ /**
407
+ * Withdraws an Intent this app created, naming why. Only the creator cancels; an approver
408
+ * declining it uses {@link AndcoIntents.reject}, and the audit keeps the two apart. Answers
409
+ * `intent_expired` when the Intent's deadline has already passed.
410
+ *
411
+ * @example
412
+ * ```ts
413
+ * await andco.intents.cancel(transfer, { reason: "rejected_by_erp" });
414
+ * ```
415
+ */
416
+ cancel<T = AndCoIntent>(intent: AndcoIntentReference, options: AndcoIntentCancelOptions): Promise<Result<T>>;
417
+ /** Reads one page of durable Intent facts, replaying after an opaque checkpoint. */
418
+ events(intent: AndcoIntentReference, after?: string, signal?: AbortSignal): Promise<Result<AndCoEventPage>>;
419
+ /**
420
+ * Follows one Intent's durable facts, in order, polling its event feed. Returns the unsubscribe,
421
+ * so binding it to `useEffect`, `$effect` or `watchEffect` is a single line.
422
+ *
423
+ * The checkpoint is pushed through `onCheckpoint` only after a handler succeeds; persist it and
424
+ * pass it back as `after` to resume after a crash without reprocessing.
425
+ *
426
+ * @example
427
+ * ```ts
428
+ * const unsubscribe = andco.intents.subscribe(transfer, (event) => console.log(event.type));
429
+ * andco.intents.subscribe(transfer, { types: ["transfer.succeeded"], after: saved, onCheckpoint: save }, onDone);
430
+ * ```
431
+ */
432
+ subscribe<E extends AndCoFinancialEvent = AndCoFinancialEvent>(intent: AndcoIntentReference, handler: (event: E) => void | Promise<void>): () => void;
433
+ subscribe<E extends AndCoFinancialEvent = AndCoFinancialEvent>(intent: AndcoIntentReference, options: AndcoIntentSubscribeOptions, handler: (event: E) => void | Promise<void>): () => void;
88
434
  }
89
435
  //# sourceMappingURL=intents.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"intents.d.ts","sourceRoot":"","sources":["../src/intents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAe,MAAM,iBAAiB,CAAC;AACtE,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAEjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAiC,MAAM,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,YAAY,EACV,cAAc,IAAI,cAAc,EAChC,mBAAmB,IAAI,mBAAmB,EAC1C,WAAW,IAAI,WAAW,GAC3B,CAAC;AAEF,gGAAgG;AAChG,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAK7D,MAAM,MAAM,wBAAwB,GAAG;IACrC,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,qBAAa,YAAY;;gBAIJ,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,iBAAiB;IAK9D;;;;;;;;;;OAUG;IACU,MAAM,CAAC,CAAC,GAAG,WAAW,EACjC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAuBrB,iGAAiG;IACpF,GAAG,CAAC,CAAC,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAavE,gGAAgG;IACnF,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAa7D,oFAAoF;IACvE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAgB5G;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACI,SAAS,CAAC,CAAC,SAAS,mBAAmB,EAC5C,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EACrC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,EACzF,MAAM,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,CAAC,GAAG,IAAI,EAChD,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC3C,OAAO,EAAE,6BAA6B,GACrC,MAAM,IAAI;CAuBd"}
1
+ {"version":3,"file":"intents.d.ts","sourceRoot":"","sources":["../src/intents.ts"],"names":[],"mappings":"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"}