castle-web-sdk 0.4.9 → 0.4.10

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/README.md CHANGED
@@ -20,6 +20,7 @@ import { setup, initCard, Storage, Leaderboard } from "castle-web-sdk";
20
20
  - [User](#user)
21
21
  - [Pass](#pass)
22
22
  - [Portal](#portal)
23
+ - [Haptics](#haptics)
23
24
  - [Lifecycle](#lifecycle)
24
25
  - [Setup](#setup)
25
26
  - [CastleError](#castleerror)
@@ -269,6 +270,41 @@ link.addEventListener("pointerenter", () => {
269
270
  });
270
271
  ```
271
272
 
273
+ ## Haptics
274
+
275
+ `Haptics` plays a short device vibration ("buzz") for tactile feedback —
276
+ a tap confirmation, a success chime, an error shake. The host owns the
277
+ effect: the Castle mobile app plays a native haptic, the website uses the
278
+ browser's vibration API where available, and the dev server or an
279
+ unsupported device does nothing.
280
+
281
+ ### `Haptics.play(style): Promise<HapticsResult>`
282
+
283
+ Plays a haptic in one of seven styles:
284
+
285
+ - `'light'`, `'medium'`, `'heavy'` — impact taps of increasing strength.
286
+ - `'selection'` — a light tick, e.g. moving through options.
287
+ - `'success'`, `'warning'`, `'error'` — notification patterns.
288
+
289
+ Usually you don't await it — fire it and move on:
290
+
291
+ ```js
292
+ button.onclick = () => {
293
+ Haptics.play("light");
294
+ doTheThing();
295
+ };
296
+ ```
297
+
298
+ The returned `HapticsResult` has a `status`, if you want to branch on it:
299
+
300
+ - `'triggered'` — the host played (or accepted) the haptic.
301
+ - `'unavailable'` — this host or device can't play haptics (e.g. the dev
302
+ server, or a browser with no vibration support). Nothing was played.
303
+
304
+ Haptics respect the player's settings — if a player has muted haptics,
305
+ `play` does nothing and resolves `'unavailable'`. Rapid repeated calls may
306
+ be coalesced, so it's safe to call on frequent events.
307
+
272
308
  ## Lifecycle
273
309
 
274
310
  `Lifecycle` tells the host when the deck has painted its first frame, so
package/dist/castle.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export { isEdit } from "./context";
2
2
  export { CastleError } from "./errors";
3
+ export { Haptics } from "./haptics";
4
+ export type { CastleHapticsApi, HapticsResult, HapticsStatus, HapticStyle } from "./haptics";
3
5
  export { Leaderboard } from "./leaderboard";
4
6
  export type { LeaderboardData, LeaderboardEntry, LeaderboardOptions, LeaderboardScope, LeaderboardSort, } from "./leaderboard";
5
7
  export { Lifecycle } from "./lifecycle";
package/dist/castle.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // Castle Web SDK
2
2
  export { isEdit } from "./context";
3
3
  export { CastleError } from "./errors";
4
+ export { Haptics } from "./haptics";
4
5
  export { Leaderboard } from "./leaderboard";
5
6
  export { Lifecycle } from "./lifecycle";
6
7
  export { Pass } from "./passes";
@@ -32,6 +32,11 @@ export type PortalPrefetchStatus = "prefetching" | "rejected" | "unavailable";
32
32
  export interface PortalPrefetchResult {
33
33
  status: PortalPrefetchStatus;
34
34
  }
35
+ export type HapticStyle = "light" | "medium" | "heavy" | "selection" | "success" | "warning" | "error";
36
+ export type HapticsStatus = "triggered" | "unavailable";
37
+ export interface HapticsResult {
38
+ status: HapticsStatus;
39
+ }
35
40
  export interface CommandParams {
36
41
  "deckStorage.load": Record<string, never>;
37
42
  "deckStorage.update": {
@@ -71,6 +76,9 @@ export interface CommandParams {
71
76
  "portal.prefetch": {
72
77
  targetDeckId: string;
73
78
  };
79
+ "haptics.play": {
80
+ style: HapticStyle;
81
+ };
74
82
  }
75
83
  export interface CommandResult {
76
84
  "deckStorage.load": {
@@ -109,6 +117,7 @@ export interface CommandResult {
109
117
  "pass.offer": PassOfferResult;
110
118
  "portal.open": PortalOpenResult;
111
119
  "portal.prefetch": PortalPrefetchResult;
120
+ "haptics.play": HapticsResult;
112
121
  }
113
122
  export type CommandName = keyof CommandParams;
114
123
  export interface SerializedCommandError {
@@ -0,0 +1,6 @@
1
+ import type { HapticStyle, HapticsResult } from "./commands";
2
+ export type { HapticStyle, HapticsResult, HapticsStatus } from "./commands";
3
+ export interface CastleHapticsApi {
4
+ play(style: HapticStyle): Promise<HapticsResult>;
5
+ }
6
+ export declare const Haptics: CastleHapticsApi;
@@ -0,0 +1,36 @@
1
+ // Haptics — a deck-facing capability for playing a device haptic (a "buzz").
2
+ // Like pass and portal, the deck stays capability-AGNOSTIC: it asks for a
3
+ // haptic and gets back one normalized outcome regardless of platform. The host
4
+ // owns the effect:
5
+ // - mobile app : plays a native haptic (Taptic Engine / VibrationEffect),
6
+ // subject to the host's own rate-limiting and device support
7
+ // - web player : best-effort navigator.vibrate; `unavailable` where the
8
+ // browser has no vibration API (e.g. iOS Safari)
9
+ // - dev CLI : no host handler, so `unavailable`
10
+ // A haptic is a fleeting device effect, not deck-scoped state, so unlike
11
+ // pass/portal the host requires no deckId. Decks usually fire-and-forget (don't
12
+ // await); the returned status just says whether the host could play it.
13
+ import { CastleError } from "./errors";
14
+ import { hostRequest } from "./transport";
15
+ const HAPTIC_STYLES = [
16
+ "light",
17
+ "medium",
18
+ "heavy",
19
+ "selection",
20
+ "success",
21
+ "warning",
22
+ "error",
23
+ ];
24
+ export const Haptics = {
25
+ play,
26
+ };
27
+ async function play(style) {
28
+ if (!HAPTIC_STYLES.includes(style)) {
29
+ throw new CastleError({
30
+ code: "INVALID_ARGUMENT",
31
+ message: `Haptics.play style must be one of: ${HAPTIC_STYLES.join(", ")}.`,
32
+ operation: "Haptics.play",
33
+ });
34
+ }
35
+ return hostRequest("haptics.play", { style });
36
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "castle-web-sdk",
3
- "version": "0.4.9",
3
+ "version": "0.4.10",
4
4
  "type": "module",
5
5
  "main": "dist/castle.js",
6
6
  "types": "dist/castle.d.ts",