boot-nemonic-printer 0.1.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.
Files changed (84) hide show
  1. package/.eslintrc.js +5 -0
  2. package/README.md +209 -0
  3. package/ai/example-ui-card-refactor.md +348 -0
  4. package/android/build.gradle +22 -0
  5. package/android/libs/NemonicSdk.aar +0 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/java/net/eventboot/nemonicprinter/BootNemonicPrinterModule.kt +509 -0
  8. package/build/BootNemonicPrinter.types.d.ts +44 -0
  9. package/build/BootNemonicPrinter.types.d.ts.map +1 -0
  10. package/build/BootNemonicPrinter.types.js +2 -0
  11. package/build/BootNemonicPrinter.types.js.map +1 -0
  12. package/build/BootNemonicPrinterModule.d.ts +36 -0
  13. package/build/BootNemonicPrinterModule.d.ts.map +1 -0
  14. package/build/BootNemonicPrinterModule.js +3 -0
  15. package/build/BootNemonicPrinterModule.js.map +1 -0
  16. package/build/constants/NBatteryStatus.d.ts +8 -0
  17. package/build/constants/NBatteryStatus.d.ts.map +1 -0
  18. package/build/constants/NBatteryStatus.js +7 -0
  19. package/build/constants/NBatteryStatus.js.map +1 -0
  20. package/build/constants/NCartridgeType.d.ts +35 -0
  21. package/build/constants/NCartridgeType.d.ts.map +1 -0
  22. package/build/constants/NCartridgeType.js +183 -0
  23. package/build/constants/NCartridgeType.js.map +1 -0
  24. package/build/constants/NConnectState.d.ts +8 -0
  25. package/build/constants/NConnectState.d.ts.map +1 -0
  26. package/build/constants/NConnectState.js +7 -0
  27. package/build/constants/NConnectState.js.map +1 -0
  28. package/build/constants/NPowerSaveMode.d.ts +6 -0
  29. package/build/constants/NPowerSaveMode.d.ts.map +1 -0
  30. package/build/constants/NPowerSaveMode.js +5 -0
  31. package/build/constants/NPowerSaveMode.js.map +1 -0
  32. package/build/constants/NPrintImageLength.d.ts +12 -0
  33. package/build/constants/NPrintImageLength.d.ts.map +1 -0
  34. package/build/constants/NPrintImageLength.js +12 -0
  35. package/build/constants/NPrintImageLength.js.map +1 -0
  36. package/build/constants/NPrintQuality.d.ts +7 -0
  37. package/build/constants/NPrintQuality.d.ts.map +1 -0
  38. package/build/constants/NPrintQuality.js +6 -0
  39. package/build/constants/NPrintQuality.js.map +1 -0
  40. package/build/constants/NPrinterStatus.d.ts +9 -0
  41. package/build/constants/NPrinterStatus.d.ts.map +1 -0
  42. package/build/constants/NPrinterStatus.js +8 -0
  43. package/build/constants/NPrinterStatus.js.map +1 -0
  44. package/build/constants/NPrinterType.d.ts +9 -0
  45. package/build/constants/NPrinterType.d.ts.map +1 -0
  46. package/build/constants/NPrinterType.js +8 -0
  47. package/build/constants/NPrinterType.js.map +1 -0
  48. package/build/constants/NResult.d.ts +51 -0
  49. package/build/constants/NResult.d.ts.map +1 -0
  50. package/build/constants/NResult.js +50 -0
  51. package/build/constants/NResult.js.map +1 -0
  52. package/build/index.d.ts +13 -0
  53. package/build/index.d.ts.map +1 -0
  54. package/build/index.js +13 -0
  55. package/build/index.js.map +1 -0
  56. package/expo-module.config.json +9 -0
  57. package/ios/BootNemonicPrinter.podspec +31 -0
  58. package/ios/BootNemonicPrinterModule.swift +257 -0
  59. package/ios/Frameworks/NemonicSdk.framework/Headers/NemonicSdk-Swift.h +797 -0
  60. package/ios/Frameworks/NemonicSdk.framework/Headers/NemonicSdk.h +18 -0
  61. package/ios/Frameworks/NemonicSdk.framework/Info.plist +0 -0
  62. package/ios/Frameworks/NemonicSdk.framework/Modules/NemonicSdk.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo +0 -0
  63. package/ios/Frameworks/NemonicSdk.framework/Modules/NemonicSdk.swiftmodule/arm64-apple-ios.abi.json +12244 -0
  64. package/ios/Frameworks/NemonicSdk.framework/Modules/NemonicSdk.swiftmodule/arm64-apple-ios.private.swiftinterface +356 -0
  65. package/ios/Frameworks/NemonicSdk.framework/Modules/NemonicSdk.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  66. package/ios/Frameworks/NemonicSdk.framework/Modules/NemonicSdk.swiftmodule/arm64-apple-ios.swiftinterface +356 -0
  67. package/ios/Frameworks/NemonicSdk.framework/Modules/NemonicSdk.swiftmodule/arm64-apple-ios.swiftmodule +0 -0
  68. package/ios/Frameworks/NemonicSdk.framework/Modules/module.modulemap +11 -0
  69. package/ios/Frameworks/NemonicSdk.framework/NemonicSdk +0 -0
  70. package/ios/Frameworks/NemonicSdk.framework/_CodeSignature/CodeResources +237 -0
  71. package/package.json +44 -0
  72. package/src/BootNemonicPrinter.types.ts +50 -0
  73. package/src/BootNemonicPrinterModule.ts +48 -0
  74. package/src/constants/NBatteryStatus.ts +8 -0
  75. package/src/constants/NCartridgeType.ts +181 -0
  76. package/src/constants/NConnectState.ts +8 -0
  77. package/src/constants/NPowerSaveMode.ts +6 -0
  78. package/src/constants/NPrintImageLength.ts +11 -0
  79. package/src/constants/NPrintQuality.ts +7 -0
  80. package/src/constants/NPrinterStatus.ts +9 -0
  81. package/src/constants/NPrinterType.ts +9 -0
  82. package/src/constants/NResult.ts +51 -0
  83. package/src/index.ts +13 -0
  84. package/tsconfig.json +9 -0
