bleam 0.0.7 → 0.0.9
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/cli.cjs +23 -4
- package/dist/cli.d.cts +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +23 -4
- package/dist/{ui-234Plg7Z.d.cts → ui-Bg11tvlc.d.ts} +7 -7
- package/dist/ui.d.ts +1 -1
- package/dist/window.d.ts +1 -1
- package/package.json +4 -1
- package/templates/image-generation/app/index.tsx +1 -1
- package/templates/native/.gitattributes +1 -0
- package/templates/native/App.tsx +26 -0
- package/templates/native/app.json +12 -0
- package/templates/native/index.ts +8 -0
- package/templates/native/ios/.xcode.env +11 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/Flux2Config.swift +288 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/MemoryConfig.swift +233 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/MemoryOptimizationConfig.swift +157 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/ModelRegistry.swift +425 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/QuantizationConfig.swift +138 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/TransformerRepoProfile.swift +59 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/VAEConfig.swift +134 -0
- package/templates/native/ios/Bleam/AI/Flux2/Flux2Core.swift +55 -0
- package/templates/native/ios/Bleam/AI/Flux2/Loading/WeightLoader.swift +1192 -0
- package/templates/native/ios/Bleam/AI/Flux2/Pipeline/FluxImageRunner.swift +1282 -0
- package/templates/native/ios/Bleam/AI/Flux2/Pipeline/LatentUtils.swift +191 -0
- package/templates/native/ios/Bleam/AI/Flux2/Scheduler/FlowMatchEulerScheduler.swift +279 -0
- package/templates/native/ios/Bleam/AI/Flux2/Text/KleinTextEncoder.swift +380 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Attention.swift +379 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Embeddings.swift +159 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2FeedForward.swift +154 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2FusedKernels.swift +198 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2KVCache.swift +36 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Modulation.swift +193 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2ParallelAttention.swift +389 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2RoPE.swift +304 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2SingleBlock.swift +290 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Transformer.swift +530 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2TransformerBlock.swift +362 -0
- package/templates/native/ios/Bleam/AI/Flux2/Utils/Flux2Debug.swift +101 -0
- package/templates/native/ios/Bleam/AI/Flux2/Utils/MLXCheckpoint.swift +118 -0
- package/templates/native/ios/Bleam/AI/Flux2/Utils/MemoryManager.swift +201 -0
- package/templates/native/ios/Bleam/AI/Flux2/VAE/AutoencoderKL.swift +476 -0
- package/templates/native/ios/Bleam/AI/Flux2/VAE/ResnetBlock.swift +316 -0
- package/templates/native/ios/Bleam/AI/Flux2/VAE/VAEDecoder.swift +120 -0
- package/templates/native/ios/Bleam/AI/Flux2/VAE/VAEEncoder.swift +136 -0
- package/templates/native/ios/Bleam/AppDelegate.swift +373 -0
- package/templates/native/ios/Bleam/Appearance.swift +62 -0
- package/templates/native/ios/Bleam/Bridging-Header.h +3 -0
- package/templates/native/ios/Bleam/Images.xcassets/AppIcon.appiconset/Contents.json +13 -0
- package/templates/native/ios/Bleam/Images.xcassets/Contents.json +6 -0
- package/templates/native/ios/Bleam/Info.plist +76 -0
- package/templates/native/ios/Bleam/PrivacyInfo.xcprivacy +48 -0
- package/templates/native/ios/Bleam/SceneDelegate.swift +58 -0
- package/templates/native/ios/Bleam/SplashScreen.storyboard +47 -0
- package/templates/native/ios/Bleam/Supporting/Expo.plist +6 -0
- package/templates/native/ios/Bleam/bleam.entitlements +10 -0
- package/templates/native/ios/Bleam.xcodeproj/project.pbxproj +1146 -0
- package/templates/native/ios/Bleam.xcodeproj/xcshareddata/xcschemes/Bleam.xcscheme +88 -0
- package/templates/native/ios/GenerationService/GenerationService.entitlements +10 -0
- package/templates/native/ios/GenerationService/ImageGenerationRunner.swift +591 -0
- package/templates/native/ios/GenerationService/Info.plist +31 -0
- package/templates/native/ios/GenerationService/main.swift +165 -0
- package/templates/native/ios/PlatformHelper/Info.plist +29 -0
- package/templates/native/ios/PlatformHelper/main.swift +335 -0
- package/templates/native/ios/Podfile +198 -0
- package/templates/native/ios/Podfile.lock +2284 -0
- package/templates/native/ios/Podfile.properties.json +5 -0
- package/templates/native/ios/Shared/Generation/GenerationServiceProtocol.swift +12 -0
- package/templates/native/ios/Shared/Generation/GenerationWorkerProtocol.swift +124 -0
- package/templates/native/metro.config.js +6 -0
- package/templates/native/modules/bleam-runtime/BleamRuntime.podspec +14 -0
- package/templates/native/modules/bleam-runtime/expo-module.config.json +8 -0
- package/templates/native/modules/bleam-runtime/ios/AIModule.swift +1258 -0
- package/templates/native/modules/bleam-runtime/ios/GenerationContracts.swift +135 -0
- package/templates/native/modules/bleam-runtime/ios/PlatformModule.swift +313 -0
- package/templates/native/modules/bleam-runtime/package.json +5 -0
- package/templates/native/package.json +39 -0
- package/templates/native/scripts/build/mlx-frameworks.ts +421 -0
- package/templates/native/scripts/start/index.ts +474 -0
- package/templates/native/scripts/start/known-failures.ts +20 -0
- package/templates/native/scripts/start/loader.ts +76 -0
- package/templates/native/scripts/start/native-state.ts +242 -0
- package/templates/native/scripts/start/package.json +4 -0
- package/templates/native/scripts/start/swift-packages.ts +414 -0
- package/templates/native/scripts/start/xcode-formatter.ts +106 -0
- package/templates/native/tsconfig.json +14 -0
- package/templates/native/yarn.lock +3749 -0
- package/dist/ui-BJmXhz9Q.d.ts +0 -92
- package/dist/ui-Dd7SXdbg.d.cts +0 -92
- package/dist/ui-Ds88eETu.d.ts +0 -92
- package/dist/ui-TaqnB5SP.d.ts +0 -92
- package/dist/ui-WQvnXL0W.d.ts +0 -92
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
@objc protocol GenerationServiceProtocol {
|
|
4
|
+
func startGeneration(requestData: Data, reply: @escaping (Bool) -> Void)
|
|
5
|
+
func cancelGeneration(reply: @escaping (Bool) -> Void)
|
|
6
|
+
func memoryTelemetry(reply: @escaping (Data?) -> Void)
|
|
7
|
+
func shutdown(reply: @escaping (Bool) -> Void)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@objc protocol GenerationServiceClientProtocol {
|
|
11
|
+
func generationWorkerDidEmit(eventData: Data)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
struct GenerationWorkerRequest: Codable, Sendable {
|
|
15
|
+
let jobID: UUID
|
|
16
|
+
let model: String
|
|
17
|
+
let prompt: String
|
|
18
|
+
let sourceImagePath: String?
|
|
19
|
+
let maskImagePath: String?
|
|
20
|
+
let maskMode: String?
|
|
21
|
+
let outpaintWidth: Int?
|
|
22
|
+
let outpaintHeight: Int?
|
|
23
|
+
let outpaintSourceX: Int?
|
|
24
|
+
let outpaintSourceY: Int?
|
|
25
|
+
let outpaintSourceWidth: Int?
|
|
26
|
+
let outpaintSourceHeight: Int?
|
|
27
|
+
let outpaintAutoCrop: Bool?
|
|
28
|
+
let resizeMode: String?
|
|
29
|
+
let maxInputLongSide: Int?
|
|
30
|
+
let referenceImagePaths: [String]
|
|
31
|
+
let referenceInfluences: [Double]?
|
|
32
|
+
let loraPaths: [String]
|
|
33
|
+
let loraScales: [Double]?
|
|
34
|
+
let loraIds: [String]?
|
|
35
|
+
let sigmaSchedule: [Double]?
|
|
36
|
+
let width: Int
|
|
37
|
+
let height: Int
|
|
38
|
+
let steps: Int
|
|
39
|
+
let guidance: Double
|
|
40
|
+
let strength: Double?
|
|
41
|
+
let seed: Int?
|
|
42
|
+
let inputIds: [Int]
|
|
43
|
+
let attentionMask: [Int]
|
|
44
|
+
let modelRoot: String
|
|
45
|
+
let textEncoderPath: String
|
|
46
|
+
let transformerPath: String
|
|
47
|
+
let vaePath: String
|
|
48
|
+
let stagingDirectoryPath: String
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
struct GenerationWorkerEvent: Codable, Sendable {
|
|
52
|
+
enum EventType: String, Codable, Sendable {
|
|
53
|
+
case ready
|
|
54
|
+
case progress
|
|
55
|
+
case completed
|
|
56
|
+
case canceled
|
|
57
|
+
case failed
|
|
58
|
+
case log
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let type: EventType
|
|
62
|
+
let message: String?
|
|
63
|
+
let currentStep: Int?
|
|
64
|
+
let totalSteps: Int?
|
|
65
|
+
let path: String?
|
|
66
|
+
let width: Int?
|
|
67
|
+
let height: Int?
|
|
68
|
+
let model: String?
|
|
69
|
+
let level: String?
|
|
70
|
+
let category: String?
|
|
71
|
+
let jobID: String?
|
|
72
|
+
let stage: String?
|
|
73
|
+
let metadata: GenerationWorkerMetadata?
|
|
74
|
+
|
|
75
|
+
init(
|
|
76
|
+
type: EventType,
|
|
77
|
+
message: String? = nil,
|
|
78
|
+
currentStep: Int? = nil,
|
|
79
|
+
totalSteps: Int? = nil,
|
|
80
|
+
path: String? = nil,
|
|
81
|
+
width: Int? = nil,
|
|
82
|
+
height: Int? = nil,
|
|
83
|
+
model: String? = nil,
|
|
84
|
+
level: String? = nil,
|
|
85
|
+
category: String? = nil,
|
|
86
|
+
jobID: String? = nil,
|
|
87
|
+
stage: String? = nil,
|
|
88
|
+
metadata: GenerationWorkerMetadata? = nil
|
|
89
|
+
) {
|
|
90
|
+
self.type = type
|
|
91
|
+
self.message = message
|
|
92
|
+
self.currentStep = currentStep
|
|
93
|
+
self.totalSteps = totalSteps
|
|
94
|
+
self.path = path
|
|
95
|
+
self.width = width
|
|
96
|
+
self.height = height
|
|
97
|
+
self.model = model
|
|
98
|
+
self.level = level
|
|
99
|
+
self.category = category
|
|
100
|
+
self.jobID = jobID
|
|
101
|
+
self.stage = stage
|
|
102
|
+
self.metadata = metadata
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
struct GenerationWorkerFailure: LocalizedError {
|
|
107
|
+
let message: String
|
|
108
|
+
let stage: String?
|
|
109
|
+
|
|
110
|
+
init(message: String, stage: String? = nil) {
|
|
111
|
+
self.message = message
|
|
112
|
+
self.stage = stage
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
var errorDescription: String? { message }
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
struct GenerationWorkerMetadata: Codable, Sendable {
|
|
119
|
+
let model: String
|
|
120
|
+
let width: Int
|
|
121
|
+
let height: Int
|
|
122
|
+
let steps: Int
|
|
123
|
+
let guidance: Double
|
|
124
|
+
let strength: Double?
|
|
125
|
+
let seed: Int?
|
|
126
|
+
let elapsedMs: Int
|
|
127
|
+
let appliedLoRAs: [GenerationWorkerLoRA]?
|
|
128
|
+
let sigmaSchedule: [Double]?
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
struct GenerationWorkerLoRA: Codable, Sendable {
|
|
132
|
+
let id: String?
|
|
133
|
+
let path: String
|
|
134
|
+
let scale: Double
|
|
135
|
+
}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import AVFoundation
|
|
2
|
+
import Contacts
|
|
3
|
+
import CoreLocation
|
|
4
|
+
import EventKit
|
|
5
|
+
import ExpoModulesCore
|
|
6
|
+
import Foundation
|
|
7
|
+
import Photos
|
|
8
|
+
|
|
9
|
+
@objc private protocol PlatformHelperProtocol {
|
|
10
|
+
func health(reply: @escaping (Data?) -> Void)
|
|
11
|
+
func downloadPlatformUpdate(requestData: Data, reply: @escaping (Data?) -> Void)
|
|
12
|
+
func applyPlatformUpdate(requestData: Data, reply: @escaping (Bool) -> Void)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public final class PlatformModule: Module {
|
|
16
|
+
public func definition() -> ModuleDefinition {
|
|
17
|
+
Name("Platform")
|
|
18
|
+
|
|
19
|
+
AsyncFunction("helperStatus") { (promise: Promise) in
|
|
20
|
+
guard Self.isSupportedInstallLocation else {
|
|
21
|
+
UserDefaults.standard.set(false, forKey: "BleamPlatformUpdatesSupported")
|
|
22
|
+
promise.resolve([
|
|
23
|
+
"healthy": false,
|
|
24
|
+
"protocolVersion": 1,
|
|
25
|
+
"helperVersion": "unavailable",
|
|
26
|
+
"platformVersion": "unavailable",
|
|
27
|
+
"capabilities": [],
|
|
28
|
+
"updatesSupported": false,
|
|
29
|
+
"installPath": Bundle.main.bundleURL.path,
|
|
30
|
+
"reason": "reinstall_required",
|
|
31
|
+
])
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
let serviceName = "\(Bundle.main.bundleIdentifier ?? "dev.bleam.app").PlatformHelper"
|
|
35
|
+
guard let connection = Self.makeConnection(serviceName: serviceName) else {
|
|
36
|
+
promise.reject("HELPER_UNAVAILABLE", "The app helper is unavailable")
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
connection.remoteObjectInterface = NSXPCInterface(with: PlatformHelperProtocol.self)
|
|
40
|
+
connection.resume()
|
|
41
|
+
|
|
42
|
+
guard let service = connection.remoteObjectProxyWithErrorHandler({ error in
|
|
43
|
+
connection.invalidate()
|
|
44
|
+
promise.reject("HELPER_UNAVAILABLE", error.localizedDescription)
|
|
45
|
+
}) as? PlatformHelperProtocol else {
|
|
46
|
+
connection.invalidate()
|
|
47
|
+
promise.reject("HELPER_UNAVAILABLE", "The app helper is unavailable")
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
service.health { data in
|
|
52
|
+
defer { connection.invalidate() }
|
|
53
|
+
guard
|
|
54
|
+
let data,
|
|
55
|
+
var status = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
|
|
56
|
+
else {
|
|
57
|
+
promise.reject("HELPER_INVALID_RESPONSE", "The app helper returned an invalid response")
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
let supported = Self.isSupportedInstallLocation
|
|
61
|
+
status["updatesSupported"] = supported
|
|
62
|
+
status["installPath"] = Bundle.main.bundleURL.path
|
|
63
|
+
if !supported {
|
|
64
|
+
status["reason"] = "reinstall_required"
|
|
65
|
+
}
|
|
66
|
+
UserDefaults.standard.set(status["healthy"], forKey: "BleamHelperHealthy")
|
|
67
|
+
UserDefaults.standard.set(status["platformVersion"], forKey: "BleamHelperPlatformVersion")
|
|
68
|
+
UserDefaults.standard.set(supported, forKey: "BleamPlatformUpdatesSupported")
|
|
69
|
+
promise.resolve(status)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
AsyncFunction("permissionState") { (capability: String, promise: Promise) in
|
|
74
|
+
guard let state = Self.permissionState(capability) else {
|
|
75
|
+
promise.reject("INVALID_CAPABILITY", "Unknown permission capability: \(capability)")
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
promise.resolve(Self.permissionResponse(capability: capability, state: state))
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
AsyncFunction("permissionStates") { (promise: Promise) in
|
|
82
|
+
let states: [[String: Any]] = Self.permissionCapabilities.compactMap { capability in
|
|
83
|
+
guard let state = Self.permissionState(capability) else { return nil }
|
|
84
|
+
return Self.permissionResponse(capability: capability, state: state)
|
|
85
|
+
}
|
|
86
|
+
promise.resolve(states)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
AsyncFunction("downloadPlatformUpdate") { (promise: Promise) in
|
|
90
|
+
guard Self.isSupportedInstallLocation else {
|
|
91
|
+
promise.reject("REINSTALL_REQUIRED", "Platform updates require the app to be installed directly in ~/Applications")
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
guard
|
|
95
|
+
let serviceURL = Bundle.main.object(forInfoDictionaryKey: "BleamUpdateServiceURL") as? String,
|
|
96
|
+
let bundleIdentifier = Bundle.main.bundleIdentifier,
|
|
97
|
+
let teamIdentifier = Bundle.main.object(forInfoDictionaryKey: "BleamTeamIdentifier") as? String,
|
|
98
|
+
let requestData = try? JSONSerialization.data(withJSONObject: [
|
|
99
|
+
"serviceURL": serviceURL,
|
|
100
|
+
"bundleIdentifier": bundleIdentifier,
|
|
101
|
+
"teamIdentifier": teamIdentifier,
|
|
102
|
+
])
|
|
103
|
+
else {
|
|
104
|
+
promise.reject("UPDATES_UNAVAILABLE", "Platform updates are not configured")
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
guard let connection = Self.makeConnection(serviceName: "\(bundleIdentifier).PlatformHelper") else {
|
|
109
|
+
promise.reject("HELPER_UNAVAILABLE", "The app helper is unavailable")
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
connection.remoteObjectInterface = NSXPCInterface(with: PlatformHelperProtocol.self)
|
|
113
|
+
connection.resume()
|
|
114
|
+
guard let service = connection.remoteObjectProxyWithErrorHandler({ error in
|
|
115
|
+
connection.invalidate()
|
|
116
|
+
promise.reject("PLATFORM_DOWNLOAD_FAILED", error.localizedDescription)
|
|
117
|
+
}) as? PlatformHelperProtocol else {
|
|
118
|
+
connection.invalidate()
|
|
119
|
+
promise.reject("HELPER_UNAVAILABLE", "The app helper is unavailable")
|
|
120
|
+
return
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
service.downloadPlatformUpdate(requestData: requestData) { data in
|
|
124
|
+
defer { connection.invalidate() }
|
|
125
|
+
guard
|
|
126
|
+
let data,
|
|
127
|
+
let result = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
|
|
128
|
+
else {
|
|
129
|
+
promise.reject("PLATFORM_DOWNLOAD_FAILED", "The platform update could not be downloaded")
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
if let error = result["error"] as? String {
|
|
133
|
+
UserDefaults.standard.set(error, forKey: "BleamPlatformDownloadError")
|
|
134
|
+
promise.reject("PLATFORM_VERIFICATION_FAILED", error)
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
UserDefaults.standard.set(result["releaseId"], forKey: "BleamPlatformDownloadRelease")
|
|
138
|
+
promise.resolve(result)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
AsyncFunction("updateAndRelaunch") { (releaseId: String, promise: Promise) in
|
|
143
|
+
guard Self.isSupportedInstallLocation else {
|
|
144
|
+
promise.reject("REINSTALL_REQUIRED", "Platform updates require the app to be installed directly in ~/Applications")
|
|
145
|
+
return
|
|
146
|
+
}
|
|
147
|
+
guard
|
|
148
|
+
let bundleIdentifier = Bundle.main.bundleIdentifier,
|
|
149
|
+
let teamIdentifier = Bundle.main.object(forInfoDictionaryKey: "BleamTeamIdentifier") as? String,
|
|
150
|
+
let requestData = try? JSONSerialization.data(withJSONObject: [
|
|
151
|
+
"releaseId": releaseId,
|
|
152
|
+
"bundleIdentifier": bundleIdentifier,
|
|
153
|
+
"teamIdentifier": teamIdentifier,
|
|
154
|
+
"installedAppPath": Bundle.main.bundleURL.path,
|
|
155
|
+
"appPID": ProcessInfo.processInfo.processIdentifier,
|
|
156
|
+
]),
|
|
157
|
+
let connection = Self.makeConnection(serviceName: "\(bundleIdentifier).PlatformHelper")
|
|
158
|
+
else {
|
|
159
|
+
promise.reject("PLATFORM_UPDATE_UNAVAILABLE", "The platform update cannot be applied")
|
|
160
|
+
return
|
|
161
|
+
}
|
|
162
|
+
connection.remoteObjectInterface = NSXPCInterface(with: PlatformHelperProtocol.self)
|
|
163
|
+
connection.resume()
|
|
164
|
+
guard let service = connection.remoteObjectProxyWithErrorHandler({ error in
|
|
165
|
+
connection.invalidate()
|
|
166
|
+
promise.reject("PLATFORM_UPDATE_FAILED", error.localizedDescription)
|
|
167
|
+
}) as? PlatformHelperProtocol else {
|
|
168
|
+
connection.invalidate()
|
|
169
|
+
promise.reject("HELPER_UNAVAILABLE", "The app helper is unavailable")
|
|
170
|
+
return
|
|
171
|
+
}
|
|
172
|
+
service.applyPlatformUpdate(requestData: requestData) { accepted in
|
|
173
|
+
connection.invalidate()
|
|
174
|
+
UserDefaults.standard.set(accepted, forKey: "BleamPlatformApplyAccepted")
|
|
175
|
+
guard accepted else {
|
|
176
|
+
promise.reject("PLATFORM_UPDATE_REJECTED", "The platform update is not verified or the app is not installed in ~/Applications")
|
|
177
|
+
return
|
|
178
|
+
}
|
|
179
|
+
promise.resolve(nil)
|
|
180
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
|
|
181
|
+
exit(0)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
private static func makeConnection(serviceName: String) -> NSXPCConnection? {
|
|
188
|
+
#if targetEnvironment(macCatalyst)
|
|
189
|
+
let connectionClass: AnyObject = NSXPCConnection.self as AnyObject
|
|
190
|
+
let allocated = connectionClass.perform(NSSelectorFromString("alloc"))?.takeUnretainedValue() as AnyObject?
|
|
191
|
+
return allocated?.perform(
|
|
192
|
+
NSSelectorFromString("initWithServiceName:"),
|
|
193
|
+
with: serviceName
|
|
194
|
+
)?.takeUnretainedValue() as? NSXPCConnection
|
|
195
|
+
#else
|
|
196
|
+
return NSXPCConnection(serviceName: serviceName)
|
|
197
|
+
#endif
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private static let permissionCapabilities = [
|
|
201
|
+
"camera",
|
|
202
|
+
"microphone",
|
|
203
|
+
"photos",
|
|
204
|
+
"contacts",
|
|
205
|
+
"calendars",
|
|
206
|
+
"reminders",
|
|
207
|
+
"location",
|
|
208
|
+
]
|
|
209
|
+
|
|
210
|
+
private static func permissionResponse(capability: String, state: String) -> [String: Any] {
|
|
211
|
+
[
|
|
212
|
+
"capability": capability,
|
|
213
|
+
"status": state,
|
|
214
|
+
"granted": state == "granted" || state == "limited",
|
|
215
|
+
"canAskAgain": state == "not-determined",
|
|
216
|
+
"expires": "never",
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
private static func permissionState(_ capability: String) -> String? {
|
|
221
|
+
switch capability {
|
|
222
|
+
case "camera":
|
|
223
|
+
return authorizationState(AVCaptureDevice.authorizationStatus(for: .video))
|
|
224
|
+
case "microphone":
|
|
225
|
+
return authorizationState(AVCaptureDevice.authorizationStatus(for: .audio))
|
|
226
|
+
case "photos":
|
|
227
|
+
switch PHPhotoLibrary.authorizationStatus(for: .readWrite) {
|
|
228
|
+
case .authorized:
|
|
229
|
+
return "granted"
|
|
230
|
+
case .limited:
|
|
231
|
+
return "limited"
|
|
232
|
+
case .denied:
|
|
233
|
+
return "denied"
|
|
234
|
+
case .restricted:
|
|
235
|
+
return "restricted"
|
|
236
|
+
case .notDetermined:
|
|
237
|
+
return "not-determined"
|
|
238
|
+
@unknown default:
|
|
239
|
+
return "unsupported"
|
|
240
|
+
}
|
|
241
|
+
case "contacts":
|
|
242
|
+
switch CNContactStore.authorizationStatus(for: .contacts) {
|
|
243
|
+
case .authorized:
|
|
244
|
+
return "granted"
|
|
245
|
+
case .denied:
|
|
246
|
+
return "denied"
|
|
247
|
+
case .restricted:
|
|
248
|
+
return "restricted"
|
|
249
|
+
case .notDetermined:
|
|
250
|
+
return "not-determined"
|
|
251
|
+
@unknown default:
|
|
252
|
+
return "unsupported"
|
|
253
|
+
}
|
|
254
|
+
case "calendars":
|
|
255
|
+
return eventAuthorizationState(EKEventStore.authorizationStatus(for: .event))
|
|
256
|
+
case "reminders":
|
|
257
|
+
return eventAuthorizationState(EKEventStore.authorizationStatus(for: .reminder))
|
|
258
|
+
case "location":
|
|
259
|
+
switch CLLocationManager().authorizationStatus {
|
|
260
|
+
case .authorizedAlways, .authorizedWhenInUse:
|
|
261
|
+
return "granted"
|
|
262
|
+
case .denied:
|
|
263
|
+
return "denied"
|
|
264
|
+
case .restricted:
|
|
265
|
+
return "restricted"
|
|
266
|
+
case .notDetermined:
|
|
267
|
+
return "not-determined"
|
|
268
|
+
@unknown default:
|
|
269
|
+
return "unsupported"
|
|
270
|
+
}
|
|
271
|
+
default:
|
|
272
|
+
return nil
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
private static func authorizationState(_ status: AVAuthorizationStatus) -> String {
|
|
277
|
+
switch status {
|
|
278
|
+
case .authorized:
|
|
279
|
+
return "granted"
|
|
280
|
+
case .denied:
|
|
281
|
+
return "denied"
|
|
282
|
+
case .restricted:
|
|
283
|
+
return "restricted"
|
|
284
|
+
case .notDetermined:
|
|
285
|
+
return "not-determined"
|
|
286
|
+
@unknown default:
|
|
287
|
+
return "unsupported"
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
private static func eventAuthorizationState(_ status: EKAuthorizationStatus) -> String {
|
|
292
|
+
switch status {
|
|
293
|
+
case .fullAccess, .authorized:
|
|
294
|
+
return "granted"
|
|
295
|
+
case .writeOnly:
|
|
296
|
+
return "limited"
|
|
297
|
+
case .denied:
|
|
298
|
+
return "denied"
|
|
299
|
+
case .restricted:
|
|
300
|
+
return "restricted"
|
|
301
|
+
case .notDetermined:
|
|
302
|
+
return "not-determined"
|
|
303
|
+
@unknown default:
|
|
304
|
+
return "unsupported"
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
private static var isSupportedInstallLocation: Bool {
|
|
309
|
+
let applications = URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)
|
|
310
|
+
.appendingPathComponent("Applications", isDirectory: true).standardizedFileURL
|
|
311
|
+
return Bundle.main.bundleURL.standardizedFileURL.deletingLastPathComponent() == applications
|
|
312
|
+
}
|
|
313
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bleam",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "index.ts",
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@nativescript-community/sqlite": "^3.5.9",
|
|
7
|
+
"@nativescript/react-native": "9.0.0-preview.4",
|
|
8
|
+
"expo": "~57.0.2",
|
|
9
|
+
"react": "19.2.3",
|
|
10
|
+
"react-native": "0.86.0"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"verify": "../../node_modules/.bin/biome check .",
|
|
14
|
+
"verify:write": "../../node_modules/.bin/biome check --write .",
|
|
15
|
+
"format": "../../node_modules/.bin/biome format --write .",
|
|
16
|
+
"format:check": "../../node_modules/.bin/biome format .",
|
|
17
|
+
"lint": "../../node_modules/.bin/biome lint .",
|
|
18
|
+
"build:runtime": "xcodebuild -workspace ios/bleam.xcworkspace -scheme Bleam -configuration Debug -destination 'platform=macOS,arch=arm64,variant=Mac Catalyst' -derivedDataPath build ARCHS=arm64 build",
|
|
19
|
+
"start": "tsx scripts/start/index.ts",
|
|
20
|
+
"start:clean": "tsx scripts/start/index.ts --clean",
|
|
21
|
+
"typecheck": "tsc --noEmit"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "^25.5.0",
|
|
25
|
+
"tsx": "^4.21.0",
|
|
26
|
+
"typescript": "7.0.1-rc"
|
|
27
|
+
},
|
|
28
|
+
"expo": {
|
|
29
|
+
"autolinking": {
|
|
30
|
+
"nativeModulesDir": "modules"
|
|
31
|
+
},
|
|
32
|
+
"install": {
|
|
33
|
+
"exclude": [
|
|
34
|
+
"typescript"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"private": true
|
|
39
|
+
}
|