@ailuracode/alpine-toast 0.1.1 → 1.0.0

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
@@ -1,4 +1,15 @@
1
- import AlpineType from 'alpinejs';
1
+ import { Alpine, Unsubscribe, PluginCallback, BaseController } from '@ailuracode/alpine-core';
2
+ export { Unsubscribe } from '@ailuracode/alpine-core';
3
+ import { Alpine as Alpine$1 } from 'alpinejs';
4
+
5
+ /**
6
+ * Public type contracts for `@ailuracode/alpine-toast`.
7
+ *
8
+ * Per `.cursor/rules/formatting.mdc`, every public type
9
+ * lives in a `types.ts` module so consumers can import them without pulling
10
+ * the implementation. The shape IS the contract — changes to a field name
11
+ * or type are breaking changes.
12
+ */
2
13
 
3
14
  /** Built-in Alpine store key for the toast queue. */
4
15
  declare const TOAST_STORE_KEY: "toast";
@@ -159,21 +170,143 @@ type ResolvedToastPluginConfig<TVariants extends readonly string[] = readonly []
159
170
  positions: TPositions;
160
171
  promise: ResolvedPromiseConfig<TVariants>;
161
172
  };
162
-
163
- /** Resolves plugin options with defaults and queue limit rules. */
164
- declare function resolveToastPluginConfig<const TVariants extends readonly string[] = readonly [], const TPositions extends readonly string[] = readonly []>(options?: ToastPluginOptions<TVariants, TPositions>): ResolvedToastPluginConfig<TVariants, TPositions>;
165
- /** Builds typed toast plugin options with inferred variant and position literals. */
166
- declare function toastOptions<const TVariants extends readonly string[] = readonly [], const TPositions extends readonly string[] = readonly [], TContent = unknown>(options: ToastPluginOptions<TVariants, TPositions, TContent>): ToastPluginOptions<TVariants, TPositions, TContent>;
167
- /** Declares toast variant names with full literal inference. */
168
- declare function toastVariants<const T extends readonly string[]>(variants: T): T;
169
- /** Declares toast position names with full literal inference. */
170
- declare function toastPositions<const T extends readonly string[]>(positions: T): T;
171
-
172
- /** Variant names that cannot override core `$toast` methods. */
173
- declare const RESERVED_TOAST_MAGIC_KEYS: Set<string>;
174
- /** Builds the callable `$toast` magic API backed by the internal toast store. */
175
- declare function createToastMagic<const TVariants extends readonly string[], const TPositions extends readonly string[] = readonly [], TContent = unknown>(config: ResolvedToastPluginConfig<TVariants, TPositions>, getStore: () => ToastStore<TVariants, TPositions, TContent>): ToastMagic<TVariants, TPositions, TContent>;
176
-
173
+ /**
174
+ * Source of a toast transition informs subscribers why a change
175
+ * happened. Single source of truth for the `change` event's `source`
176
+ * field; adding a new member ripples through every consumer so
177
+ * exhaustiveness is enforced by TypeScript.
178
+ *
179
+ * Public: branching on `detail.source` is a contract.
180
+ */
181
+ type ToastChangeSource = "initialization" | "push" | "pushUnique" | "update" | "dismiss" | "dismissAt" | "dismissAll";
182
+ /**
183
+ * Structured payload delivered to subscribers on every transition.
184
+ *
185
+ * - `source` discriminates the kind of transition.
186
+ * - `items` is the full snapshot Alpine's reactive proxy mirrors
187
+ * the array reference (replacing, not mutating in place) so
188
+ * template `x-for` loops see the new contents.
189
+ */
190
+ interface ToastChangeDetail<TVariants extends readonly string[] = readonly [], TPositions extends readonly string[] = readonly [], TContent = unknown> {
191
+ readonly source: ToastChangeSource;
192
+ readonly items: ToastItem<TVariants, TPositions, TContent>[];
193
+ }
194
+ /** Options accepted by {@link createToastController}. */
195
+ interface CreateToastControllerOptions<TPositions extends readonly string[] = readonly [], _TContent = unknown> {
196
+ /**
197
+ * Stable identifier exposed via {@link ToastController.id}. When
198
+ * omitted, the controller generates one from the controller name.
199
+ * Tests typically pin this for deterministic assertions.
200
+ */
201
+ readonly id?: string;
202
+ /** Default position for new toasts when payload omits it. */
203
+ readonly defaultPosition?: ToastPosition<TPositions>;
204
+ /** Declared positions — each gets its own stack. */
205
+ readonly positions?: TPositions;
206
+ /** Default auto-dismiss duration in milliseconds. */
207
+ readonly defaultDuration?: number;
208
+ /** Maximum toasts in the queue. `0` = unlimited. */
209
+ readonly maxToasts?: number;
210
+ /** Maximum toasts shown at once. Defaults to `maxToasts`. */
211
+ readonly maxVisible?: number;
212
+ /** Listen for `toast` window events. Default: `true`. */
213
+ readonly listenToWindowEvents?: boolean;
214
+ /** Internal store key. Default: `"toast"`. */
215
+ readonly storeKey?: ToastStoreKey;
216
+ /**
217
+ * Reactive store accessor — maintained for backwards compatibility
218
+ * with the pre-controller architecture. The auto-dismiss timer
219
+ * routes through this accessor when provided, so callers can wrap
220
+ * the store in a proxy and observe timer-fired dismissals.
221
+ */
222
+ readonly getStore?: () => ToastStore<readonly [], TPositions, unknown>;
223
+ }
224
+ /**
225
+ * Public, framework-agnostic manager returned by {@link createToastController}.
226
+ *
227
+ * Reads flow through getters; mutations go through the manager so
228
+ * subscriptions and the in-place snapshot stay consistent.
229
+ *
230
+ * The Alpine integration subscribes to the `change` event and
231
+ * mirrors the snapshot into the reactive store so bindings re-render
232
+ * automatically. Standalone consumers can wire their own adapter via
233
+ * `manager.on("change", detail => ...)`.
234
+ */
235
+ interface ToastManager<TVariants extends readonly string[] = readonly [], TPositions extends readonly string[] = readonly [], TContent = unknown> {
236
+ /** Default position for new toasts when payload omits it. */
237
+ readonly defaultPosition: ToastPosition<TPositions>;
238
+ /** Declared positions with an independent stack each. */
239
+ readonly stackPositions: readonly ToastPosition<TPositions>[];
240
+ /** Maximum toasts in the queue. `0` = unlimited. */
241
+ readonly maxToasts: number;
242
+ /** Maximum toasts shown at once. */
243
+ readonly maxVisible: number;
244
+ /** Live snapshot of every toast (newest first). */
245
+ readonly items: ToastItem<TVariants, TPositions, TContent>[];
246
+ /** Pushes a new toast and returns its id. */
247
+ push(payload?: ToastPayload<TVariants, TPositions, TContent>): string;
248
+ /**
249
+ * Dismisses every active toast with the same `key`, then pushes.
250
+ * Useful for undo flows and single-slot notices.
251
+ */
252
+ pushUnique(key: string, payload?: ToastPayload<TVariants, TPositions, TContent>): string;
253
+ /** Patches a toast in place by id. Resets the auto-dismiss timer if `duration` changes. */
254
+ update(id: string, payload?: Partial<ToastPayload<TVariants, TPositions, TContent>>): void;
255
+ /** Marks a toast as removed; purge happens after a short delay. */
256
+ dismiss(id: string): void;
257
+ /** Marks every toast at `position` as removed. */
258
+ dismissAt(position: ToastPosition<TPositions>): void;
259
+ /** Marks every toast as removed. */
260
+ dismissAll(): void;
261
+ /** Toasts at `position`, newest first (includes exiting `removed` items). */
262
+ itemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];
263
+ /** Timed stack at `position` (includes exiting `removed` items). */
264
+ timedItemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];
265
+ /** Persistent stack at `position` (includes exiting `removed` items). */
266
+ persistentItemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];
267
+ /** Active timed toasts only — preferred for `x-for` render lists. */
268
+ activeTimedItemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];
269
+ /** Active persistent toasts only — preferred for `x-for` render lists. */
270
+ activePersistentItemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];
271
+ /** Whether the timed toast at `index` (within `timedItemsAt`) should render. */
272
+ isVisibleAt(position: ToastPosition<TPositions>, index: number): boolean;
273
+ /**
274
+ * Subscribes to a `change` event. Returns an unsubscribe function.
275
+ * The detail payload carries `source` and `items` (full snapshot).
276
+ */
277
+ on(event: "change", listener: (detail: ToastChangeDetail<TVariants, TPositions, TContent>) => void): Unsubscribe;
278
+ /** Tears down listeners and timers. Idempotent. */
279
+ destroy(): void;
280
+ }
281
+ /**
282
+ * Typed view of `Alpine` the toast plugin uses internally.
283
+ *
284
+ * Built from the toolkit's {@link Alpine} generic with the `toast`
285
+ * store mapped to its concrete {@link ToastStore} shape. A real
286
+ * `Alpine` runtime is assignable to `ToastAlpine` without a cast
287
+ * because the toolkit's `Alpine<Stores>` only adds overloads.
288
+ *
289
+ * The optional `cleanup?` member mirrors theme/lang/scroll's
290
+ * integrations so `controller.destroy()` can be forwarded through
291
+ * Alpine's lifecycle when available.
292
+ */
293
+ type ToastAlpine = Alpine<{
294
+ toast: ToastStore;
295
+ }> & {
296
+ /** Forwarded through Alpine's cleanup mechanism when available. */
297
+ cleanup?(callback: () => void): void;
298
+ };
299
+ /**
300
+ * `Alpine.plugin()` callback signature.
301
+ *
302
+ * Typed against the base {@link AlpineBase} via the toolkit's
303
+ * {@link PluginCallback} generic, which keeps this alias structurally
304
+ * assignable to `Base.PluginCallback`. The plugin narrows the
305
+ * runtime instance to {@link ToastAlpine} inside the function body
306
+ * for typed access to the `"toast"` store / magic.
307
+ */
308
+ type ToastPluginCallback = PluginCallback<Alpine$1>;
309
+ /** Backwards-compat alias for {@link CreateToastControllerOptions}. */
177
310
  interface CreateToastStoreOptions<TPositions extends readonly string[] = readonly []> {
178
311
  defaultPosition?: ToastPosition<TPositions>;
179
312
  /** Declared positions — each gets its own stack. */
@@ -184,6 +317,203 @@ interface CreateToastStoreOptions<TPositions extends readonly string[] = readonl
184
317
  /** Reactive store accessor — required for Alpine auto-dismiss timers. */
185
318
  getStore?: () => ToastStore<readonly [], TPositions, unknown>;
186
319
  }