@@ -0,0 +1,257 @@
1
+ import ExpoModulesCore
2
+ import NemonicSdk
3
+ import UIKit
4
+
5
+ private let MAX_IMAGE_SIZE = 196_603
6
+ private let EXCEED_MAX_SIZE = -900
7
+ private let PRINT_TAG = "NemonicPrintTimer"
8
+
9
+ public class BootNemonicPrinterModule: Module {
10
+ private var printerController: NPrinterController!
11
+ private var scanController: NPrinterScanController!
12
+ private var connectedPrinter: NPrinter?
13
+ fileprivate var printStartedAt: Date?
14
+ fileprivate var printSeq: Int = 0
15
+
16
+ public func definition() -> ModuleDefinition {
17
+ Name("BootNemonicPrinter")
18
+
19
+ Constant("MAX_IMAGE_SIZE") { MAX_IMAGE_SIZE }
20
+ Constant("SDK_VERSION") { "1.1.0" }
21
+
22
+ Events("onDeviceFound", "onDisconnected", "onPrintProgress", "onPrintComplete", "onNativeLog")
23
+
24
+ OnCreate {
25
+ let delegate = BootNemonicPrinterDelegate(owner: self)
26
+ self.delegateRef = delegate
27
+ self.printerController = NPrinterController(delegate)
28
+ self.scanController = NPrinterScanController(delegate)
29
+ }
30
+
31
+ // === BLE 스캔
32
+ AsyncFunction("startScan") { () -> Int in
33
+ return self.scanController.startScan()
34
+ }
35
+ Function("stopScan") {
36
+ self.scanController.stopScan()
37
+ }
38
+
39
+ // === USB — iOS 미지원
40
+ AsyncFunction("getUsbPrinterList") { () -> [[String: Any]] in [] }
41
+ AsyncFunction("requestUsbPermission") { (_: [String: Any]) -> Bool in false }
42
+
43
+ // === 연결 라이프사이클
44
+ AsyncFunction("connect") { (params: [String: Any]) -> Int in
45
+ let name = params["name"] as? String ?? ""
46
+ let macAddress = params["macAddress"] as? String ?? ""
47
+ let typeRaw = params["type"] as? Int ?? 0
48
+ let queueLabel = params["queueLabel"] as? String
49
+
50
+ let printer = NPrinter()
51
+ printer.setName(name)
52
+ _ = printer.setMacAddress(macAddress)
53
+ printer.setType(NPrinterType(rawValue: typeRaw) ?? .none)
54
+
55
+ let result = self.printerController.connect(printer, queueLabel: queueLabel)
56
+ if result == NemonicSdk.NResult.ok.rawValue {
57
+ self.connectedPrinter = printer
58
+ }
59
+ return result
60
+ }
61
+ Function("disconnect") {
62
+ self.printerController.disconnect()
63
+ self.connectedPrinter = nil
64
+ }
65
+ AsyncFunction("getConnectState") { () -> Int in
66
+ return self.printerController.getConnectState()
67
+ }
68
+ Function("cancel") {
69
+ self.printerController.cancel()
70
+ }
71
+
72
+ // === 인쇄
73
+ Function("setPrintTimeout") { (enableAuto: Bool, manualTime: Int) in
74
+ self.printerController.setPrintTimeout(enableAuto, manualTime)
75
+ }
76
+ AsyncFunction("print") { (params: [String: Any]) -> Int in
77
+ let imageData = params["images"] as? [[Int]] ?? []
78
+ let imageUrls = params["imageUrls"] as? [String] ?? []
79
+
80
+ for img in imageData where img.count > MAX_IMAGE_SIZE {
81
+ return EXCEED_MAX_SIZE
82
+ }
83
+ guard let printer = self.connectedPrinter else {
84
+ return -301 // NOT_CONNECTED
85
+ }
86
+
87
+ self.printSeq += 1
88
+ let seq = self.printSeq
89
+ let t0 = Date()
90
+ let elapsedMs: (Date) -> Int = { Int($0.timeIntervalSince(t0) * 1000) }
91
+ NSLog("[\(PRINT_TAG)] #\(seq) T+0ms ▶ print() entered (images=\(imageData.count), urls=\(imageUrls.count))")
92
+
93
+ let images = self.decodeImages(imageData: imageData, imageUrls: imageUrls)
94
+ let tDecoded = Date()
95
+ let firstSize = images.first.map { "\(Int($0.size.width))x\(Int($0.size.height))" } ?? "-"
96
+ NSLog("[\(PRINT_TAG)] #\(seq) T+\(elapsedMs(tDecoded))ms images decoded (count=\(images.count), size=\(firstSize))")
97
+
98
+ guard !images.isEmpty else {
99
+ return -501 // INVALID_PARAMETER
100
+ }
101
+
102
+ let qualityRaw = params["quality"] as? Int ?? 0
103
+ let copiesN = params["copies"] as? Int ?? 1
104
+ let cut = params["isLastPageCut"] as? Bool ?? true
105
+ let dither = params["enableDither"] as? Bool ?? true
106
+ let checkStatus = params["isCheckPrinterStatus"] as? Bool ?? true
107
+ let checkCart = params["isCheckCartridgeType"] as? Bool ?? true
108
+ let checkPower = params["isCheckPower"] as? Bool ?? true
109
+
110
+ let info = NPrintInfo(printer: printer, images: images)
111
+ _ = info
112
+ .setPrintQuality(NPrintQuality(rawValue: qualityRaw) ?? .lowFast)
113
+ .setCopies(copiesN)
114
+ .setEnableLastPageCut(cut)
115
+ .setEnableDither(dither)
116
+ .setEnableCheckPrinterStatus(checkStatus)
117
+ .setEnableCheckCartridgeType(checkCart)
118
+ .setEnableCheckPower(checkPower)
119
+
120
+ let tBeforeSdk = Date()
121
+ NSLog("[\(PRINT_TAG)] #\(seq) T+\(elapsedMs(tBeforeSdk))ms ▶ printerController.print() called (quality=\(qualityRaw), copies=\(copiesN), dither=\(dither), cut=\(cut), checkStatus=\(checkStatus), checkCart=\(checkCart), checkPower=\(checkPower))")
122
+ self.printStartedAt = tBeforeSdk
123
+
124
+ let result = self.printerController.print(info)
125
+
126
+ let tAfterSdk = Date()
127
+ let sdkMs = Int(tAfterSdk.timeIntervalSince(tBeforeSdk) * 1000)
128
+ NSLog("[\(PRINT_TAG)] #\(seq) T+\(elapsedMs(tAfterSdk))ms ◀ printerController.print() returned (result=\(result), sdkCall=\(sdkMs)ms)")
129
+ return result
130
+ }
131
+
132
+ // === 템플릿
133
+ AsyncFunction("setTemplate") { (image: [Int], withPrint: Bool, enableDither: Bool) -> Int in
134
+ if image.count > MAX_IMAGE_SIZE { return EXCEED_MAX_SIZE }
135
+ let bytes = image.map { UInt8($0 & 0xff) }
136
+ let data = Data(bytes)
137
+ guard let uiImage = UIImage(data: data) else { return -501 }
138
+ return self.printerController.setTemplate(uiImage, withPrint: withPrint, enableDither: enableDither)
139
+ }
140
+ AsyncFunction("setTemplateWithUrl") { (imageUrl: String, withPrint: Bool, enableDither: Bool) -> Int in
141
+ guard let url = URL(string: imageUrl),
142
+ let data = try? Data(contentsOf: url),
143
+ let uiImage = UIImage(data: data) else { return -501 }
144
+ return self.printerController.setTemplate(uiImage, withPrint: withPrint, enableDither: enableDither)
145
+ }
146
+ AsyncFunction("clearTemplate") { () -> Int in
147
+ return self.printerController.clearTemplate()
148
+ }
149
+
150
+ // === 상태
151
+ AsyncFunction("getPrinterStatus") { () -> Int in self.printerController.getPrinterStatus() }
152
+ AsyncFunction("getCartridgeType") { () -> Int in self.printerController.getCartridgeType() }
153
+ AsyncFunction("getPrinterName") { () -> [String: Any] in
154
+ let r = self.printerController.getPrinterName()
155
+ return ["result": r.getResult(), "value": r.getValue()]
156
+ }
157
+ AsyncFunction("getBatteryLevel") { () -> Int in self.printerController.getBatteryLevel() }
158
+ AsyncFunction("getBatteryStatus") { () -> Int in self.printerController.getBatteryStatus() }
159
+
160
+ // === Android BLE 딜레이 stub
161
+ AsyncFunction("getBleConnectDelayOffset") { () -> Int in 0 }
162
+ Function("setBleConnectDelayOffset") { (_: Int) in }
163
+ AsyncFunction("getBleSendRetryDelayOffset") { () -> Int in 0 }
164
+ Function("setBleSendRetryDelayOffset") { (_: Int) in }
165
+
166
+ // === iOS connect delay
167
+ AsyncFunction("getDefaultConnectDelay") { () -> Int in
168
+ return Int(self.printerController.getDefaultConnectDelay())
169
+ }
170
+ AsyncFunction("getConnectDelay") { () -> Int in
171
+ return Int(self.printerController.getConnectDelay())
172
+ }
173
+ Function("setConnectDelay") { (msec: Int) in
174
+ self.printerController.setConnectDelay(UInt32(msec))
175
+ }
176
+ }
177
+
178
+ private var delegateRef: BootNemonicPrinterDelegate?
179
+
180
+ fileprivate func emitDisconnected() {
181
+ sendEvent("onDisconnected", [:])
182
+ }
183
+ fileprivate func emitPrintProgress(index: Int, total: Int, result: Int) {
184
+ let elapsed = printStartedAt.map { Int(Date().timeIntervalSince($0) * 1000) } ?? -1
185
+ NSLog("[\(PRINT_TAG)] #\(printSeq) T+\(elapsed)ms · printProgress index=\(index)/\(total) result=\(result)")
186
+ sendEvent("onPrintProgress", ["index": index, "total": total, "result": result])
187
+ }
188
+ fileprivate func emitPrintComplete(result: Int) {
189
+ let elapsed = printStartedAt.map { Int(Date().timeIntervalSince($0) * 1000) } ?? -1
190
+ NSLog("[\(PRINT_TAG)] #\(printSeq) T+\(elapsed)ms ✓ printComplete result=\(result)")
191
+ sendEvent("onPrintComplete", ["result": result])
192
+ }
193
+ fileprivate func emitDeviceFound(_ printer: NPrinter) {
194
+ let type = printer.getType()
195
+ sendEvent("onDeviceFound", [
196
+ "name": printer.getName(),
197
+ "macAddress": printer.getMacAddress(),
198
+ "type": type.rawValue,
199
+ "typeName": printerTypeName(type),
200
+ "transport": "bluetooth",
201
+ ])
202
+ }
203
+
204
+ // SDK 의 NPrinterType 은 Obj-C NS_ENUM 으로 노출돼 String(describing:) 결과가
205
+ // "NPrinterType(rawValue: N)" 으로 나옴. Android SDK 의 enum.toString() 이 반환하는
206
+ // 사람 친화적 표시명 ("Nemonic AI" 등) 과 맞추기 위해 명시적으로 매핑.
207
+ // (표시명 출처: NemonicSdk-Swift.h 의 NPrinterType doc-comment.)
208
+ private func printerTypeName(_ type: NPrinterType) -> String {
209
+ switch type {
210
+ case .none: return "None"
211
+ case .nemonic: return "Nemonic"
212
+ case .nemonicLabel: return "Nemonic Label"
213
+ case .nemonicMini: return "Nemonic mini"
214
+ case .nemonicMip201: return "Nemonic AI"
215
+ @unknown default: return "Unknown(\(type.rawValue))"
216
+ }
217
+ }
218
+
219
+ private func decodeImages(imageData: [[Int]], imageUrls: [String]) -> [UIImage] {
220
+ var result: [UIImage] = []
221
+ if !imageData.isEmpty {
222
+ for arr in imageData {
223
+ let bytes = arr.map { UInt8($0 & 0xff) }
224
+ let data = Data(bytes)
225
+ if let image = UIImage(data: data) {
226
+ result.append(image)
227
+ }
228
+ }
229
+ } else {
230
+ for urlString in imageUrls {
231
+ guard let url = URL(string: urlString),
232
+ let data = try? Data(contentsOf: url),
233
+ let image = UIImage(data: data) else { continue }
234
+ result.append(image)
235
+ }
236
+ }
237
+ return result
238
+ }
239
+ }
240
+
241
+ private class BootNemonicPrinterDelegate: NSObject, NPrinterControllerDelegate, NPrinterScanControllerDelegate {
242
+ weak var owner: BootNemonicPrinterModule?
243
+ init(owner: BootNemonicPrinterModule) { self.owner = owner }
244
+
245
+ func disconnected() {
246
+ owner?.emitDisconnected()
247
+ }
248
+ func printProgress(index: Int, total: Int, result: Int) {
249
+ owner?.emitPrintProgress(index: index, total: total, result: result)
250
+ }
251
+ func printComplete(result: Int) {
252
+ owner?.emitPrintComplete(result: result)
253
+ }
254
+ func deviceFound(_ printer: NPrinter) {
255
+ owner?.emitDeviceFound(printer)
256
+ }
257
+ }