jsutils.nim 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. when defined(js):
  2. import std/jsbigints
  3. type
  4. ArrayBuffer* = ref object of JsRoot
  5. Float64Array* = ref object of JsRoot
  6. Uint32Array* = ref object of JsRoot
  7. Uint8Array* = ref object of JsRoot
  8. BigUint64Array* = ref object of JsRoot
  9. func newArrayBuffer*(n: int): ArrayBuffer {.importjs: "new ArrayBuffer(#)".}
  10. func newFloat64Array*(buffer: ArrayBuffer): Float64Array {.importjs: "new Float64Array(#)".}
  11. func newUint32Array*(buffer: ArrayBuffer): Uint32Array {.importjs: "new Uint32Array(#)".}
  12. func newBigUint64Array*(buffer: ArrayBuffer): BigUint64Array {.importjs: "new BigUint64Array(#)".}
  13. func newUint8Array*(n: int): Uint8Array {.importjs: "new Uint8Array(#)".}
  14. func `[]`*(arr: Uint32Array, i: int): uint32 {.importjs: "#[#]".}
  15. func `[]`*(arr: Uint8Array, i: int): uint8 {.importjs: "#[#]".}
  16. func `[]`*(arr: BigUint64Array, i: int): JsBigInt {.importjs: "#[#]".}
  17. func `[]=`*(arr: Float64Array, i: int, v: float) {.importjs: "#[#] = #".}
  18. proc jsTypeOf*[T](x: T): cstring {.importjs: "typeof(#)".} =
  19. ## Returns the name of the JsObject's JavaScript type as a cstring.
  20. # xxx replace jsffi.jsTypeOf with this definition and add tests
  21. runnableExamples:
  22. import std/[jsffi, jsbigints]
  23. assert jsTypeOf(1.toJs) == "number"
  24. assert jsTypeOf(false.toJs) == "boolean"
  25. assert [1].toJs.jsTypeOf == "object" # note the difference with `getProtoName`
  26. assert big"1".toJs.jsTypeOf == "bigint"
  27. proc jsConstructorName*[T](a: T): cstring =
  28. runnableExamples:
  29. import std/jsffi
  30. let a = array[2, float64].default
  31. assert jsConstructorName(a) == "Float64Array"
  32. assert jsConstructorName(a.toJs) == "Float64Array"
  33. {.emit: """`result` = `a`.constructor.name;""".}
  34. proc hasJsBigInt*(): bool =
  35. {.emit: """`result` = typeof BigInt != 'undefined';""".}
  36. proc hasBigUint64Array*(): bool =
  37. {.emit: """`result` = typeof BigUint64Array != 'undefined';""".}
  38. proc getProtoName*[T](a: T): cstring {.importjs: "Object.prototype.toString.call(#)".} =
  39. runnableExamples:
  40. import std/[jsffi, jsbigints]
  41. type A = ref object
  42. assert 1.toJs.getProtoName == "[object Number]"
  43. assert "a".toJs.getProtoName == "[object String]"
  44. assert big"1".toJs.getProtoName == "[object BigInt]"
  45. assert false.toJs.getProtoName == "[object Boolean]"
  46. assert (a: 1).toJs.getProtoName == "[object Object]"
  47. assert A.default.toJs.getProtoName == "[object Null]"
  48. assert [1].toJs.getProtoName == "[object Int32Array]" # implementation defined
  49. assert @[1].toJs.getProtoName == "[object Array]" # ditto
  50. const maxSafeInteger* = 9007199254740991
  51. ## The same as `Number.MAX_SAFE_INTEGER` or `2^53 - 1`.
  52. ## See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
  53. runnableExamples:
  54. let a {.importjs: "Number.MAX_SAFE_INTEGER".}: int64
  55. assert a == maxSafeInteger
  56. proc isInteger*[T](x: T): bool {.importjs: "Number.isInteger(#)".} =
  57. runnableExamples:
  58. import std/jsffi
  59. assert 1.isInteger
  60. assert not 1.5.isInteger
  61. assert 1.toJs.isInteger
  62. assert not 1.5.toJs.isInteger
  63. proc isSafeInteger*[T](x: T): bool {.importjs: "Number.isSafeInteger(#)".} =
  64. runnableExamples:
  65. import std/jsffi
  66. assert not "123".toJs.isSafeInteger
  67. assert 123.isSafeInteger
  68. assert 123.toJs.isSafeInteger
  69. when false:
  70. assert 9007199254740991.toJs.isSafeInteger
  71. assert not 9007199254740992.toJs.isSafeInteger
  72. template whenJsNoBigInt64*(no64, yes64): untyped =
  73. when defined(js):
  74. when compiles(compileOption("jsbigint64")):
  75. when compileOption("jsbigint64"):
  76. yes64
  77. else:
  78. no64
  79. else:
  80. no64
  81. else:
  82. no64