320
+
321
+ /**
322
+ * Strongly-typed event map for the toast controller.
323
+ *
324
+ * Per the toolkit convention (see `@ailuracode/alpine-theme` and
325
+ * `@ailuracode/alpine-lang`), the event map is the small surface
326
+ * this module owns; the detail types live in `./types.ts` so the
327
+ * manager interface in that module can reference them without an
328
+ * `events.ts ↔ types.ts` import cycle.
329
+ *
330
+ * The controller emits a single `change` event after every state
331
+ * mutation (push, update, dismiss, dismissAt, dismissAll,
332
+ * pushUnique). The Alpine adapter subscribes to this one event and
333
+ * mirrors the `items` snapshot into the reactive store proxy.
334
+ *
335
+ * `source` discriminates the kind of transition so subscribers can
336
+ * branch on intent (e.g. animations might react differently to
337
+ * `push` vs `dismiss`).
338
+ *
339
+ * The event map is parameterized by `TPositions` and `TContent` so
340
+ * `BaseController.emit` infers the right `ToastChangeDetail` shape
341
+ * for each generic instantiation of the controller.
342
+ */
343
+
344
+ /**
345
+ * Event map consumed by `BaseController<ToastEvents>`. Single-key
346
+ * contract: every transition emits `change` with the same
347
+ * {@link ToastChangeDetail} payload.
348
+ */
349
+ interface ToastEvents<TPositions extends readonly string[] = readonly [], TContent = unknown> extends Record<string, unknown> {
350
+ change: ToastChangeDetail<readonly [], TPositions, TContent>;
351
+ }
352
+ /**
353
+ * Subscriber callback for the `change` event. Hardcoded to the
354
+ * listener signature `(detail: ToastChangeDetail) => void` rather
355
+ * than indexed via `ToastEvents['change']` because that indexer
356
+ * returns the *payload* type, not the *callback* type. Keeping it
357
+ * explicit avoids the silent payload-vs-callback swap.
358
+ */
359
+ type ToastListener<TPositions extends readonly string[] = readonly [], TContent = unknown> = (detail: ToastChangeDetail<readonly [], TPositions, TContent>) => void;
360
+
361
+ /**
362
+ * Toast controller — the framework-agnostic core of
363
+ * `@ailuracode/alpine-toast`. Owns every piece of toast queue
364
+ * state and is the single source of truth for the
365
+ * `items` array, the auto-dismiss timers, and the position /
366
+ * variant filtering logic.
367
+ *
368
+ * Responsibilities:
369
+ *
370
+ * 1. **State** — owns `items`, `defaultPosition`, `stackPositions`,
371
+ * `maxToasts`, `maxVisible`. Mutations always produce a fresh
372
+ * `items` array (immutable replacement) so Alpine's reactive
373
+ * proxy can observe the change.
374
+ * 2. **Timers** — schedules auto-dismiss timers per timed toast.
375
+ * Timers are tracked internally and cleared on `destroy()`
376
+ * via `registerCleanup()` so the BaseController lifecycle
377
+ * covers them.
378
+ * 3. **Queue limits** — enforces `maxToasts` per (position, stack)
379
+ * pair on every `push` / `update` (when position or duration
380
+ * flips between timed ↔ persistent).
381
+ * 4. **Subscriptions** — typed `on('change', listener)` from the
382
+ * inherited bus, with the toast-level detail shape (`source`
383
+ * discriminator + full `items` snapshot).
384
+ *
385
+ * Construction rules:
386
+ *
387
+ * - The constructor MUST NOT touch `window`, `document`, or timers.
388
+ * Browser-side wiring (the window `toast` event listener) lives
389
+ * in `mount()`.
390
+ * - The factory `createToastController()` auto-mounts so callers
391
+ * receive a fully-initialized instance.
392
+ * - `destroy()` MUST be idempotent and MUST clear every pending
393
+ * timer.
394
+ */
395
+
396
+ /**
397
+ * Public entrypoint — builds and mounts a fully-initialized
398
+ * {@link ToastController}. The constructor stays pure; the factory
399
+ * wires the browser-touching `mount()` step.
400
+ *
401
+ * Singleton guarantee: at most one live `ToastController` per
402
+ * document. Repeated calls return the existing instance; the
403
+ * controller's `destroy()` releases the slot so the next call
404
+ * builds a fresh one. Direct `new ToastController(...)` is still
405
+ * supported for tests and advanced consumers — only the
406
+ * `createToastController()` factory enforces uniqueness.
407
+ */
408
+ declare function createToastController<const TPositions extends readonly string[] = readonly [], TContent = unknown>(options?: CreateToastControllerOptions<TPositions, TContent>): ToastController<TPositions, TContent>;
409
+ /**
410
+ * Headless controller for `@ailuracode/alpine-toast`. Owns every
411
+ * piece of toast queue state. The Alpine integration in
412
+ * `plugin.ts` subscribes to the controller's `change` event and
413
+ * mirrors the snapshot into the reactive store so bindings
414
+ * re-render automatically.
415
+ *
416
+ * Standalone consumers (non-Alpine) can `createToastController()`
417
+ * directly and wire their own adapter via
418
+ * `manager.on("change", detail => ...)`.
419
+ */
420
+ declare class ToastController<const TPositions extends readonly string[] = readonly [], TContent = unknown> extends BaseController<ToastEvents<TPositions, TContent>> {
421
+ #private;
422
+ constructor(options: CreateToastControllerOptions<TPositions, TContent>);
423
+ /**
424
+ * Tears down every side effect. Idempotent. `super.destroy()` runs
425
+ * the registered cleanups (currently just the window listener)
426
+ * first; the timer cleanup runs as a final step. Also releases
427
+ * the singleton slot so the next `createToastController()` call
428
+ * builds a fresh controller.
429
+ */
430
+ destroy(): void;
431
+ /**
432
+ * Starts the controller's side effects. The constructor leaves
433
+ * `#items` empty; `mount()` registers the `toast` window event
434
+ * listener (when enabled) and emits the initialization event.
435
+ *
436
+ * Calling `mount()` more than once is a no-op — `BaseController`
437
+ * guards the phase. Calling it after `destroy()` throws.
438
+ */
439
+ mount(): void;
440
+ get defaultPosition(): ToastPosition<TPositions>;
441
+ get stackPositions(): readonly ToastPosition<TPositions>[];
442
+ get maxToasts(): number;
443
+ get maxVisible(): number;
444
+ get items(): ToastItem<readonly [], TPositions, TContent>[];
445
+ push(payload?: ToastPayload<readonly [], TPositions, TContent>): string;
446
+ pushUnique(key: string, payload?: ToastPayload<readonly [], TPositions, TContent>): string;
447
+ update(id: string, payload?: Partial<ToastPayload<readonly [], TPositions, TContent>>): void;
448
+ dismiss(id: string): void;
449
+ dismissAt(position: ToastPosition<TPositions>): void;
450
+ dismissAll(): void;
451
+ itemsAt(position: ToastPosition<TPositions>): ToastItem<readonly [], TPositions, TContent>[];
452
+ timedItemsAt(position: ToastPosition<TPositions>): ToastItem<readonly [], TPositions, TContent>[];
453
+ persistentItemsAt(position: ToastPosition<TPositions>): ToastItem<readonly [], TPositions, TContent>[];
454
+ activeTimedItemsAt(position: ToastPosition<TPositions>): ToastItem<readonly [], TPositions, TContent>[];
455
+ activePersistentItemsAt(position: ToastPosition<TPositions>): ToastItem<readonly [], TPositions, TContent>[];
456
+ isVisibleAt(position: ToastPosition<TPositions>, index: number): boolean;
457
+ /**
458
+ * Public escape hatch for callers (mainly the magic's `fromPayload`)
459
+ * that need to push a toast from a raw `ToastEventPayload` shape.
460
+ */
461
+ fromPayload(payload?: ToastPayload<readonly [], TPositions, TContent>): string;
462
+ }
463
+ /**
464
+ * Wraps a {@link ToastController} in the {@link ToastStore} surface.
465
+ * The store's reads delegate to the controller; mutations go
466
+ * through the controller's semantic commands.
467
+ *
468
+ * The wrapper subscribes to the controller's `change` event so its
469
+ * own `items` property stays in sync with the controller's queue —
470
+ * that subscription is what keeps standalone consumers (`store.items`
471
+ * reads in tests, scripts) up to date. Alpine consumers also benefit
472
+ * because the wrapper's `items` is a regular settable property,
473
+ * which means Alpine's reactive proxy can intercept assignments
474
+ * through its SET trap and trigger template re-renders.
475
+ *
476
+ * The Alpine adapter (`plugin.ts`) registers its own subscription
477
+ * that mirrors changes into the proxy via the SET trap — that is
478
+ * what triggers Alpine's reactivity. The wrapper's own subscription
479
+ * keeps `store.items` fresh in standalone use and provides a
480
+ * redundant but safe update path in Alpine use (Alpine's SET trap
481
+ * still fires because the proxy's cached value lags the target's
482
+ * direct mutation).
483
+ *
484
+ * `destroy()` unsubscribes the internal listener AND forwards to
485
+ * the controller's destroy so callers have one entry point.
486
+ *
487
+ * Used both by `toastPlugin` (to register with Alpine) and by the
488
+ * standalone {@link createToastStore} factory.
489
+ */
490
+ declare function wrapToastStore<const TPositions extends readonly string[] = readonly [], TContent = unknown>(controller: ToastController<TPositions, TContent>): ToastStore<readonly [], TPositions, TContent>;
491
+ /**
492
+ * Standalone factory — creates a fresh (non-singleton)
493
+ * {@link ToastController} and returns the {@link ToastStore}
494
+ * surface. Useful for tests, scripts, and non-Alpine consumers
495
+ * that need a one-off queue.
496
+ *
497
+ * Each call returns a NEW controller; for the document-level
498
+ * singleton pattern, use {@link createToastController} instead.
499
+ */
500
+ declare function createToastStore<const TPositions extends readonly string[] = readonly [], TContent = unknown>(options?: CreateToastControllerOptions<TPositions, TContent>): ToastStore<readonly [], TPositions, TContent>;
501
+ /**
502
+ * Timed duration for `$toast.promise` loading state.
503
+ * Stays in the timed stack; the timer is replaced when the promise
504
+ * settles. Exported from `./index.ts` so consumers can compare
505
+ * against the sentinel without importing the controller module.
506
+ */
507
+ declare const PROMISE_LOADING_DURATION = 3600000;
508
+ /** Canonical persistent value — `0` is normalized to `false`. */
509
+ declare function normalizeToastDuration(duration: ToastDuration): ToastDuration;
510
+ /** Resolves payload duration — `false` / `0` persist; `undefined` uses the default. */
511
+ declare function resolveToastDuration(duration: ToastDuration | undefined, defaultDuration: number): ToastDuration;
512
+ /** Whether the toast should schedule an auto-dismiss timer. */
513
+ declare function shouldAutoDismiss(duration: ToastDuration): duration is number;
514
+ /** Persistent toasts (`duration: false` / `0`) use a separate UI stack from timed toasts. */
515
+ declare function isPersistentDuration(duration: ToastDuration): boolean;
516
+ /** Resolves `maxToasts` / `maxVisible` with the standard clamp rule. */
187
517
  declare function resolveToastLimits(options?: {
188
518
  maxToasts?: number;
189
519
  maxVisible?: number;
@@ -193,33 +523,53 @@ declare function resolveToastLimits(options?: {
193
523
  };
194
524
  /** Unique stack keys: built-in default plus configured positions. */
195
525
  declare function resolveStackPositions<TPositions extends readonly string[]>(defaultPosition: ToastPosition<TPositions>, positions?: TPositions): readonly ToastPosition<TPositions>[];
196
- /** Canonical persistent value — `0` is normalized to `false`. */
197
- declare function normalizeToastDuration(duration: ToastDuration): ToastDuration;
198
- /** Resolves payload duration — `false` / `0` persist; `undefined` uses the default. */
199
- declare function resolveToastDuration(duration: ToastDuration | undefined, defaultDuration: number): ToastDuration;
200
- /** Whether the toast should schedule an auto-dismiss timer. */
201
- declare function shouldAutoDismiss(duration: ToastDuration): duration is number;
202
- /** Persistent toasts (`duration: false` / `0`) use a separate UI stack from timed toasts. */
203
- declare function isPersistentDuration(duration: ToastDuration): boolean;
526
+
204
527
  /**
205
- * Timed duration for `$toast.promise` loading state.
206
- * Stays in the timed stack; the timer is replaced when the promise settles.
528
+ * Alpine.js integration for `@ailuracode/alpine-toast`.
529
+ *
530
+ * Thin adapter that wires {@link ToastController} into `$store.toast`
531
+ * and the `$toast` magic. Every command forwards to the controller
532
+ * (see `AGENTS.md` for the integration contract).
207
533
  */
208
- declare const PROMISE_LOADING_DURATION = 3600000;
209
- /** Creates the internal reactive toast queue consumed by `$toast` and UI integrators. */
210
- declare function createToastStore<const TPositions extends readonly string[] = readonly [], TContent = unknown>(options?: CreateToastStoreOptions<TPositions>): ToastStore<readonly [], TPositions, TContent>;
211
534
 
212
- /** Alpine.js toast plugin. Registers magic `$toast` with an internal reactive queue. CSS-framework agnostic — no markup or styles. */
213
- declare function toastPlugin<const TVariants extends readonly string[] = readonly [], const TPositions extends readonly string[] = readonly [], TContent = unknown>(optionsOrAlpine?: ToastPluginOptions<TVariants, TPositions, TContent> | AlpineType.Alpine): undefined | ((Alpine: AlpineType.Alpine) => void);
214
- declare global {
215
- namespace Alpine {
216
- interface Stores {
217
- toast: ToastStore;
218
- }
219
- interface Magics<T> {
220
- $toast: ToastMagic;
221
- }
222
- }
223
- }
535
+ /** Variant names that cannot override core `$toast` methods. */
536
+ declare const RESERVED_TOAST_MAGIC_KEYS: Set<string>;
537
+ /** Resolves plugin options with defaults and queue limit rules. */
538
+ declare function resolveToastPluginConfig<const TVariants extends readonly string[] = readonly [], const TPositions extends readonly string[] = readonly []>(options?: ToastPluginOptions<TVariants, TPositions>): ResolvedToastPluginConfig<TVariants, TPositions>;
539
+ /** Builds typed toast plugin options with inferred variant and position literals. */
540
+ declare function toastOptions<const TVariants extends readonly string[] = readonly [], const TPositions extends readonly string[] = readonly [], TContent = unknown>(options: ToastPluginOptions<TVariants, TPositions, TContent>): ToastPluginOptions<TVariants, TPositions, TContent>;
541
+ /** Declares toast variant names with full literal inference. */
542
+ declare function toastVariants<const T extends readonly string[]>(variants: T): T;
543
+ /** Declares toast position names with full literal inference. */
544
+ declare function toastPositions<const T extends readonly string[]>(positions: T): T;
545
+ /**
546
+ * Plugin factory — returns the `Alpine.plugin()` callback. Pass
547
+ * {@link ToastPluginOptions} to configure {@link ToastController},
548
+ * or `{}` for the package defaults. See `AGENTS.md` for the
549
+ * integration contract.
550
+ */
551
+ declare function toastPlugin<const TVariants extends readonly string[] = readonly [], const TPositions extends readonly string[] = readonly [], TContent = unknown>(options?: ToastPluginOptions<TVariants, TPositions, TContent>): ToastPluginCallback;
552
+ /**
553
+ * Wraps a {@link ToastController} in the {@link ToastStore} surface
554
+ * that Alpine consumers (templates, `$store.toast.*` references)
555
+ * see. The store's reads delegate to the controller; mutations go
556
+ * through the controller's semantic commands.
557
+ *
558
+ * The store is intentionally a thin object literal — every field is
559
+ * a direct getter into the controller, and every method is a one-line
560
+ * delegation. Splitting helpers would add indirection without buying
561
+ * anything because the controller already exposes the entire surface.
562
+ *
563
+ * The implementation lives in `./controller.ts` (see
564
+ * {@link wrapToastStore}) so both `toastPlugin` and the standalone
565
+ * `createToastStore` factory can share it.
566
+ */
567
+ /**
568
+ * Builds the callable `$toast` magic API. The magic delegates every
569
+ * command to the store accessor passed in by the caller — typically
570
+ * `() => Alpine.store("toast")` so the magic stays reactive, but
571
+ * tests inject their own store.
572
+ */
573
+ declare function createToastMagic<const TVariants extends readonly string[], const TPositions extends readonly string[] = readonly [], TContent = unknown>(config: ResolvedToastPluginConfig<TVariants, TPositions>, getStore: () => ToastStore<TVariants, TPositions, TContent>): ToastMagic<TVariants, TPositions, TContent>;
224
574
 
225
- export { type DefaultToastPosition, type DefaultToastVariant, PROMISE_LOADING_DURATION, RESERVED_TOAST_MAGIC_KEYS, type ResolvedPromiseConfig, type ResolvedToastPluginConfig, TOAST_STORE_KEY, type ToastAction, type ToastDuration, type ToastEventPayload, type ToastItem, type ToastMagic, type ToastPayload, type ToastPayloadWithoutVariant, type ToastPluginOptions, type ToastPosition, type ToastPromiseInput, type ToastPromiseMessages, type ToastPromiseOptions, type ToastStore, type ToastStoreKey, type ToastVariant, type ToastVariantMethods, createToastMagic, createToastStore, toastPlugin as default, isPersistentDuration, normalizeToastDuration, resolveStackPositions, resolveToastDuration, resolveToastLimits, resolveToastPluginConfig, shouldAutoDismiss, toastOptions, toastPositions, toastVariants };
575
+ export { type CreateToastControllerOptions, type CreateToastStoreOptions, type DefaultToastPosition, type DefaultToastVariant, PROMISE_LOADING_DURATION, RESERVED_TOAST_MAGIC_KEYS, type ResolvedPromiseConfig, type ResolvedToastPluginConfig, TOAST_STORE_KEY, type ToastAction, type ToastAlpine, type ToastChangeDetail, type ToastChangeSource, ToastController, type ToastDuration, type ToastEventPayload, type ToastEvents, type ToastItem, type ToastListener, type ToastMagic, type ToastManager, type ToastPayload, type ToastPayloadWithoutVariant, type ToastPluginCallback, type ToastPluginOptions, type ToastPosition, type ToastPromiseInput, type ToastPromiseMessages, type ToastPromiseOptions, type ToastStore, type ToastStoreKey, type ToastVariant, type ToastVariantMethods, createToastController, createToastMagic, createToastStore, toastPlugin as default, isPersistentDuration, normalizeToastDuration, resolveStackPositions, resolveToastDuration, resolveToastLimits, resolveToastPluginConfig, shouldAutoDismiss, toastOptions, toastPlugin, toastPositions, toastVariants, wrapToastStore };