@momo-kits/camerakit 0.161.2-beta.2 → 0.161.2-beta.26

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.
@@ -71,6 +71,10 @@ public class CameraView: UIView {
71
71
 
72
72
  // This is used to delay camera setup until we have both granted permission & received default props
73
73
  var hasCameraBeenSetup = false
74
+ // [CKCameraKit][perf] TEMP measurement — remove before publish. Captured when the
75
+ // view is constructed so we can see how long the OUTSIDE path (permission grant +
76
+ // first props) takes before camera.setup() is even called.
77
+ private let viewCreatedAt = CFAbsoluteTimeGetCurrent()
74
78
  var hasPropBeenSetup = false {
75
79
  didSet {
76
80
  setupCamera()
@@ -84,6 +88,8 @@ public class CameraView: UIView {
84
88
  private func setupCamera() {
85
89
  if hasPropBeenSetup && hasPermissionBeenGranted && !hasCameraBeenSetup {
86
90
  hasCameraBeenSetup = true
91
+ // [CKCameraKit][perf] TEMP measurement — remove before publish.
92
+ print(String(format: "[CKCameraKit][perf] view→setupCalled=%.0fms (permission+props before setup)", (CFAbsoluteTimeGetCurrent() - viewCreatedAt) * 1000))
87
93
  #if targetEnvironment(macCatalyst)
88
94
  // Force front camera on Mac Catalyst during initial setup
89
95
  camera.setup(cameraType: .front, supportedBarcodeType: scanBarcode && onReadCode != nil ? supportedBarcodeType : [])
@@ -72,6 +72,23 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
72
72
 
73
73
  // MARK: - Lifecycle
74
74
 
75
+ override init() {
76
+ super.init()
77
+ #if DEBUG
78
+ assert(Thread.isMainThread, "RealCamera must be initialized on the main thread (it wires the preview CALayer).")
79
+ #endif
80
+ // Wire the preview to the (idle, never-started) session AND set its gravity
81
+ // ONCE here at init, on the main thread, before anything starts. Benefits:
82
+ // (a) the preview renders the instant the first frame arrives (~camera warm-up)
83
+ // instead of waiting for a late post-setup attach → less black.
84
+ // (b) assigning previewLayer.session opens an implicit AVFoundation config
85
+ // transaction; doing it now (session idle, no startRunning yet, never
86
+ // reassigned) makes it impossible to race startRunning() → the begin/commit
87
+ // crash class is closed by construction, on every device.
88
+ cameraPreview.session = session
89
+ cameraPreview.previewLayer.videoGravity = .resizeAspectFill
90
+ }
91
+
75
92
  func cameraRemovedFromSuperview() {
76
93
  sessionQueue.async { [weak self] in
77
94
  guard let self, self.setupResult == .success else { return }
@@ -114,8 +131,11 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
114
131
  // MARK: - Public
115
132
 
116
133
  func setup(cameraType: CameraType, supportedBarcodeType: [CodeFormat]) {
134
+ // [CKCameraKit][perf] TEMP measurement — remove before publish.
135
+ let tCall = CFAbsoluteTimeGetCurrent()
117
136
  sessionQueue.async { [weak self] in
118
137
  guard let self else { return }
138
+ let tBlock = CFAbsoluteTimeGetCurrent()
119
139
 
120
140
  // Idempotency guard: a RealCamera configures its session exactly once.
121
141
  // A fresh instance is created on every mount / Fabric recycle, so this
@@ -133,24 +153,33 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
133
153
  // calls to beginConfiguration and commitConfiguration".
134
154
  self.setupResult = self.configureSession(cameraType: cameraType,
135
155
  supportedBarcodeType: supportedBarcodeType)
156
+ let tConfigured = CFAbsoluteTimeGetCurrent()
136
157
 
137
158
  guard self.setupResult == .success else { return }
138
159
 
139
- // Order matches the previous behaviour: start, then observe, then torch.
140
- self.startSessionIfNeeded()
141
- self.addObservers()
142
- self.update(torchMode: self.torchMode)
143
-
144
- // Only the preview LAYER is touched on the main queue. Connecting an
145
- // AVCaptureVideoPreviewLayer to a session from the main thread is
146
- // sanctioned by AVFoundation (see Apple's AVCam) and does NOT open a
147
- // session configuration transaction, so it cannot race startRunning().
160
+ // Set the preview orientation on the main queue NOW BEFORE the (~145ms)
161
+ // startRunning below — so the very first frame renders at the correct
162
+ // orientation instead of appearing once and then snapping ("giật 1 nhịp").
163
+ // The preview's `.session` and gravity are already wired at init; this is a
164
+ // pure connection-property write (no session config transaction → no race
165
+ // with startRunning). The connection exists because configureSession has
166
+ // committed the video input above.
148
167
  DispatchQueue.main.async { [weak self] in
149
168
  guard let self else { return }
150
- self.cameraPreview.session = self.session
151
- self.cameraPreview.previewLayer.videoGravity = .resizeAspectFill
152
169
  self.setVideoOrientationToInterfaceOrientation()
153
170
  }
171
+
172
+ // Order matches the previous behaviour: start, then observe, then torch.
173
+ self.startSessionIfNeeded()
174
+ let tStarted = CFAbsoluteTimeGetCurrent()
175
+ // [CKCameraKit][perf] TEMP measurement — remove before publish.
176
+ print(String(format: "[CKCameraKit][perf] queueWait=%.0fms configure=%.0fms startRunning=%.0fms setupTotal=%.0fms",
177
+ (tBlock - tCall) * 1000,
178
+ (tConfigured - tBlock) * 1000,
179
+ (tStarted - tConfigured) * 1000,
180
+ (tStarted - tCall) * 1000))
181
+ self.addObservers()
182
+ self.update(torchMode: self.torchMode)
154
183
  }
155
184
 
156
185
  DispatchQueue.global(qos: .utility).async { [weak self] in
package/package.json CHANGED
@@ -1,41 +1,41 @@
1
1
  {
2
- "name": "@momo-kits/camerakit",
3
- "version": "0.161.2-beta.2",
4
- "repository": {
5
- "type": "git",
6
- "url": "https://github.com/teslamotors/react-native-camera-kit.git"
7
- },
8
- "publishConfig": {
9
- "registry": "https://registry.npmjs.org/"
10
- },
11
- "description": "A high performance, fully featured, rock solid camera library for React Native applications",
12
- "nativePackage": true,
13
- "scripts": {
14
- "build": "echo",
15
- "test": "jest",
16
- "lint": "yarn eslint -c .eslintrc.js"
17
- },
18
- "main": "./src/index.ts",
19
- "dependencies": {},
20
- "license": "MIT",
21
- "devDependencies": {
22
- "react": "19.0.0",
23
- "react-native": "0.80.1"
24
- },
25
- "peerDependencies": {
26
- "react": "*",
27
- "react-native": "*"
28
- },
29
- "engines": {
30
- "node": ">=18"
31
- },
32
- "codegenConfig": {
33
- "name": "rncamerakit_specs",
34
- "type": "all",
35
- "jsSrcsDir": "src/specs",
36
- "android": {
37
- "javaPackageName": "com.rncamerakit"
38
- }
39
- },
40
- "packageManager": "yarn@1.22.22"
41
- }
2
+ "name": "@momo-kits/camerakit",
3
+ "version": "0.161.2-beta.26",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/teslamotors/react-native-camera-kit.git"
7
+ },
8
+ "publishConfig": {
9
+ "registry": "https://registry.npmjs.org/"
10
+ },
11
+ "description": "A high performance, fully featured, rock solid camera library for React Native applications",
12
+ "nativePackage": true,
13
+ "scripts": {
14
+ "build": "echo",
15
+ "test": "jest",
16
+ "lint": "yarn eslint -c .eslintrc.js"
17
+ },
18
+ "main": "./src/index.ts",
19
+ "dependencies": {},
20
+ "license": "MIT",
21
+ "devDependencies": {
22
+ "react": "19.0.0",
23
+ "react-native": "0.80.1"
24
+ },
25
+ "peerDependencies": {
26
+ "react": "*",
27
+ "react-native": "*"
28
+ },
29
+ "engines": {
30
+ "node": ">=18"
31
+ },
32
+ "codegenConfig": {
33
+ "name": "rncamerakit_specs",
34
+ "type": "all",
35
+ "jsSrcsDir": "src/specs",
36
+ "android": {
37
+ "javaPackageName": "com.rncamerakit"
38
+ }
39
+ },
40
+ "packageManager": "yarn@1.22.22"
41
+ }