@snap/react-camera-kit 0.1.0 → 0.2.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/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @snap/react-camera-kit
2
2
 
3
- React Camera Kit for web applications.
3
+ The official React wrapper for the [Camera Kit Web SDK](https://developers.snap.com/camera-kit/integrate-sdk/web/web-configuration). It provides declarative components and hooks that handle SDK bootstrapping, session lifecycle, media sources, and Lens management — so you can integrate Snap AR into React apps with minimal boilerplate.
4
4
 
5
- **[Live Demo](https://snapchat.github.io/react-camera-kit/)**
5
+ **[Live Demo](https://snapchat.github.io/react-camera-kit/)** · **[Camera Kit Docs](https://developers.snap.com/camera-kit/integrate-sdk/web/guides/react-camera-kit)**
6
6
 
7
7
  ## Installation
8
8
 
@@ -10,107 +10,373 @@ React Camera Kit for web applications.
10
10
  npm install @snap/react-camera-kit @snap/camera-kit
11
11
  ```
12
12
 
13
- ## Prerequisites
13
+ ### Requirements
14
14
 
15
- Before using this package, complete Camera Kit Web setup and obtain:
15
+ - `@snap/camera-kit` `^1.13.0` (peer dependency)
16
+ - `react` `>=16.8.0` and `react-dom` `>=16.8.0`
17
+ - `rxjs` `>=7`
18
+ - `https://` for deployed apps (`http://localhost` works for local development)
16
19
 
17
- - `apiToken`
18
- - `lensId`
19
- - `lensGroupId`
20
- - `https://` for deployed apps (`http://localhost` should works for local dev)
20
+ You'll need a Camera Kit API token, Lens ID, and Lens Group ID from the [Snap Developer Portal](https://kit.snapchat.com/manage). See [Setting Up Accounts](https://developers.snap.com/camera-kit/getting-started/setting-up-accounts) if you're new to Camera Kit.
21
21
 
22
- Full setup guides:
22
+ ## Quick start
23
23
 
24
- - Camera Kit Web configuration: https://developers.snap.com/camera-kit/integrate-sdk/web/web-configuration
25
- - `@snap/camera-kit` docs: https://www.npmjs.com/package/@snap/camera-kit
24
+ ```tsx
25
+ import { CameraKitProvider, LensPlayer } from "@snap/react-camera-kit";
26
26
 
27
- ## Compatibility
27
+ function App() {
28
+ return (
29
+ <CameraKitProvider apiToken="YOUR_API_TOKEN">
30
+ <LensPlayer lensId="YOUR_LENS_ID" lensGroupId="YOUR_LENS_GROUP_ID" />
31
+ </CameraKitProvider>
32
+ );
33
+ }
34
+ ```
28
35
 
29
- - Requires `@snap/camera-kit` `^1.13.0`, because `1.13.0+` includes the SDK-side font bootstrap behavior needed by this package.
36
+ That's it `CameraKitProvider` initializes the SDK, and `LensPlayer` sets up the camera, applies the Lens, and renders the output canvas.
30
37
 
31
- ## Usage
38
+ ## Components
32
39
 
33
- This package provides a simple API for integrating Camera Kit into React applications.
40
+ ### CameraKitProvider
34
41
 
35
- The simplest use case is:
42
+ The root provider that initializes the Camera Kit SDK. All other components and hooks must be descendants of this provider.
36
43
 
37
44
  ```tsx
38
- <CameraKitProvider apiToken="YOUR_TOKEN">
39
- <LensPlayer lensId="YOUR_LENS_ID" lensGroupId="YOUR_GROUP_ID" />
40
- </CameraKitProvider>
45
+ import { CameraKitProvider, createConsoleLogger } from "@snap/react-camera-kit";
46
+
47
+ <CameraKitProvider apiToken="YOUR_API_TOKEN" logger={createConsoleLogger()} logLevel="info">
48
+ {children}
49
+ </CameraKitProvider>;
41
50
  ```
42
51
 
43
- if you need to render specific canvas with custom layout:
52
+ | Prop | Type | Default | Description |
53
+ | ----------------------------- | ---------------------------------------- | ------------ | ------------------------------------------------------------- |
54
+ | `apiToken` | `string` | **required** | Camera Kit API token |
55
+ | `logger` | `CameraKitLogger` | `noopLogger` | Logger instance — use `createConsoleLogger()` for development |
56
+ | `logLevel` | `"debug" \| "info" \| "warn" \| "error"` | `"info"` | Log verbosity |
57
+ | `renderWhileTabHidden` | `boolean` | `false` | Continue rendering when the browser tab is hidden |
58
+ | `stabilityKey` | `string \| number` | auto | Manual control over when the SDK re-initializes |
59
+ | `extendContainer` | `(container) => container` | — | Customize the SDK's DI container |
60
+ | `createBootstrapEventHandler` | `MetricEventHandlerFactory` | — | Factory for tracking bootstrap success/failure |
61
+
62
+ ### LensPlayer
63
+
64
+ All-in-one component that handles source setup, Lens application, and playback. Defaults to the user's camera if no `source` is provided.
44
65
 
45
66
  ```tsx
46
- <CameraKitProvider apiToken="YOUR_TOKEN">
47
- <LensPlayer lensId="YOUR_LENS_ID" lensGroupId="YOUR_GROUP_ID" canvasType="both">
48
- <div>
49
- <LiveCanvas />
50
- </div>
67
+ <LensPlayer lensId="YOUR_LENS_ID" lensGroupId="YOUR_LENS_GROUP_ID" className="camera-canvas" />
68
+ ```
69
+
70
+ | Prop | Type | Default | Description |
71
+ | ---------------- | ----------------------- | -------------------- | ------------------------------------------------------------------------------------------------ |
72
+ | `lensId` | `string` | — | Lens to apply |
73
+ | `lensGroupId` | `string` | — | Lens Group containing the Lens |
74
+ | `source` | `SourceInput` | `{ kind: "camera" }` | Media source (camera, video, or image) |
75
+ | `outputSize` | `OutputSize` | — | Rendering canvas size |
76
+ | `lensLaunchData` | `LensLaunchData` | — | Launch parameters passed to the Lens |
77
+ | `lensReadyGuard` | `() => Promise<void>` | — | Async guard called while Lens is loading (2s timeout) |
78
+ | `refreshTrigger` | `unknown` | — | When this value changes, the Lens is removed and reapplied |
79
+ | `canvasType` | `"live" \| "capture"` | `"live"` | Which canvas to render. For custom layouts, use `LiveCanvas`/`CaptureCanvas` as children instead |
80
+ | `fpsLimit` | `number` | — | Maximum rendering framerate |
81
+ | `muted` | `boolean` | `false` | Mute audio output |
82
+ | `screenRegions` | `ScreenRegions` | — | Screen regions for Lens-aware UI layout |
83
+ | `onError` | `(error, lens) => void` | — | Callback for playback errors |
84
+ | `className` | `string` | — | CSS class name |
85
+ | `style` | `CSSProperties` | — | Inline styles |
86
+ | `children` | `ReactNode` | — | Custom children (use with `LiveCanvas`/`CaptureCanvas`) |
87
+
88
+ ### LiveCanvas / CaptureCanvas
89
+
90
+ Render the live preview or capture canvas as children of `LensPlayer`:
91
+
92
+ ```tsx
93
+ <LensPlayer lensId="YOUR_LENS_ID" lensGroupId="YOUR_LENS_GROUP_ID">
94
+ <div>
95
+ <LiveCanvas style={{ width: "100%" }} />
96
+ </div>
97
+ <div>
98
+ <CaptureCanvas style={{ width: "100%" }} />
99
+ </div>
100
+ </LensPlayer>
101
+ ```
102
+
103
+ Both accept `className` and `style` props.
104
+
105
+ ## Hooks
106
+
107
+ ### useCameraKit
108
+
109
+ Access the full Camera Kit context — SDK status, source/Lens state, and imperative methods. Must be called within a `CameraKitProvider`.
110
+
111
+ ```tsx
112
+ import { useCameraKit } from "@snap/react-camera-kit";
113
+
114
+ function Controls() {
115
+ const { sdkStatus, lens, lenses, isMuted, toggleMuted, applyLens, removeLens, fetchLenses } = useCameraKit();
116
+
117
+ if (sdkStatus !== "ready") return <p>Loading SDK...</p>;
118
+
119
+ return (
51
120
  <div>
52
- <CaptureCanvas />
121
+ <p>Lens: {lens.lensId ?? "None"}</p>
122
+ <button onClick={toggleMuted}>{isMuted ? "Unmute" : "Mute"}</button>
123
+ <button onClick={removeLens}>Remove Lens</button>
53
124
  </div>
54
- </LensPlayer>
55
- </CameraKitProvider>
125
+ );
126
+ }
127
+ ```
128
+
129
+ **State properties:**
130
+
131
+ | Property | Type | Description |
132
+ | --------------- | --------------------------------------------------------- | --------------------------------------- |
133
+ | `sdkStatus` | `"uninitialized" \| "initializing" \| "ready" \| "error"` | SDK initialization status |
134
+ | `sdkError` | `Error \| undefined` | Error from SDK initialization |
135
+ | `source` | `CurrentSource` | Current source status, input, and error |
136
+ | `lens` | `CurrentLens` | Current Lens status, IDs, and error |
137
+ | `lenses` | `Lens[]` | Array of loaded Lens objects |
138
+ | `liveCanvas` | `HTMLCanvasElement \| undefined` | Live preview canvas element |
139
+ | `captureCanvas` | `HTMLCanvasElement \| undefined` | Capture canvas element |
140
+ | `keyboard` | `Keyboard \| undefined` | Keyboard API for Lens keyboard requests |
141
+ | `isMuted` | `boolean` | Whether audio is muted |
142
+ | `fpsLimit` | `number \| undefined` | Current FPS limit |
143
+ | `screenRegions` | `ScreenRegions \| undefined` | Current screen regions |
144
+
145
+ **Methods:**
146
+
147
+ | Method | Description |
148
+ | ------------------------------------------------------ | ------------------------------------------------------- |
149
+ | `applySource(input, size?)` | Apply a media source (camera, video, or image) |
150
+ | `removeSource()` | Remove the current source |
151
+ | `fetchLens(lensId, groupId)` | Load a single Lens (returns cached if already loaded) |
152
+ | `fetchLenses(groupId)` | Load all Lenses in a group (accepts string or string[]) |
153
+ | `applyLens(lensId, groupId, launchData?, readyGuard?)` | Apply a Lens by ID |
154
+ | `removeLens()` | Remove the current Lens |
155
+ | `refreshLens()` | Remove and reapply the current Lens |
156
+ | `reinitialize()` | Re-bootstrap the SDK (useful after errors) |
157
+ | `setMuted(muted)` | Set the muted state |
158
+ | `toggleMuted()` | Toggle audio mute |
159
+ | `setFPSLimit(fps)` | Set maximum rendering FPS |
160
+ | `setScreenRegions(regions)` | Set screen regions for Lens-aware layout |
161
+
162
+ ### useApplyLens
163
+
164
+ Declaratively apply a Lens — it updates automatically when parameters change.
165
+
166
+ ```tsx
167
+ import { useApplyLens } from "@snap/react-camera-kit";
168
+
169
+ useApplyLens("YOUR_LENS_ID", "YOUR_LENS_GROUP_ID");
56
170
  ```
57
171
 
58
- if you need to access lens status (assuming `CameraKitProvider` context):
172
+ | Parameter | Type | Description |
173
+ | ---------------- | --------------------- | ------------------------------------ |
174
+ | `lensId` | `string \| undefined` | Lens ID — pass `undefined` to remove |
175
+ | `lensGroupId` | `string \| undefined` | Lens Group ID |
176
+ | `lensLaunchData` | `LensLaunchData` | Optional launch parameters |
177
+ | `lensReadyGuard` | `() => Promise<void>` | Optional async ready guard |
178
+
179
+ ### useApplySource
180
+
181
+ Declaratively apply a media source. Defaults to camera if no source is provided.
182
+
183
+ ```tsx
184
+ import { useApplySource } from "@snap/react-camera-kit";
185
+
186
+ // Video source with fixed output size
187
+ useApplySource({ kind: "video", url: "/demo.mp4", autoplay: true }, { mode: "fixed", width: 720, height: 1280 });
188
+ ```
189
+
190
+ | Parameter | Type | Default | Description |
191
+ | ------------ | ------------- | -------------------- | -------------- |
192
+ | `source` | `SourceInput` | `{ kind: "camera" }` | Media source |
193
+ | `outputSize` | `OutputSize` | — | Rendering size |
194
+
195
+ ### usePlaybackOptions
196
+
197
+ Declaratively set playback options.
198
+
199
+ ```tsx
200
+ import { usePlaybackOptions } from "@snap/react-camera-kit";
201
+
202
+ usePlaybackOptions({
203
+ fpsLimit: 30,
204
+ muted: false,
205
+ onError: (error) => console.error("Playback error:", error),
206
+ });
207
+ ```
208
+
209
+ | Option | Type | Description |
210
+ | --------------- | ----------------------- | ------------------------------ |
211
+ | `fpsLimit` | `number` | Maximum rendering FPS |
212
+ | `muted` | `boolean` | Mute audio |
213
+ | `screenRegions` | `ScreenRegions` | Screen regions for Lens layout |
214
+ | `onError` | `(error, lens) => void` | Playback error callback |
215
+
216
+ ## Media sources
217
+
218
+ Pass a `SourceInput` to `LensPlayer`'s `source` prop or to `useApplySource`:
219
+
220
+ ```tsx
221
+ // Camera (default)
222
+ { kind: "camera" }
223
+ { kind: "camera", deviceId: "abc123", options: { cameraFacing: "environment" } }
224
+
225
+ // Video
226
+ { kind: "video", url: "/demo.mp4", autoplay: true }
227
+
228
+ // Image
229
+ { kind: "image", url: "/photo.jpg" }
230
+ ```
231
+
232
+ ### Camera source options
233
+
234
+ | Option | Type | Default | Description |
235
+ | ------------------- | ------------------------- | ------------------------------ | ----------------------------- |
236
+ | `cameraFacing` | `"user" \| "environment"` | `"user"` | Front or back camera |
237
+ | `cameraConstraints` | `MediaTrackConstraints` | `{ width: 1280, height: 720 }` | Camera resolution constraints |
238
+ | `cameraRotation` | `0 \| -90 \| 90 \| 180` | `0` | Camera rotation |
239
+ | `fpsLimit` | `number` | — | Max FPS for the source |
240
+ | `outputSize` | `OutputSize` | — | Rendering canvas size |
241
+
242
+ ### Output size
243
+
244
+ ```tsx
245
+ // Fixed resolution
246
+ { mode: "fixed", width: 720, height: 1280 }
247
+
248
+ // Match input source resolution
249
+ { mode: "match-input" }
250
+ ```
251
+
252
+ ## Handling loading and error states
253
+
254
+ Use `useCameraKit()` to track the status of the SDK, source, and Lens. Each progresses through `"none" → "loading" → "ready"` (or `"error"`):
59
255
 
60
256
  ```tsx
61
257
  function Preview() {
62
- const { lens } = useCameraKit();
258
+ const { sdkStatus, sdkError, source, lens } = useCameraKit();
259
+
260
+ if (sdkStatus === "error") return <p>SDK failed: {sdkError?.message}</p>;
261
+ if (sdkStatus !== "ready") return <p>Initializing...</p>;
262
+ if (source.status === "loading") return <p>Setting up camera...</p>;
263
+ if (lens.status === "error") return <p>Lens error: {lens.error?.message}</p>;
264
+
63
265
  return (
64
- <LensPlayer lensId="YOUR_LENS_ID" lensGroupId="YOUR_GROUP_ID">
65
- {lens.status !== "ready" && lens.status !== "error" && <Spinner />}
66
- {lens.status === "error" && <Error error={lens.error} />}
67
- {lens.status === "ready" && <LiveCanvas />}
266
+ <LensPlayer lensId="YOUR_LENS_ID" lensGroupId="YOUR_LENS_GROUP_ID">
267
+ {lens.status !== "ready" && <div className="spinner" />}
268
+ <LiveCanvas />
68
269
  </LensPlayer>
69
270
  );
70
271
  }
71
272
  ```
72
273
 
73
- When you need full control (assuming `CameraKitProvider` context):
274
+ ### Frame Metrics
275
+
276
+ Use `useLensFrameMetrics` to monitor lens rendering performance:
74
277
 
75
278
  ```tsx
76
- function Preview() {
77
- const { sdkStatus, source, lens } = useCameraKit();
78
- useApplySource({ kind: "video", url: "/demo.mp4" }, { mode: "fixed", width: 720, height: 1280 });
79
- useApplyLens("123", "abc", launchData);
80
- usePlaybackOptions({ onError: (error) => console.error(error) });
279
+ import { useLensFrameMetrics } from "@snap/react-camera-kit";
81
280
 
82
- if (sdkStatus !== "ready" || source.status !== "ready" || lens.status !== "ready") {
83
- return <Spinner />;
84
- }
85
- return <CaptureCanvas className="rounded-xl" />;
281
+ function PerformanceOverlay() {
282
+ const metrics = useLensFrameMetrics({ interval: 500 });
283
+
284
+ if (!metrics) return null;
285
+
286
+ return (
287
+ <div>
288
+ <p>FPS: {metrics.avgFps.toFixed(1)}</p>
289
+ <p>Frame time: {metrics.lensFrameProcessingTimeMsAvg.toFixed(1)}ms</p>
290
+ </div>
291
+ );
86
292
  }
87
293
  ```
88
294
 
89
- ## Development
295
+ The hook accepts:
90
296
 
91
- ```bash
92
- # Install dependencies
93
- npm install
297
+ - `interval` (required) — polling interval in milliseconds
298
+ - `enabled` (optional, defaults to `true`) — set to `false` to disable measurement without unmounting
94
299
 
95
- # Build the package (ESM + CJS)
96
- npm run build
300
+ ## Full example: Lens switcher
97
301
 
98
- # Build in watch mode (for development)
99
- npm run watch
302
+ ```tsx
303
+ import { CameraKitProvider, LensPlayer, LiveCanvas, useCameraKit } from "@snap/react-camera-kit";
304
+ import { useEffect } from "react";
305
+
306
+ const LENS_GROUP_ID = "YOUR_LENS_GROUP_ID";
307
+
308
+ function LensSwitcher() {
309
+ const { sdkStatus, lenses, lens, fetchLenses, applyLens, isMuted, toggleMuted, reinitialize, sdkError } =
310
+ useCameraKit();
311
+
312
+ useEffect(() => {
313
+ if (sdkStatus === "ready") fetchLenses(LENS_GROUP_ID);
314
+ }, [sdkStatus]);
315
+
316
+ if (sdkStatus === "error") {
317
+ return (
318
+ <div>
319
+ <p>SDK error: {sdkError?.message}</p>
320
+ <button onClick={reinitialize}>Retry</button>
321
+ </div>
322
+ );
323
+ }
100
324
 
101
- # Type checking
102
- npm run typecheck
325
+ return (
326
+ <div>
327
+ <select value={lens.lensId ?? ""} onChange={(e) => applyLens(e.target.value, LENS_GROUP_ID)}>
328
+ <option value="" disabled>
329
+ Select a Lens
330
+ </option>
331
+ {lenses.map((l) => (
332
+ <option key={l.id} value={l.id}>
333
+ {l.name}
334
+ </option>
335
+ ))}
336
+ </select>
337
+ <button onClick={toggleMuted}>{isMuted ? "Unmute" : "Mute"}</button>
338
+
339
+ <LensPlayer lensId={lens.lensId} lensGroupId={LENS_GROUP_ID}>
340
+ <LiveCanvas style={{ width: "100%", maxWidth: 640 }} />
341
+ </LensPlayer>
342
+ </div>
343
+ );
344
+ }
103
345
 
104
- # Run tests
105
- npm test
346
+ export default function App() {
347
+ return (
348
+ <CameraKitProvider apiToken="YOUR_API_TOKEN">
349
+ <LensSwitcher />
350
+ </CameraKitProvider>
351
+ );
352
+ }
353
+ ```
106
354
 
107
- # Clean dist folder
108
- npm run clean
355
+ ## Utilities
356
+
357
+ | Export | Description |
358
+ | ------------------------ | --------------------------------------------------- |
359
+ | `createConsoleLogger()` | Returns a logger that prints to the browser console |
360
+ | `createNoopLogger()` | Returns a silent logger (default) |
361
+ | `isCameraSource(source)` | Type guard for `CameraSourceInput` |
362
+ | `isVideoSource(source)` | Type guard for `VideoSourceInput` |
363
+ | `isImageSource(source)` | Type guard for `ImageSourceInput` |
364
+ | `CameraRotationOptions` | Valid rotation values: `[0, -90, 90, 180]` |
365
+
366
+ ## Development
367
+
368
+ ```bash
369
+ npm install # Install dependencies
370
+ npm run build # Build ESM + CJS
371
+ npm run watch # Build in watch mode
372
+ npm run typecheck # Type checking
373
+ npm test # Run tests
374
+ npm run clean # Clean dist folder
109
375
  ```
110
376
 
111
- ## Demo App
377
+ ### Demo app
112
378
 
113
- A Vite demo app is available at `demo`.
379
+ A Vite demo app is available in `demo/`:
114
380
 
115
381
  ```bash
116
382
  npm run demo:install
@@ -120,7 +386,7 @@ npm run demo:dev
120
386
 
121
387
  ## Contributing
122
388
 
123
- We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details on how to get started.
389
+ We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.
124
390
 
125
391
  - [Code of Conduct](CODE_OF_CONDUCT.md)
126
392
  - [Security Policy](SECURITY.md)
@@ -1 +1 @@
1
- {"version":3,"file":"CameraKitProvider.d.ts","sourceRoot":"","sources":["../../src/CameraKitProvider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CameraKitProvider.d.ts","sourceRoot":"","sources":["../../src/CameraKitProvider.tsx"],"names":[],"mappings":"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"}
@@ -142,6 +142,9 @@ const CameraKitProvider = ({ extendContainer, stabilityKey, children, createBoot
142
142
  (0, react_1.useEffect)(() => {
143
143
  const abortController = new AbortController();
144
144
  const emit = eventFactoryRef.current?.();
145
+ // Clear stale lens cache — the old kit's lensRepository is no longer valid.
146
+ lensCache.current.clear();
147
+ setLenses([]);
145
148
  setCameraKitState({ status: "initializing" });
146
149
  emit?.({ kind: "bootstrap-attempt" });
147
150
  log.info("bootstrap_attempt");