@snap/react-camera-kit 0.0.1
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/LICENSE.md +37 -0
- package/README.md +130 -0
- package/dist/cjs/CameraKitProvider.d.ts +203 -0
- package/dist/cjs/CameraKitProvider.d.ts.map +1 -0
- package/dist/cjs/CameraKitProvider.js +542 -0
- package/dist/cjs/CameraKitProvider.js.map +1 -0
- package/dist/cjs/Canvas.d.ts +7 -0
- package/dist/cjs/Canvas.d.ts.map +1 -0
- package/dist/cjs/Canvas.js +50 -0
- package/dist/cjs/Canvas.js.map +1 -0
- package/dist/cjs/LensPlayer.d.ts +101 -0
- package/dist/cjs/LensPlayer.d.ts.map +1 -0
- package/dist/cjs/LensPlayer.js +67 -0
- package/dist/cjs/LensPlayer.js.map +1 -0
- package/dist/cjs/index.d.ts +17 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +34 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/internal/bootstrapUtils.d.ts +13 -0
- package/dist/cjs/internal/bootstrapUtils.d.ts.map +1 -0
- package/dist/cjs/internal/bootstrapUtils.js +29 -0
- package/dist/cjs/internal/bootstrapUtils.js.map +1 -0
- package/dist/cjs/internal/error.d.ts +2 -0
- package/dist/cjs/internal/error.d.ts.map +1 -0
- package/dist/cjs/internal/error.js +30 -0
- package/dist/cjs/internal/error.js.map +1 -0
- package/dist/cjs/internal/isMobile.d.ts +5 -0
- package/dist/cjs/internal/isMobile.d.ts.map +1 -0
- package/dist/cjs/internal/isMobile.js +15 -0
- package/dist/cjs/internal/isMobile.js.map +1 -0
- package/dist/cjs/internal/logging.d.ts +40 -0
- package/dist/cjs/internal/logging.d.ts.map +1 -0
- package/dist/cjs/internal/logging.js +63 -0
- package/dist/cjs/internal/logging.js.map +1 -0
- package/dist/cjs/internal/metrics.d.ts +29 -0
- package/dist/cjs/internal/metrics.d.ts.map +1 -0
- package/dist/cjs/internal/metrics.js +128 -0
- package/dist/cjs/internal/metrics.js.map +1 -0
- package/dist/cjs/internal/sessionUtils.d.ts +3 -0
- package/dist/cjs/internal/sessionUtils.d.ts.map +1 -0
- package/dist/cjs/internal/sessionUtils.js +17 -0
- package/dist/cjs/internal/sessionUtils.js.map +1 -0
- package/dist/cjs/internal/sourceUtils.d.ts +22 -0
- package/dist/cjs/internal/sourceUtils.d.ts.map +1 -0
- package/dist/cjs/internal/sourceUtils.js +143 -0
- package/dist/cjs/internal/sourceUtils.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/types.d.ts +96 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +26 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/useApplyLens.d.ts +25 -0
- package/dist/cjs/useApplyLens.d.ts.map +1 -0
- package/dist/cjs/useApplyLens.js +87 -0
- package/dist/cjs/useApplyLens.js.map +1 -0
- package/dist/cjs/useApplySource.d.ts +11 -0
- package/dist/cjs/useApplySource.d.ts.map +1 -0
- package/dist/cjs/useApplySource.js +66 -0
- package/dist/cjs/useApplySource.js.map +1 -0
- package/dist/cjs/usePlaybackOptions.d.ts +38 -0
- package/dist/cjs/usePlaybackOptions.d.ts.map +1 -0
- package/dist/cjs/usePlaybackOptions.js +51 -0
- package/dist/cjs/usePlaybackOptions.js.map +1 -0
- package/dist/cjs/version.d.ts +3 -0
- package/dist/cjs/version.d.ts.map +1 -0
- package/dist/cjs/version.js +6 -0
- package/dist/cjs/version.js.map +1 -0
- package/dist/esm/CameraKitProvider.d.ts +203 -0
- package/dist/esm/CameraKitProvider.d.ts.map +1 -0
- package/dist/esm/CameraKitProvider.js +533 -0
- package/dist/esm/CameraKitProvider.js.map +1 -0
- package/dist/esm/Canvas.d.ts +7 -0
- package/dist/esm/Canvas.d.ts.map +1 -0
- package/dist/esm/Canvas.js +45 -0
- package/dist/esm/Canvas.js.map +1 -0
- package/dist/esm/LensPlayer.d.ts +101 -0
- package/dist/esm/LensPlayer.d.ts.map +1 -0
- package/dist/esm/LensPlayer.js +63 -0
- package/dist/esm/LensPlayer.js.map +1 -0
- package/dist/esm/index.d.ts +17 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +13 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/bootstrapUtils.d.ts +13 -0
- package/dist/esm/internal/bootstrapUtils.d.ts.map +1 -0
- package/dist/esm/internal/bootstrapUtils.js +26 -0
- package/dist/esm/internal/bootstrapUtils.js.map +1 -0
- package/dist/esm/internal/error.d.ts +2 -0
- package/dist/esm/internal/error.d.ts.map +1 -0
- package/dist/esm/internal/error.js +27 -0
- package/dist/esm/internal/error.js.map +1 -0
- package/dist/esm/internal/isMobile.d.ts +5 -0
- package/dist/esm/internal/isMobile.d.ts.map +1 -0
- package/dist/esm/internal/isMobile.js +12 -0
- package/dist/esm/internal/isMobile.js.map +1 -0
- package/dist/esm/internal/logging.d.ts +40 -0
- package/dist/esm/internal/logging.d.ts.map +1 -0
- package/dist/esm/internal/logging.js +58 -0
- package/dist/esm/internal/logging.js.map +1 -0
- package/dist/esm/internal/metrics.d.ts +29 -0
- package/dist/esm/internal/metrics.d.ts.map +1 -0
- package/dist/esm/internal/metrics.js +91 -0
- package/dist/esm/internal/metrics.js.map +1 -0
- package/dist/esm/internal/sessionUtils.d.ts +3 -0
- package/dist/esm/internal/sessionUtils.d.ts.map +1 -0
- package/dist/esm/internal/sessionUtils.js +14 -0
- package/dist/esm/internal/sessionUtils.js.map +1 -0
- package/dist/esm/internal/sourceUtils.d.ts +22 -0
- package/dist/esm/internal/sourceUtils.d.ts.map +1 -0
- package/dist/esm/internal/sourceUtils.js +139 -0
- package/dist/esm/internal/sourceUtils.js.map +1 -0
- package/dist/esm/types.d.ts +96 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +20 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/useApplyLens.d.ts +25 -0
- package/dist/esm/useApplyLens.d.ts.map +1 -0
- package/dist/esm/useApplyLens.js +81 -0
- package/dist/esm/useApplyLens.js.map +1 -0
- package/dist/esm/useApplySource.d.ts +11 -0
- package/dist/esm/useApplySource.d.ts.map +1 -0
- package/dist/esm/useApplySource.js +60 -0
- package/dist/esm/useApplySource.js.map +1 -0
- package/dist/esm/usePlaybackOptions.d.ts +38 -0
- package/dist/esm/usePlaybackOptions.d.ts.map +1 -0
- package/dist/esm/usePlaybackOptions.js +48 -0
- package/dist/esm/usePlaybackOptions.js.map +1 -0
- package/dist/esm/version.d.ts +3 -0
- package/dist/esm/version.d.ts.map +1 -0
- package/dist/esm/version.js +3 -0
- package/dist/esm/version.js.map +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useCameraKit = exports.useInternalCameraKit = exports.CameraKitProvider = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("react");
|
|
9
|
+
const stable_hash_1 = __importDefault(require("stable-hash"));
|
|
10
|
+
const types_1 = require("./types");
|
|
11
|
+
const logging_1 = require("./internal/logging");
|
|
12
|
+
const error_1 = require("./internal/error");
|
|
13
|
+
const sourceUtils_1 = require("./internal/sourceUtils");
|
|
14
|
+
const sessionUtils_1 = require("./internal/sessionUtils");
|
|
15
|
+
const bootstrapUtils_1 = require("./internal/bootstrapUtils");
|
|
16
|
+
const metrics_1 = require("./internal/metrics");
|
|
17
|
+
// How long to wait for a Lens "ready" event.
|
|
18
|
+
const readyTimeoutMs = 2000;
|
|
19
|
+
const throwNoContext = () => {
|
|
20
|
+
throw new Error("useCameraKit must be used within a CameraKitProvider");
|
|
21
|
+
};
|
|
22
|
+
const defaultCameraKitContextValue = {
|
|
23
|
+
sdkStatus: "uninitialized",
|
|
24
|
+
sdkError: undefined,
|
|
25
|
+
liveCanvas: undefined,
|
|
26
|
+
captureCanvas: undefined,
|
|
27
|
+
source: {
|
|
28
|
+
status: "none",
|
|
29
|
+
error: undefined,
|
|
30
|
+
input: undefined,
|
|
31
|
+
initializedInput: undefined,
|
|
32
|
+
},
|
|
33
|
+
lens: types_1.NO_CURRENT_LENS,
|
|
34
|
+
keyboard: undefined,
|
|
35
|
+
lenses: [],
|
|
36
|
+
isMuted: false,
|
|
37
|
+
fpsLimit: undefined,
|
|
38
|
+
screenRegions: undefined,
|
|
39
|
+
reinitialize: throwNoContext,
|
|
40
|
+
applySource: throwNoContext,
|
|
41
|
+
removeSource: throwNoContext,
|
|
42
|
+
fetchLens: throwNoContext,
|
|
43
|
+
fetchLenses: throwNoContext,
|
|
44
|
+
applyLens: throwNoContext,
|
|
45
|
+
removeLens: throwNoContext,
|
|
46
|
+
refreshLens: throwNoContext,
|
|
47
|
+
setFPSLimit: throwNoContext,
|
|
48
|
+
setMuted: throwNoContext,
|
|
49
|
+
toggleMuted: throwNoContext,
|
|
50
|
+
setScreenRegions: throwNoContext,
|
|
51
|
+
};
|
|
52
|
+
// Single context that includes everything (setters are internal)
|
|
53
|
+
const CameraKitContext = (0, react_1.createContext)(undefined);
|
|
54
|
+
/* ------------------------------ provider -------------------------------- */
|
|
55
|
+
/**
|
|
56
|
+
* Provider component that initializes and manages the Camera Kit SDK.
|
|
57
|
+
*
|
|
58
|
+
* This component handles SDK bootstrapping, session creation, and provides access to
|
|
59
|
+
* Camera Kit functionality through React context. All Camera Kit hooks and components
|
|
60
|
+
* must be used within this provider.
|
|
61
|
+
*
|
|
62
|
+
* The provider automatically manages SDK lifecycle, including initialization, cleanup,
|
|
63
|
+
* and re-initialization when configuration changes.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* import { CameraKitProvider, createConsoleLogger } from '@snap/react-camera-kit';
|
|
68
|
+
*
|
|
69
|
+
* function App() {
|
|
70
|
+
* return (
|
|
71
|
+
* <CameraKitProvider
|
|
72
|
+
* apiToken="your-api-token"
|
|
73
|
+
* logger={createConsoleLogger()}
|
|
74
|
+
* logLevel="debug"
|
|
75
|
+
* >
|
|
76
|
+
* <YourCameraKitComponents />
|
|
77
|
+
* </CameraKitProvider>
|
|
78
|
+
* );
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
const CameraKitProvider = ({ extendContainer, stabilityKey, children, createBootstrapEventHandler, logger: providedLogger, logLevel = "info", renderWhileTabHidden, ...bootstrapConfig }) => {
|
|
83
|
+
// Prevent nesting CameraKitProvider within another CameraKitProvider
|
|
84
|
+
const existingContext = (0, react_1.useContext)(CameraKitContext);
|
|
85
|
+
if (existingContext) {
|
|
86
|
+
throw new Error("CameraKitProvider cannot be nested within another CameraKitProvider.");
|
|
87
|
+
}
|
|
88
|
+
const { rootLogger, log } = (0, react_1.useMemo)(() => {
|
|
89
|
+
const rootLogger = (0, logging_1.wrapLogger)({ ...(providedLogger ?? (0, logging_1.createNoopLogger)()), logLevel }, "react-camera-kit");
|
|
90
|
+
const currentLogger = (0, logging_1.wrapLogger)(rootLogger, "CameraKitProvider");
|
|
91
|
+
return { rootLogger, log: currentLogger };
|
|
92
|
+
}, [providedLogger, logLevel]);
|
|
93
|
+
// Cache for child loggers to ensure same namespace returns same instance
|
|
94
|
+
const loggerCacheRef = (0, react_1.useRef)(new Map());
|
|
95
|
+
// Clear cache when log changes to ensure child loggers get new parent
|
|
96
|
+
(0, react_1.useEffect)(() => {
|
|
97
|
+
loggerCacheRef.current.clear();
|
|
98
|
+
}, [rootLogger]);
|
|
99
|
+
// Helper to create child loggers for internal hooks
|
|
100
|
+
const getLogger = (0, react_1.useCallback)((ns) => {
|
|
101
|
+
// Check cache first
|
|
102
|
+
if (loggerCacheRef.current.has(ns)) {
|
|
103
|
+
return loggerCacheRef.current.get(ns);
|
|
104
|
+
}
|
|
105
|
+
// Create and cache new child logger
|
|
106
|
+
const childLogger = (0, logging_1.wrapLogger)(rootLogger, ns);
|
|
107
|
+
loggerCacheRef.current.set(ns, childLogger);
|
|
108
|
+
return childLogger;
|
|
109
|
+
}, [rootLogger]);
|
|
110
|
+
/** engine bootstrap + global state */
|
|
111
|
+
const [cameraKitState, setCameraKitState] = (0, react_1.useState)({ status: "uninitialized" });
|
|
112
|
+
/** per-provider session + ui states (single session for now) */
|
|
113
|
+
const [source, setSource] = (0, react_1.useState)(defaultCameraKitContextValue.source);
|
|
114
|
+
const [lens, setLens] = (0, react_1.useState)(defaultCameraKitContextValue.lens);
|
|
115
|
+
const [bootstrapCounter, setBootstrapCounter] = (0, react_1.useState)(0);
|
|
116
|
+
/** playback state */
|
|
117
|
+
const [isMuted, setIsMuted] = (0, react_1.useState)(false);
|
|
118
|
+
const [fpsLimit, setFpsLimitState] = (0, react_1.useState)(undefined);
|
|
119
|
+
const [screenRegions, setScreenRegionsState] = (0, react_1.useState)(undefined);
|
|
120
|
+
/** Lens manager state */
|
|
121
|
+
const [lenses, setLenses] = (0, react_1.useState)([]);
|
|
122
|
+
const lensCache = (0, react_1.useRef)(new Map());
|
|
123
|
+
/** keep latest cameraKit in a ref for cleanup */
|
|
124
|
+
const kitRef = (0, react_1.useRef)();
|
|
125
|
+
/** keep metrics factory in a ref so swapping it doesn’t re-bootstrap */
|
|
126
|
+
const eventFactoryRef = (0, react_1.useRef)(createBootstrapEventHandler);
|
|
127
|
+
(0, react_1.useEffect)(() => {
|
|
128
|
+
eventFactoryRef.current = createBootstrapEventHandler;
|
|
129
|
+
}, [createBootstrapEventHandler]);
|
|
130
|
+
/**
|
|
131
|
+
* Semantic key:
|
|
132
|
+
* - If stabilityKey is provided - use it as the sole trigger.
|
|
133
|
+
* - Else hash a generic projection of { config, extendContainer } so ANY field change
|
|
134
|
+
* in CameraKitBootstrapConfiguration (or extendContainer) reboots the SDK.
|
|
135
|
+
*/
|
|
136
|
+
const bootstrapKey = (0, react_1.useMemo)(() => {
|
|
137
|
+
if (stabilityKey != null)
|
|
138
|
+
return String(stabilityKey);
|
|
139
|
+
return (0, stable_hash_1.default)({ config: bootstrapConfig, extendContainer, renderWhileTabHidden });
|
|
140
|
+
}, [bootstrapConfig, extendContainer, renderWhileTabHidden, stabilityKey]);
|
|
141
|
+
/* ---------------------------- bootstrap engine ------------------------- */
|
|
142
|
+
(0, react_1.useEffect)(() => {
|
|
143
|
+
const abortController = new AbortController();
|
|
144
|
+
const emit = eventFactoryRef.current?.();
|
|
145
|
+
setCameraKitState({ status: "initializing" });
|
|
146
|
+
emit?.({ kind: "bootstrap-attempt" });
|
|
147
|
+
log.info("bootstrap_attempt");
|
|
148
|
+
(0, bootstrapUtils_1.bootstrapCameraKitWithSession)(bootstrapConfig, (0, metrics_1.extendContainerWithMetrics)(extendContainer), { renderWhileTabHidden }, abortController.signal, log)
|
|
149
|
+
.then(({ kit, session, destroy }) => {
|
|
150
|
+
// Store kit reference for cleanup
|
|
151
|
+
kitRef.current = { kit, destroy };
|
|
152
|
+
setCameraKitState({ kit, session, status: "ready" });
|
|
153
|
+
log.info("bootstrap_success");
|
|
154
|
+
emit?.({ kind: "bootstrap-success" });
|
|
155
|
+
metrics_1.metricsReporter.reportCount("bootstrap_success");
|
|
156
|
+
})
|
|
157
|
+
.catch((error) => {
|
|
158
|
+
// Ignore errors from aborted operations
|
|
159
|
+
if (error.name === "AbortError")
|
|
160
|
+
return;
|
|
161
|
+
log.error("bootstrap_failure", error);
|
|
162
|
+
setCameraKitState({ kit: undefined, session: undefined, status: "error", error });
|
|
163
|
+
emit?.({ kind: "bootstrap-failure", error });
|
|
164
|
+
metrics_1.metricsReporter.reportCount("bootstrap_failure");
|
|
165
|
+
});
|
|
166
|
+
return () => {
|
|
167
|
+
abortController.abort();
|
|
168
|
+
kitRef.current?.destroy();
|
|
169
|
+
kitRef.current = undefined;
|
|
170
|
+
};
|
|
171
|
+
// Re-bootstrap when key changes or when manual counter bumps on reinit
|
|
172
|
+
}, [bootstrapKey, bootstrapCounter]);
|
|
173
|
+
/* --------------------------- Lens cache cleanup ------------------------ */
|
|
174
|
+
// When Camera Kit errors, remove all Lenses from the local cache.
|
|
175
|
+
// Otherwise, if any component tries to apply a Lens that broke Camera Kit before,
|
|
176
|
+
// Lens manager will fail with cannot find Lens error.
|
|
177
|
+
(0, react_1.useEffect)(() => {
|
|
178
|
+
if (cameraKitState.session) {
|
|
179
|
+
cameraKitState.session.events.addEventListener("error", (event) => {
|
|
180
|
+
if (event.detail.error.name === "LensExecutionError") {
|
|
181
|
+
lensCache.current.clear();
|
|
182
|
+
setLenses([]);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}, [cameraKitState.session]);
|
|
187
|
+
/* ---------------------------- Lens manager methods --------------------- */
|
|
188
|
+
const fetchLens = (0, react_1.useCallback)(async (lensId, groupId) => {
|
|
189
|
+
try {
|
|
190
|
+
if (!cameraKitState.kit)
|
|
191
|
+
throw new Error("CameraKit not initialized.");
|
|
192
|
+
const key = `${groupId}:${lensId}`;
|
|
193
|
+
if (lensCache.current.has(key))
|
|
194
|
+
return lensCache.current.get(key);
|
|
195
|
+
const lens = await cameraKitState.kit.lensRepository.loadLens(lensId, groupId);
|
|
196
|
+
lensCache.current.set(key, lens);
|
|
197
|
+
setLenses((prev) => [...prev, lens]);
|
|
198
|
+
return lens;
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
log.error("lens_load_failed", { lensId, groupId }, error);
|
|
202
|
+
throw error;
|
|
203
|
+
}
|
|
204
|
+
}, [cameraKitState.kit, log]);
|
|
205
|
+
const fetchLenses = (0, react_1.useCallback)(async (groupId) => {
|
|
206
|
+
try {
|
|
207
|
+
if (!cameraKitState.kit)
|
|
208
|
+
throw new Error("CameraKit not initialized.");
|
|
209
|
+
const { lenses: loaded } = await cameraKitState.kit.lensRepository.loadLensGroups([groupId].flat());
|
|
210
|
+
loaded.forEach((l) => {
|
|
211
|
+
const key = `${l.groupId}:${l.id}`;
|
|
212
|
+
if (!lensCache.current.has(key))
|
|
213
|
+
lensCache.current.set(key, l);
|
|
214
|
+
});
|
|
215
|
+
setLenses(Array.from(lensCache.current.values()));
|
|
216
|
+
return loaded;
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
log.error("lens_group_load_failed", { groupId }, error);
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
}, [cameraKitState.kit, log]);
|
|
223
|
+
const applyLens = (0, react_1.useCallback)(async (lensId, lensGroupId, launchData, lensReadyGuard) => {
|
|
224
|
+
const commonFields = {
|
|
225
|
+
lensId,
|
|
226
|
+
lensGroupId,
|
|
227
|
+
lensLaunchData: launchData,
|
|
228
|
+
lensReadyGuard,
|
|
229
|
+
};
|
|
230
|
+
let lens;
|
|
231
|
+
try {
|
|
232
|
+
if (!cameraKitState.session)
|
|
233
|
+
throw new Error("No active session.");
|
|
234
|
+
setLens({
|
|
235
|
+
...commonFields,
|
|
236
|
+
status: "loading",
|
|
237
|
+
error: undefined,
|
|
238
|
+
lens: undefined,
|
|
239
|
+
});
|
|
240
|
+
lens = await fetchLens(lensId, lensGroupId);
|
|
241
|
+
// Caller might do an animation and wait for some rendering event.
|
|
242
|
+
// If they return a Promise, we await it.
|
|
243
|
+
const readyPromise = lensReadyGuard?.() ?? Promise.resolve();
|
|
244
|
+
const applyPromise = cameraKitState.session.applyLens(lens, launchData);
|
|
245
|
+
await Promise.race([
|
|
246
|
+
Promise.all([applyPromise, readyPromise]),
|
|
247
|
+
new Promise((resolve) => setTimeout(resolve, readyTimeoutMs)),
|
|
248
|
+
]);
|
|
249
|
+
setLens({
|
|
250
|
+
...commonFields,
|
|
251
|
+
status: "ready",
|
|
252
|
+
error: undefined,
|
|
253
|
+
lens,
|
|
254
|
+
});
|
|
255
|
+
metrics_1.metricsReporter.reportCount("lens_apply_success");
|
|
256
|
+
return await applyPromise;
|
|
257
|
+
}
|
|
258
|
+
catch (cause) {
|
|
259
|
+
const error = (0, error_1.ensureError)(cause);
|
|
260
|
+
log.error("lens_apply_failed", { lensId, lensGroupId }, error);
|
|
261
|
+
setLens({ ...commonFields, status: "error", error, lens });
|
|
262
|
+
metrics_1.metricsReporter.reportCount("lens_apply_failure");
|
|
263
|
+
throw error;
|
|
264
|
+
}
|
|
265
|
+
}, [fetchLens, cameraKitState.session, log]);
|
|
266
|
+
const removeLens = (0, react_1.useCallback)(async () => {
|
|
267
|
+
try {
|
|
268
|
+
if (!cameraKitState.session)
|
|
269
|
+
throw new Error("No active session.");
|
|
270
|
+
const removed = await cameraKitState.session.removeLens();
|
|
271
|
+
if (removed)
|
|
272
|
+
setLens(types_1.NO_CURRENT_LENS);
|
|
273
|
+
return removed;
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
log.error("lens_remove_failed", error);
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
}, [cameraKitState.session, log]);
|
|
280
|
+
const refreshLens = (0, react_1.useCallback)(async () => {
|
|
281
|
+
const { lensId, lensGroupId, lensLaunchData, lensReadyGuard } = lens;
|
|
282
|
+
if (!lensId || !lensGroupId)
|
|
283
|
+
return;
|
|
284
|
+
await removeLens();
|
|
285
|
+
await applyLens(lensId, lensGroupId, lensLaunchData, lensReadyGuard);
|
|
286
|
+
}, [lens, removeLens, applyLens]);
|
|
287
|
+
/* ---------------------------- source manager methods ------------------- */
|
|
288
|
+
const sourceCleanupRef = (0, react_1.useRef)({});
|
|
289
|
+
const applySource = (0, react_1.useCallback)(async (input, size) => {
|
|
290
|
+
try {
|
|
291
|
+
if (!cameraKitState.session)
|
|
292
|
+
throw new Error("No active session.");
|
|
293
|
+
// Clean up previous source
|
|
294
|
+
sourceCleanupRef.current.mediaStream?.getTracks().forEach((track) => track.stop());
|
|
295
|
+
await sourceCleanupRef.current.cameraKitSource?.detach(() => { });
|
|
296
|
+
sourceCleanupRef.current = {};
|
|
297
|
+
setSource({
|
|
298
|
+
input,
|
|
299
|
+
status: "loading",
|
|
300
|
+
error: undefined,
|
|
301
|
+
initializedInput: undefined,
|
|
302
|
+
});
|
|
303
|
+
const { cameraKitSource, transform, inputSize, mediaStream, initializedSourceInput } = await (0, sourceUtils_1.createCameraKitSource)(input);
|
|
304
|
+
// Store refs for cleanup
|
|
305
|
+
sourceCleanupRef.current = { cameraKitSource, mediaStream };
|
|
306
|
+
// Pause session, set source, apply transforms and render size, then resume
|
|
307
|
+
await (0, sessionUtils_1.withSessionPaused)(cameraKitState.session, async () => {
|
|
308
|
+
await cameraKitState.session.setSource(cameraKitSource);
|
|
309
|
+
await cameraKitSource.setTransform(transform);
|
|
310
|
+
if (size?.mode === "fixed") {
|
|
311
|
+
await cameraKitSource.setRenderSize(size.width, size.height);
|
|
312
|
+
}
|
|
313
|
+
else if (size?.mode === "match-input" && inputSize) {
|
|
314
|
+
await cameraKitSource.setRenderSize(inputSize[0], inputSize[1]);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
setSource({
|
|
318
|
+
input,
|
|
319
|
+
initializedInput: initializedSourceInput,
|
|
320
|
+
status: "ready",
|
|
321
|
+
error: undefined,
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
catch (cause) {
|
|
325
|
+
const error = (0, error_1.ensureError)(cause);
|
|
326
|
+
log.error("source_apply_failed", { kind: input.kind }, error);
|
|
327
|
+
setSource({
|
|
328
|
+
input,
|
|
329
|
+
status: "error",
|
|
330
|
+
error,
|
|
331
|
+
initializedInput: undefined,
|
|
332
|
+
});
|
|
333
|
+
throw error;
|
|
334
|
+
}
|
|
335
|
+
}, [cameraKitState.session, log]);
|
|
336
|
+
const removeSource = (0, react_1.useCallback)(async () => {
|
|
337
|
+
try {
|
|
338
|
+
// Clean up media stream and detach source
|
|
339
|
+
sourceCleanupRef.current.mediaStream?.getTracks().forEach((track) => track.stop());
|
|
340
|
+
await sourceCleanupRef.current.cameraKitSource?.detach(() => { });
|
|
341
|
+
sourceCleanupRef.current = {};
|
|
342
|
+
setSource({
|
|
343
|
+
status: "none",
|
|
344
|
+
error: undefined,
|
|
345
|
+
input: undefined,
|
|
346
|
+
initializedInput: undefined,
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
catch (error) {
|
|
350
|
+
log.error("source_remove_failed", error);
|
|
351
|
+
throw error;
|
|
352
|
+
}
|
|
353
|
+
}, [log]);
|
|
354
|
+
/* ---------------------------- playback control methods ----------------- */
|
|
355
|
+
const setFPSLimit = (0, react_1.useCallback)(async (fps) => {
|
|
356
|
+
try {
|
|
357
|
+
if (!cameraKitState.session)
|
|
358
|
+
throw new Error("No active session.");
|
|
359
|
+
await cameraKitState.session.setFPSLimit(fps);
|
|
360
|
+
setFpsLimitState(fps);
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
log.error("fps_limit_set_failed", { fps }, error);
|
|
364
|
+
throw error;
|
|
365
|
+
}
|
|
366
|
+
}, [cameraKitState.session, log]);
|
|
367
|
+
const setMuted = (0, react_1.useCallback)((muted) => {
|
|
368
|
+
if (!cameraKitState.session)
|
|
369
|
+
throw new Error("No active session.");
|
|
370
|
+
if (muted) {
|
|
371
|
+
cameraKitState.session.mute();
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
cameraKitState.session.unmute();
|
|
375
|
+
}
|
|
376
|
+
setIsMuted(muted);
|
|
377
|
+
}, [cameraKitState.session]);
|
|
378
|
+
const toggleMuted = (0, react_1.useCallback)(() => {
|
|
379
|
+
setMuted(!isMuted);
|
|
380
|
+
}, [isMuted, setMuted]);
|
|
381
|
+
const setScreenRegions = (0, react_1.useCallback)(async (regions) => {
|
|
382
|
+
try {
|
|
383
|
+
if (!cameraKitState.session)
|
|
384
|
+
throw new Error("No active session.");
|
|
385
|
+
await cameraKitState.session.setScreenRegions(regions);
|
|
386
|
+
setScreenRegionsState(regions);
|
|
387
|
+
}
|
|
388
|
+
catch (error) {
|
|
389
|
+
log.error("screen_regions_set_failed", error);
|
|
390
|
+
throw error;
|
|
391
|
+
}
|
|
392
|
+
}, [cameraKitState.session, log]);
|
|
393
|
+
const abortCameraKit = (0, react_1.useCallback)((error) => {
|
|
394
|
+
cameraKitState.kit?.destroy().catch((cause) => {
|
|
395
|
+
log.error("kit_destroy_failed", cause);
|
|
396
|
+
});
|
|
397
|
+
setCameraKitState({ kit: undefined, status: "error", error: (0, error_1.ensureError)(error) });
|
|
398
|
+
}, [cameraKitState.kit, log]);
|
|
399
|
+
(0, react_1.useEffect)(() => {
|
|
400
|
+
if (!cameraKitState.session)
|
|
401
|
+
return;
|
|
402
|
+
function handleSessionError(event) {
|
|
403
|
+
if (event.detail.error.name === "LensExecutionError") {
|
|
404
|
+
// Update lens state to error, but don't abort the entire SDK.
|
|
405
|
+
// This allows the user to apply a new lens and recover from the error.
|
|
406
|
+
setLens((currentLens) => ({
|
|
407
|
+
...currentLens,
|
|
408
|
+
status: "error",
|
|
409
|
+
error: event.detail.error,
|
|
410
|
+
}));
|
|
411
|
+
}
|
|
412
|
+
else if (event.detail.error.name === "LensAbortError") {
|
|
413
|
+
// LensAbortError is a critical error that requires SDK re-initialization.
|
|
414
|
+
// Abort the SDK so the user must call reinitialize() to recover.
|
|
415
|
+
metrics_1.metricsReporter.reportCount("session_lens_abort_error");
|
|
416
|
+
abortCameraKit(event.detail.error);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
cameraKitState.session.events.addEventListener("error", handleSessionError);
|
|
420
|
+
return () => cameraKitState.session.events.removeEventListener("error", handleSessionError);
|
|
421
|
+
}, [cameraKitState.session, abortCameraKit]);
|
|
422
|
+
/* ---------------------------- memoised context ------------------------- */
|
|
423
|
+
const ctxValue = (0, react_1.useMemo)(() => ({
|
|
424
|
+
cameraKit: cameraKitState.kit,
|
|
425
|
+
currentSession: cameraKitState.session,
|
|
426
|
+
sdkStatus: cameraKitState.status,
|
|
427
|
+
sdkError: cameraKitState.error,
|
|
428
|
+
// Canvas elements
|
|
429
|
+
liveCanvas: cameraKitState.session?.output.live,
|
|
430
|
+
captureCanvas: cameraKitState.session?.output.capture,
|
|
431
|
+
source,
|
|
432
|
+
lens,
|
|
433
|
+
// Playback state
|
|
434
|
+
isMuted,
|
|
435
|
+
fpsLimit,
|
|
436
|
+
screenRegions,
|
|
437
|
+
keyboard: cameraKitState.session?.keyboard,
|
|
438
|
+
getLogger,
|
|
439
|
+
abortCameraKit,
|
|
440
|
+
reinitialize: () => {
|
|
441
|
+
if (cameraKitState.status === "error" && !cameraKitState.kit) {
|
|
442
|
+
setBootstrapCounter((prev) => prev + 1);
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
throw new Error("Cannot re-initialize CameraKit when it is not in an aborted state.");
|
|
446
|
+
}
|
|
447
|
+
},
|
|
448
|
+
// Lens manager methods
|
|
449
|
+
fetchLens,
|
|
450
|
+
fetchLenses,
|
|
451
|
+
applyLens,
|
|
452
|
+
removeLens,
|
|
453
|
+
refreshLens,
|
|
454
|
+
lenses,
|
|
455
|
+
// Source manager methods
|
|
456
|
+
applySource,
|
|
457
|
+
removeSource,
|
|
458
|
+
// Playback control methods
|
|
459
|
+
setFPSLimit,
|
|
460
|
+
setMuted,
|
|
461
|
+
toggleMuted,
|
|
462
|
+
setScreenRegions,
|
|
463
|
+
}), [
|
|
464
|
+
cameraKitState,
|
|
465
|
+
source,
|
|
466
|
+
lens,
|
|
467
|
+
isMuted,
|
|
468
|
+
fpsLimit,
|
|
469
|
+
screenRegions,
|
|
470
|
+
getLogger,
|
|
471
|
+
fetchLens,
|
|
472
|
+
fetchLenses,
|
|
473
|
+
applyLens,
|
|
474
|
+
removeLens,
|
|
475
|
+
refreshLens,
|
|
476
|
+
lenses,
|
|
477
|
+
applySource,
|
|
478
|
+
removeSource,
|
|
479
|
+
setFPSLimit,
|
|
480
|
+
setMuted,
|
|
481
|
+
toggleMuted,
|
|
482
|
+
setScreenRegions,
|
|
483
|
+
abortCameraKit,
|
|
484
|
+
]);
|
|
485
|
+
return (0, jsx_runtime_1.jsx)(CameraKitContext.Provider, { value: ctxValue, children: children });
|
|
486
|
+
};
|
|
487
|
+
exports.CameraKitProvider = CameraKitProvider;
|
|
488
|
+
/**
|
|
489
|
+
* Internal hook with access to Camera Kit internals.
|
|
490
|
+
* Only for use within react-camera-kit library components and hooks.
|
|
491
|
+
*
|
|
492
|
+
* @internal
|
|
493
|
+
*/
|
|
494
|
+
const useInternalCameraKit = () => {
|
|
495
|
+
const context = (0, react_1.useContext)(CameraKitContext);
|
|
496
|
+
if (!context) {
|
|
497
|
+
throw new Error("useInternalCameraKit must be used within a CameraKitProvider");
|
|
498
|
+
}
|
|
499
|
+
return context;
|
|
500
|
+
};
|
|
501
|
+
exports.useInternalCameraKit = useInternalCameraKit;
|
|
502
|
+
/**
|
|
503
|
+
* Hook to access Camera Kit context and methods.
|
|
504
|
+
*
|
|
505
|
+
* Provides access to SDK state, Lens management, source control, and playback options.
|
|
506
|
+
* Must be used within a CameraKitProvider.
|
|
507
|
+
*
|
|
508
|
+
* @returns Camera Kit context value with state and methods
|
|
509
|
+
* @throws Error if used outside of CameraKitProvider
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```tsx
|
|
513
|
+
* function MyComponent() {
|
|
514
|
+
* const {
|
|
515
|
+
* sdkStatus,
|
|
516
|
+
* lens,
|
|
517
|
+
* applyLens,
|
|
518
|
+
* removeLens,
|
|
519
|
+
* liveCanvas
|
|
520
|
+
* } = useCameraKit();
|
|
521
|
+
*
|
|
522
|
+
* useEffect(() => {
|
|
523
|
+
* if (sdkStatus === 'ready') {
|
|
524
|
+
* applyLens('lens-id', 'group-id');
|
|
525
|
+
* }
|
|
526
|
+
* }, [sdkStatus, applyLens]);
|
|
527
|
+
*
|
|
528
|
+
* return <div>{lens.status}</div>;
|
|
529
|
+
* }
|
|
530
|
+
* ```
|
|
531
|
+
*/
|
|
532
|
+
const useCameraKit = () => {
|
|
533
|
+
const context = (0, react_1.useContext)(CameraKitContext);
|
|
534
|
+
if (!context) {
|
|
535
|
+
throw new Error("useCameraKit must be used within a CameraKitProvider");
|
|
536
|
+
}
|
|
537
|
+
// Return only the public API (exclude internal fields)
|
|
538
|
+
const { cameraKit: _cameraKit, currentSession: _currentSession, getLogger: _getLogger, ...publicContext } = context;
|
|
539
|
+
return publicContext;
|
|
540
|
+
};
|
|
541
|
+
exports.useCameraKit = useCameraKit;
|
|
542
|
+
//# sourceMappingURL=CameraKitProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CameraKitProvider.js","sourceRoot":"","sources":["../../src/CameraKitProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { createContext, useContext, useEffect, useState, ReactNode, useRef, useMemo, useCallback } from \"react\";\nimport {\n CameraKit,\n CameraKitBootstrapConfiguration,\n CameraKitSession,\n PublicContainer,\n Lens,\n LensLaunchData,\n CameraKitSource,\n CameraKitSessionEvents,\n ScreenRegions,\n Keyboard,\n} from \"@snap/camera-kit\";\nimport hash from \"stable-hash\";\nimport { CurrentLens, CurrentSource, NO_CURRENT_LENS, SourceInput, OutputSize } from \"./types\";\nimport { CameraKitLogger, InternalLogger, LogLevel, createNoopLogger, wrapLogger } from \"./internal/logging\";\nimport { ensureError } from \"./internal/error\";\nimport { createCameraKitSource } from \"./internal/sourceUtils\";\nimport { withSessionPaused } from \"./internal/sessionUtils\";\nimport { bootstrapCameraKitWithSession } from \"./internal/bootstrapUtils\";\nimport { metricsReporter, extendContainerWithMetrics } from \"./internal/metrics\";\n\n// How long to wait for a Lens \"ready\" event.\nconst readyTimeoutMs = 2000;\n\nexport type MetricEventHandlerFactory = () => (\n event:\n | { kind: \"bootstrap-attempt\" | \"bootstrap-success\" }\n | { kind: \"bootstrap-failure\" | \"lens-failure\"; error: Error },\n) => void;\n\n/**\n * Public context interface exposed to consumers via useCameraKit hook.\n * Provides access to Camera Kit SDK state, Lens management, source control, and playback options.\n */\ninterface CameraKitContextValue {\n /** Current SDK initialization status. */\n sdkStatus: \"uninitialized\" | \"initializing\" | \"ready\" | \"error\";\n\n /** Error that occurred during SDK initialization, if any. */\n sdkError: Error | undefined;\n\n /** Live canvas element for real-time preview rendering. */\n liveCanvas: HTMLCanvasElement | undefined;\n\n /** Capture canvas element for snapshot rendering. */\n captureCanvas: HTMLCanvasElement | undefined;\n\n /** Source state including status, input parameters, and any errors. */\n source: CurrentSource;\n\n /** Lens state including status, Lens object, and any errors. */\n lens: CurrentLens;\n\n /**\n * The {@link Keyboard} API enables applications to handle keyboard input requests from lenses.\n * When a lens requests a keyboard, the app displays it in its preferred UI. As users type,\n * the app sends the text back to the lens for display. The lens can also request keyboard dismissal,\n * prompting the app to remove the displayed keyboard.\n */\n keyboard: Keyboard | undefined;\n\n /** Attempts to re-initialize the SDK after an error. Only available when SDK is in error state. */\n reinitialize: () => void;\n\n /** Applies a media source (camera, video, or image) to the session. */\n applySource: (input: SourceInput, size?: OutputSize) => Promise<void>;\n\n /** Removes the current source from the session. */\n removeSource: () => Promise<void>;\n\n /** Array of lenses that have been loaded via fetchLens or fetchLenses. */\n lenses: Lens[];\n\n /** Loads a single Lens by ID and group ID. Returns cached Lens if already loaded. */\n fetchLens: (lensId: string, groupId: string) => Promise<Lens>;\n\n /** Loads all lenses from one or more Lens groups. */\n fetchLenses: (groupId: string | string[]) => Promise<Lens[]>;\n\n /**\n * Applies a Lens to the current session.\n * @param lensId - The Lens identifier\n * @param groupId - The Lens group identifier\n * @param launchData - Optional launch parameters for the Lens\n * @param lensReadyGuard - Optional async guard for coordinating Lens application\n * @returns Promise that resolves to true if Lens was applied successfully\n */\n applyLens: (\n lensId: string,\n groupId: string,\n launchData?: LensLaunchData,\n lensReadyGuard?: () => Promise<void>,\n ) => Promise<boolean>;\n\n /** Removes the currently applied Lens from the session. */\n removeLens: () => Promise<boolean>;\n\n /** Refreshes the current Lens by removing and reapplying it. */\n refreshLens: () => Promise<void>;\n\n /** Sets the muted state for audio playback. */\n setMuted: (muted: boolean) => void;\n\n /** Toggles the current muted state. */\n toggleMuted: () => void;\n\n /** Whether audio is currently muted. */\n isMuted: boolean;\n\n /** Current FPS limit, if set. */\n fpsLimit: number | undefined;\n\n /** Sets the maximum FPS for rendering. Useful for reducing resource usage. */\n setFPSLimit: (fpsLimit: number) => Promise<void>;\n\n /** Current screen regions configuration, if set. */\n screenRegions: ScreenRegions | undefined;\n\n /** Sets screen regions for Lens-aware UI layout. */\n setScreenRegions: (screenRegions: ScreenRegions) => Promise<void>;\n}\n\n// Internal context interface (includes dangerous APIs for internal use only)\ninterface InternalCameraKitContextValue extends CameraKitContextValue {\n cameraKit: CameraKit | undefined;\n currentSession: CameraKitSession | undefined;\n getLogger: (ns: string) => CameraKitLogger;\n}\n\nconst throwNoContext = () => {\n throw new Error(\"useCameraKit must be used within a CameraKitProvider\");\n};\n\nconst defaultCameraKitContextValue: CameraKitContextValue = {\n sdkStatus: \"uninitialized\",\n sdkError: undefined,\n liveCanvas: undefined,\n captureCanvas: undefined,\n source: {\n status: \"none\",\n error: undefined,\n input: undefined,\n initializedInput: undefined,\n },\n lens: NO_CURRENT_LENS,\n keyboard: undefined,\n lenses: [],\n isMuted: false,\n fpsLimit: undefined,\n screenRegions: undefined,\n reinitialize: throwNoContext,\n applySource: throwNoContext,\n removeSource: throwNoContext,\n fetchLens: throwNoContext,\n fetchLenses: throwNoContext,\n applyLens: throwNoContext,\n removeLens: throwNoContext,\n refreshLens: throwNoContext,\n setFPSLimit: throwNoContext,\n setMuted: throwNoContext,\n toggleMuted: throwNoContext,\n setScreenRegions: throwNoContext,\n};\n\n// Single context that includes everything (setters are internal)\nconst CameraKitContext = createContext<InternalCameraKitContextValue | undefined>(undefined);\n\n/**\n * Props for the CameraKitProvider component.\n * Extends Camera Kit bootstrap configuration with React-specific options.\n */\ninterface CameraKitProviderProps extends Omit<CameraKitBootstrapConfiguration, \"logger\"> {\n /**\n * Optional function to extend the Camera Kit dependency injection container.\n * This is the second parameter to bootstrapCameraKit and allows customization\n * of the SDK's internal dependencies.\n */\n extendContainer?: (container: PublicContainer) => PublicContainer;\n\n /**\n * Optional factory for creating bootstrap event handlers for metrics/analytics.\n * Useful for tracking SDK initialization success/failure in your analytics system.\n */\n createBootstrapEventHandler?: MetricEventHandlerFactory;\n\n /**\n * Optional custom logger implementation. If not provided, a no-op logger is used by default.\n * Pass createConsoleLogger() from './logging' for console-based logging in development.\n *\n * @example\n * ```tsx\n * import { createConsoleLogger } from '@snap/react-camera-kit';\n *\n * <CameraKitProvider logger={createConsoleLogger()} logLevel=\"debug\">\n * {children}\n * </CameraKitProvider>\n * ```\n */\n logger?: CameraKitLogger;\n\n /**\n * Optional log level to control logger verbosity. Defaults to \"info\" if not specified.\n * Supported levels: \"debug\", \"info\", \"warn\", \"error\".\n */\n logLevel?: LogLevel;\n\n /**\n * Browsers optimize tabs when they are hidden - for example, by pausing the execution of requestAnimationFrame\n * callbacks.\n *\n * If you need the CameraKitSession to continue rendering even when the tab is in the background, set this to true.\n * There is a small performance penalty, and it's a good practice to only render in the background if absolutely\n * necessary.\n */\n renderWhileTabHidden?: boolean;\n\n /**\n * Optional manual override for bootstrap stability. If provided, the provider will re-bootstrap\n * whenever this value changes, regardless of other config details.\n *\n * Useful when you want explicit control over when the SDK reinitializes.\n */\n stabilityKey?: string | number;\n\n /**\n * React children to render within the provider.\n */\n children: ReactNode;\n}\n\n/* ------------------------------ provider -------------------------------- */\n\n/**\n * Provider component that initializes and manages the Camera Kit SDK.\n *\n * This component handles SDK bootstrapping, session creation, and provides access to\n * Camera Kit functionality through React context. All Camera Kit hooks and components\n * must be used within this provider.\n *\n * The provider automatically manages SDK lifecycle, including initialization, cleanup,\n * and re-initialization when configuration changes.\n *\n * @example\n * ```tsx\n * import { CameraKitProvider, createConsoleLogger } from '@snap/react-camera-kit';\n *\n * function App() {\n * return (\n * <CameraKitProvider\n * apiToken=\"your-api-token\"\n * logger={createConsoleLogger()}\n * logLevel=\"debug\"\n * >\n * <YourCameraKitComponents />\n * </CameraKitProvider>\n * );\n * }\n * ```\n */\nexport const CameraKitProvider: React.FC<CameraKitProviderProps> = ({\n extendContainer,\n stabilityKey,\n children,\n createBootstrapEventHandler,\n logger: providedLogger,\n logLevel = \"info\",\n renderWhileTabHidden,\n ...bootstrapConfig\n}) => {\n // Prevent nesting CameraKitProvider within another CameraKitProvider\n const existingContext = useContext(CameraKitContext);\n if (existingContext) {\n throw new Error(\"CameraKitProvider cannot be nested within another CameraKitProvider.\");\n }\n\n const { rootLogger, log } = useMemo(() => {\n const rootLogger = wrapLogger({ ...(providedLogger ?? createNoopLogger()), logLevel }, \"react-camera-kit\");\n const currentLogger = wrapLogger(rootLogger, \"CameraKitProvider\");\n return { rootLogger, log: currentLogger };\n }, [providedLogger, logLevel]);\n\n // Cache for child loggers to ensure same namespace returns same instance\n const loggerCacheRef = useRef<Map<string, InternalLogger>>(new Map());\n\n // Clear cache when log changes to ensure child loggers get new parent\n useEffect(() => {\n loggerCacheRef.current.clear();\n }, [rootLogger]);\n\n // Helper to create child loggers for internal hooks\n const getLogger = useCallback(\n (ns: string) => {\n // Check cache first\n if (loggerCacheRef.current.has(ns)) {\n return loggerCacheRef.current.get(ns)!;\n }\n\n // Create and cache new child logger\n const childLogger = wrapLogger(rootLogger, ns);\n loggerCacheRef.current.set(ns, childLogger);\n return childLogger;\n },\n [rootLogger],\n );\n\n /** engine bootstrap + global state */\n const [cameraKitState, setCameraKitState] = useState<{\n kit?: CameraKit;\n session?: CameraKitSession;\n status: CameraKitContextValue[\"sdkStatus\"];\n error?: CameraKitContextValue[\"sdkError\"];\n }>({ status: \"uninitialized\" });\n\n /** per-provider session + ui states (single session for now) */\n const [source, setSource] = useState<CurrentSource>(defaultCameraKitContextValue.source);\n const [lens, setLens] = useState<CurrentLens>(defaultCameraKitContextValue.lens);\n const [bootstrapCounter, setBootstrapCounter] = useState(0);\n\n /** playback state */\n const [isMuted, setIsMuted] = useState(false);\n const [fpsLimit, setFpsLimitState] = useState<number | undefined>(undefined);\n const [screenRegions, setScreenRegionsState] = useState<ScreenRegions | undefined>(undefined);\n\n /** Lens manager state */\n const [lenses, setLenses] = useState<Lens[]>([]);\n const lensCache = useRef<Map<string, Lens>>(new Map());\n\n /** keep latest cameraKit in a ref for cleanup */\n const kitRef = useRef<{ kit: CameraKit; destroy: () => Promise<void> }>();\n\n /** keep metrics factory in a ref so swapping it doesn’t re-bootstrap */\n const eventFactoryRef = useRef<MetricEventHandlerFactory | undefined>(createBootstrapEventHandler);\n useEffect(() => {\n eventFactoryRef.current = createBootstrapEventHandler;\n }, [createBootstrapEventHandler]);\n\n /**\n * Semantic key:\n * - If stabilityKey is provided - use it as the sole trigger.\n * - Else hash a generic projection of { config, extendContainer } so ANY field change\n * in CameraKitBootstrapConfiguration (or extendContainer) reboots the SDK.\n */\n const bootstrapKey = useMemo(() => {\n if (stabilityKey != null) return String(stabilityKey);\n\n return hash({ config: bootstrapConfig, extendContainer, renderWhileTabHidden });\n }, [bootstrapConfig, extendContainer, renderWhileTabHidden, stabilityKey]);\n\n /* ---------------------------- bootstrap engine ------------------------- */\n useEffect(() => {\n const abortController = new AbortController();\n const emit = eventFactoryRef.current?.();\n\n setCameraKitState({ status: \"initializing\" });\n emit?.({ kind: \"bootstrap-attempt\" });\n log.info(\"bootstrap_attempt\");\n\n bootstrapCameraKitWithSession(\n bootstrapConfig,\n extendContainerWithMetrics(extendContainer),\n { renderWhileTabHidden },\n abortController.signal,\n log,\n )\n .then(({ kit, session, destroy }) => {\n // Store kit reference for cleanup\n kitRef.current = { kit, destroy };\n setCameraKitState({ kit, session, status: \"ready\" });\n log.info(\"bootstrap_success\");\n emit?.({ kind: \"bootstrap-success\" });\n metricsReporter.reportCount(\"bootstrap_success\");\n })\n .catch((error) => {\n // Ignore errors from aborted operations\n if (error.name === \"AbortError\") return;\n\n log.error(\"bootstrap_failure\", error);\n setCameraKitState({ kit: undefined, session: undefined, status: \"error\", error });\n emit?.({ kind: \"bootstrap-failure\", error });\n metricsReporter.reportCount(\"bootstrap_failure\");\n });\n\n return () => {\n abortController.abort();\n kitRef.current?.destroy();\n kitRef.current = undefined;\n };\n // Re-bootstrap when key changes or when manual counter bumps on reinit\n }, [bootstrapKey, bootstrapCounter]);\n\n /* --------------------------- Lens cache cleanup ------------------------ */\n // When Camera Kit errors, remove all Lenses from the local cache.\n // Otherwise, if any component tries to apply a Lens that broke Camera Kit before,\n // Lens manager will fail with cannot find Lens error.\n useEffect(() => {\n if (cameraKitState.session) {\n cameraKitState.session.events.addEventListener(\"error\", (event) => {\n if (event.detail.error.name === \"LensExecutionError\") {\n lensCache.current.clear();\n setLenses([]);\n }\n });\n }\n }, [cameraKitState.session]);\n\n /* ---------------------------- Lens manager methods --------------------- */\n const fetchLens = useCallback(\n async (lensId: string, groupId: string) => {\n try {\n if (!cameraKitState.kit) throw new Error(\"CameraKit not initialized.\");\n const key = `${groupId}:${lensId}`;\n if (lensCache.current.has(key)) return lensCache.current.get(key)!;\n const lens = await cameraKitState.kit.lensRepository.loadLens(lensId, groupId);\n lensCache.current.set(key, lens);\n setLenses((prev) => [...prev, lens]);\n return lens;\n } catch (error) {\n log.error(\"lens_load_failed\", { lensId, groupId }, error);\n throw error;\n }\n },\n [cameraKitState.kit, log],\n );\n\n const fetchLenses = useCallback(\n async (groupId: string | string[]) => {\n try {\n if (!cameraKitState.kit) throw new Error(\"CameraKit not initialized.\");\n\n const { lenses: loaded } = await cameraKitState.kit.lensRepository.loadLensGroups([groupId].flat());\n loaded.forEach((l) => {\n const key = `${l.groupId}:${l.id}`;\n if (!lensCache.current.has(key)) lensCache.current.set(key, l);\n });\n setLenses(Array.from(lensCache.current.values()));\n return loaded;\n } catch (error) {\n log.error(\"lens_group_load_failed\", { groupId }, error);\n throw error;\n }\n },\n [cameraKitState.kit, log],\n );\n\n const applyLens = useCallback(\n async (lensId: string, lensGroupId: string, launchData?: LensLaunchData, lensReadyGuard?: () => Promise<void>) => {\n const commonFields = {\n lensId,\n lensGroupId,\n lensLaunchData: launchData,\n lensReadyGuard,\n };\n let lens: Lens | undefined;\n\n try {\n if (!cameraKitState.session) throw new Error(\"No active session.\");\n\n setLens({\n ...commonFields,\n status: \"loading\",\n error: undefined,\n lens: undefined,\n });\n lens = await fetchLens(lensId, lensGroupId);\n\n // Caller might do an animation and wait for some rendering event.\n // If they return a Promise, we await it.\n const readyPromise = lensReadyGuard?.() ?? Promise.resolve();\n const applyPromise = cameraKitState.session.applyLens(lens, launchData);\n await Promise.race([\n Promise.all([applyPromise, readyPromise]),\n new Promise<void>((resolve) => setTimeout(resolve, readyTimeoutMs)),\n ]);\n setLens({\n ...commonFields,\n status: \"ready\",\n error: undefined,\n lens,\n });\n metricsReporter.reportCount(\"lens_apply_success\");\n return await applyPromise;\n } catch (cause) {\n const error = ensureError(cause);\n log.error(\"lens_apply_failed\", { lensId, lensGroupId }, error);\n setLens({ ...commonFields, status: \"error\", error, lens });\n metricsReporter.reportCount(\"lens_apply_failure\");\n throw error;\n }\n },\n [fetchLens, cameraKitState.session, log],\n );\n\n const removeLens = useCallback(async () => {\n try {\n if (!cameraKitState.session) throw new Error(\"No active session.\");\n\n const removed = await cameraKitState.session.removeLens();\n if (removed) setLens(NO_CURRENT_LENS);\n return removed;\n } catch (error) {\n log.error(\"lens_remove_failed\", error);\n throw error;\n }\n }, [cameraKitState.session, log]);\n\n const refreshLens = useCallback(async () => {\n const { lensId, lensGroupId, lensLaunchData, lensReadyGuard } = lens;\n\n if (!lensId || !lensGroupId) return;\n\n await removeLens();\n await applyLens(lensId, lensGroupId, lensLaunchData, lensReadyGuard);\n }, [lens, removeLens, applyLens]);\n\n /* ---------------------------- source manager methods ------------------- */\n const sourceCleanupRef = useRef<{\n mediaStream?: MediaStream;\n cameraKitSource?: CameraKitSource;\n }>({});\n\n const applySource = useCallback(\n async (input: SourceInput, size?: OutputSize) => {\n try {\n if (!cameraKitState.session) throw new Error(\"No active session.\");\n\n // Clean up previous source\n sourceCleanupRef.current.mediaStream?.getTracks().forEach((track) => track.stop());\n await sourceCleanupRef.current.cameraKitSource?.detach(() => {});\n sourceCleanupRef.current = {};\n\n setSource({\n input,\n status: \"loading\",\n error: undefined,\n initializedInput: undefined,\n });\n\n const { cameraKitSource, transform, inputSize, mediaStream, initializedSourceInput } =\n await createCameraKitSource(input);\n\n // Store refs for cleanup\n sourceCleanupRef.current = { cameraKitSource, mediaStream };\n\n // Pause session, set source, apply transforms and render size, then resume\n await withSessionPaused(cameraKitState.session, async () => {\n await cameraKitState.session!.setSource(cameraKitSource);\n await cameraKitSource.setTransform(transform);\n if (size?.mode === \"fixed\") {\n await cameraKitSource.setRenderSize(size.width, size.height);\n } else if (size?.mode === \"match-input\" && inputSize) {\n await cameraKitSource.setRenderSize(inputSize[0], inputSize[1]);\n }\n });\n\n setSource({\n input,\n initializedInput: initializedSourceInput,\n status: \"ready\",\n error: undefined,\n });\n } catch (cause) {\n const error = ensureError(cause);\n log.error(\"source_apply_failed\", { kind: input.kind }, error);\n setSource({\n input,\n status: \"error\",\n error,\n initializedInput: undefined,\n });\n throw error;\n }\n },\n [cameraKitState.session, log],\n );\n\n const removeSource = useCallback(async () => {\n try {\n // Clean up media stream and detach source\n sourceCleanupRef.current.mediaStream?.getTracks().forEach((track) => track.stop());\n await sourceCleanupRef.current.cameraKitSource?.detach(() => {});\n sourceCleanupRef.current = {};\n\n setSource({\n status: \"none\",\n error: undefined,\n input: undefined,\n initializedInput: undefined,\n });\n } catch (error) {\n log.error(\"source_remove_failed\", error);\n throw error;\n }\n }, [log]);\n\n /* ---------------------------- playback control methods ----------------- */\n const setFPSLimit = useCallback(\n async (fps: number) => {\n try {\n if (!cameraKitState.session) throw new Error(\"No active session.\");\n await cameraKitState.session.setFPSLimit(fps);\n setFpsLimitState(fps);\n } catch (error) {\n log.error(\"fps_limit_set_failed\", { fps }, error);\n throw error;\n }\n },\n [cameraKitState.session, log],\n );\n\n const setMuted = useCallback(\n (muted: boolean) => {\n if (!cameraKitState.session) throw new Error(\"No active session.\");\n if (muted) {\n cameraKitState.session.mute();\n } else {\n cameraKitState.session.unmute();\n }\n setIsMuted(muted);\n },\n [cameraKitState.session],\n );\n\n const toggleMuted = useCallback(() => {\n setMuted(!isMuted);\n }, [isMuted, setMuted]);\n\n const setScreenRegions = useCallback(\n async (regions: ScreenRegions) => {\n try {\n if (!cameraKitState.session) throw new Error(\"No active session.\");\n await cameraKitState.session.setScreenRegions(regions);\n setScreenRegionsState(regions);\n } catch (error) {\n log.error(\"screen_regions_set_failed\", error);\n throw error;\n }\n },\n [cameraKitState.session, log],\n );\n\n const abortCameraKit = useCallback(\n (error: unknown) => {\n cameraKitState.kit?.destroy().catch((cause) => {\n log.error(\"kit_destroy_failed\", cause);\n });\n setCameraKitState({ kit: undefined, status: \"error\", error: ensureError(error) });\n },\n [cameraKitState.kit, log],\n );\n\n useEffect(() => {\n if (!cameraKitState.session) return;\n\n function handleSessionError(event: CameraKitSessionEvents) {\n if (event.detail.error.name === \"LensExecutionError\") {\n // Update lens state to error, but don't abort the entire SDK.\n // This allows the user to apply a new lens and recover from the error.\n setLens((currentLens) => ({\n ...currentLens,\n status: \"error\",\n error: event.detail.error,\n }));\n } else if (event.detail.error.name === \"LensAbortError\") {\n // LensAbortError is a critical error that requires SDK re-initialization.\n // Abort the SDK so the user must call reinitialize() to recover.\n metricsReporter.reportCount(\"session_lens_abort_error\");\n abortCameraKit(event.detail.error);\n }\n }\n\n cameraKitState.session.events.addEventListener(\"error\", handleSessionError);\n\n return () => cameraKitState.session!.events.removeEventListener(\"error\", handleSessionError);\n }, [cameraKitState.session, abortCameraKit]);\n\n /* ---------------------------- memoised context ------------------------- */\n const ctxValue: InternalCameraKitContextValue = useMemo(\n () => ({\n cameraKit: cameraKitState.kit,\n currentSession: cameraKitState.session,\n sdkStatus: cameraKitState.status,\n sdkError: cameraKitState.error,\n\n // Canvas elements\n liveCanvas: cameraKitState.session?.output.live,\n captureCanvas: cameraKitState.session?.output.capture,\n\n source,\n lens,\n\n // Playback state\n isMuted,\n fpsLimit,\n screenRegions,\n\n keyboard: cameraKitState.session?.keyboard,\n\n getLogger,\n\n abortCameraKit,\n\n reinitialize: () => {\n if (cameraKitState.status === \"error\" && !cameraKitState.kit) {\n setBootstrapCounter((prev) => prev + 1);\n } else {\n throw new Error(\"Cannot re-initialize CameraKit when it is not in an aborted state.\");\n }\n },\n\n // Lens manager methods\n fetchLens,\n fetchLenses,\n applyLens,\n removeLens,\n refreshLens,\n lenses,\n\n // Source manager methods\n applySource,\n removeSource,\n\n // Playback control methods\n setFPSLimit,\n setMuted,\n toggleMuted,\n setScreenRegions,\n }),\n [\n cameraKitState,\n source,\n lens,\n isMuted,\n fpsLimit,\n screenRegions,\n getLogger,\n fetchLens,\n fetchLenses,\n applyLens,\n removeLens,\n refreshLens,\n lenses,\n applySource,\n removeSource,\n setFPSLimit,\n setMuted,\n toggleMuted,\n setScreenRegions,\n abortCameraKit,\n ],\n );\n\n return <CameraKitContext.Provider value={ctxValue}>{children}</CameraKitContext.Provider>;\n};\n\n/**\n * Internal hook with access to Camera Kit internals.\n * Only for use within react-camera-kit library components and hooks.\n *\n * @internal\n */\nexport const useInternalCameraKit = (): InternalCameraKitContextValue => {\n const context = useContext(CameraKitContext);\n if (!context) {\n throw new Error(\"useInternalCameraKit must be used within a CameraKitProvider\");\n }\n return context;\n};\n\n/**\n * Hook to access Camera Kit context and methods.\n *\n * Provides access to SDK state, Lens management, source control, and playback options.\n * Must be used within a CameraKitProvider.\n *\n * @returns Camera Kit context value with state and methods\n * @throws Error if used outside of CameraKitProvider\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const {\n * sdkStatus,\n * lens,\n * applyLens,\n * removeLens,\n * liveCanvas\n * } = useCameraKit();\n *\n * useEffect(() => {\n * if (sdkStatus === 'ready') {\n * applyLens('lens-id', 'group-id');\n * }\n * }, [sdkStatus, applyLens]);\n *\n * return <div>{lens.status}</div>;\n * }\n * ```\n */\nexport const useCameraKit = (): CameraKitContextValue => {\n const context = useContext(CameraKitContext);\n if (!context) {\n throw new Error(\"useCameraKit must be used within a CameraKitProvider\");\n }\n // Return only the public API (exclude internal fields)\n const { cameraKit: _cameraKit, currentSession: _currentSession, getLogger: _getLogger, ...publicContext } = context;\n return publicContext;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../src/Canvas.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAYD,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAiBjD,CAAC;AAGF,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAiBpD,CAAC"}
|