JavaScriptWorker.swift 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. //
  2. // JavaScriptWorker.swift
  3. // FreeAPS
  4. //
  5. // Created by Ivan Valkou on 29.01.2021.
  6. //
  7. import Foundation
  8. import JavaScriptCore
  9. final class JavaScriptWorker {
  10. private let processQueue = DispatchQueue(label: "DispatchQueue.JavaScriptWorker")
  11. private let virtualMachine: JSVirtualMachine
  12. private let context: JSContext
  13. init() {
  14. virtualMachine = processQueue.sync { JSVirtualMachine()! }
  15. context = JSContext(virtualMachine: virtualMachine)!
  16. context.exceptionHandler = { _, exception in
  17. if let error = exception?.toString() {
  18. print(error)
  19. }
  20. }
  21. context.setObject(require, forKeyedSubscript: "require" as NSString)
  22. }
  23. private lazy var require: @convention(block) (String) -> (JSValue?) = { path in
  24. switch path {
  25. case "../round-basal", "./round-basal":
  26. self.evaluate(script: Script(name: "oref0/lib/round-basal"))
  27. case "lodash/endsWith":
  28. self.evaluate(script: Script(name: "lodash"))
  29. default:
  30. return nil
  31. }
  32. return self.context.objectForKeyedSubscript("module")?.objectForKeyedSubscript("exports")
  33. }
  34. @discardableResult
  35. func evaluate(script: Script) -> JSValue! {
  36. context.evaluateScript(script.body)
  37. }
  38. @discardableResult
  39. func evaluate(string: String) -> JSValue! {
  40. context.evaluateScript(string)
  41. }
  42. subscript(key: String) -> JSValue! {
  43. context.objectForKeyedSubscript(key)
  44. }
  45. func json(for string: String) -> JSON {
  46. evaluate(string: "JSON.stringify(\(string));")!.toString()!
  47. }
  48. func call(function: String, with arguments: [JSON]) -> JSON {
  49. let joined = arguments.map(\.string).joined(separator: ",")
  50. return json(for: "\(function)(\(joined))")
  51. }
  52. func setEnviromentValue(_ value: JSON, forKey key: String) {
  53. evaluate(string: "freeaps.\(key) = \(value.string);")
  54. }
  55. var log: String {
  56. context.objectForKeyedSubscript("freeaps")!.objectForKeyedSubscript("log")!.toString()!
  57. }
  58. // func recursivePathsForResources(type: String, in directoryPath: String) -> [String] {
  59. // // Enumerators are recursive
  60. // let enumerator = FileManager.default.enumerator(atPath: directoryPath)
  61. // var filePaths: [String] = []
  62. //
  63. // while let filePath = enumerator?.nextObject() as? String {
  64. //
  65. // if URL(fileURLWithPath: filePath).pathExtension == type {
  66. // filePaths.append(directoryPath.byAppending(pathComponent: filePath))
  67. // }
  68. // }
  69. // return filePaths
  70. // }
  71. }