@iamevan/nobjc 0.0.1 → 0.0.3
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/build/Release/nobjc_native.node +0 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +30 -15
- package/package.json +5 -3
|
Binary file
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { LoadLibrary, GetClassObject, ObjcObject } from
|
|
1
|
+
import { LoadLibrary, GetClassObject, ObjcObject } from "./native.js";
|
|
2
|
+
const NATIVE_OBJC_OBJECT = Symbol("nativeObjcObject");
|
|
2
3
|
class NobjcLibrary {
|
|
3
4
|
constructor(library) {
|
|
4
5
|
const handler = {
|
|
@@ -9,56 +10,70 @@ class NobjcLibrary {
|
|
|
9
10
|
this.wasLoaded = true;
|
|
10
11
|
}
|
|
11
12
|
return new NobjcObject(GetClassObject(className));
|
|
12
|
-
}
|
|
13
|
+
},
|
|
13
14
|
};
|
|
14
15
|
return new Proxy({}, handler);
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
18
|
function NobjcMethodNameToObjcSelector(methodName) {
|
|
18
|
-
return methodName.replace(/\$/g,
|
|
19
|
+
return methodName.replace(/\$/g, ":");
|
|
19
20
|
}
|
|
20
21
|
// unused, might be useful for codegen later
|
|
21
22
|
function ObjcSelectorToNobjcMethodName(selector) {
|
|
22
|
-
return selector.replace(/:/g,
|
|
23
|
+
return selector.replace(/:/g, "$");
|
|
23
24
|
}
|
|
24
25
|
class NobjcObject {
|
|
25
26
|
constructor(object) {
|
|
26
27
|
const handler = {
|
|
27
28
|
has(target, p) {
|
|
28
|
-
//
|
|
29
|
-
if (
|
|
29
|
+
// Return true for the special Symbol to enable unwrapping
|
|
30
|
+
if (p === NATIVE_OBJC_OBJECT)
|
|
31
|
+
return true;
|
|
32
|
+
// guard against other symbols
|
|
33
|
+
if (typeof p === "symbol")
|
|
30
34
|
return Reflect.has(target, p);
|
|
31
35
|
// toString is always present
|
|
32
|
-
if (p ===
|
|
36
|
+
if (p === "toString")
|
|
33
37
|
return true;
|
|
34
38
|
// check if the object responds to the selector
|
|
35
|
-
return target.$msgSend(
|
|
39
|
+
return target.$msgSend("respondsToSelector:", NobjcMethodNameToObjcSelector(p.toString()));
|
|
36
40
|
},
|
|
37
|
-
get(
|
|
41
|
+
get(target, methodName, receiver) {
|
|
42
|
+
// Return the underlying native object when Symbol is accessed
|
|
43
|
+
if (methodName === NATIVE_OBJC_OBJECT) {
|
|
44
|
+
return target;
|
|
45
|
+
}
|
|
38
46
|
// guard against symbols
|
|
39
|
-
if (typeof methodName ===
|
|
47
|
+
if (typeof methodName === "symbol") {
|
|
40
48
|
return Reflect.get(object, methodName, receiver);
|
|
41
49
|
}
|
|
42
50
|
// handle toString separately
|
|
43
|
-
if (methodName ===
|
|
44
|
-
return () => String(object.$msgSend(
|
|
51
|
+
if (methodName === "toString") {
|
|
52
|
+
return () => String(object.$msgSend("description"));
|
|
45
53
|
}
|
|
46
54
|
if (!(methodName in receiver)) {
|
|
47
55
|
throw new Error(`Method ${methodName} not found on object ${receiver}`);
|
|
48
56
|
}
|
|
49
57
|
return new NobjcMethod(object, methodName);
|
|
50
|
-
}
|
|
58
|
+
},
|
|
51
59
|
};
|
|
52
60
|
return new Proxy(object, handler);
|
|
53
61
|
}
|
|
54
62
|
}
|
|
63
|
+
function unwrapArg(arg) {
|
|
64
|
+
if (arg && typeof arg === "object" && NATIVE_OBJC_OBJECT in arg) {
|
|
65
|
+
return arg[NATIVE_OBJC_OBJECT];
|
|
66
|
+
}
|
|
67
|
+
return arg;
|
|
68
|
+
}
|
|
55
69
|
class NobjcMethod {
|
|
56
70
|
constructor(object, methodName) {
|
|
57
71
|
const selector = NobjcMethodNameToObjcSelector(methodName);
|
|
58
72
|
// This cannot be an arrow function because we need to access `arguments`.
|
|
59
73
|
function methodFunc() {
|
|
60
|
-
const
|
|
61
|
-
|
|
74
|
+
const unwrappedArgs = Array.from(arguments).map(unwrapArg);
|
|
75
|
+
const result = object.$msgSend(selector, ...unwrappedArgs);
|
|
76
|
+
if (typeof result == "object" && result instanceof ObjcObject) {
|
|
62
77
|
return new NobjcObject(result);
|
|
63
78
|
}
|
|
64
79
|
return result;
|
package/package.json
CHANGED
|
@@ -32,11 +32,13 @@
|
|
|
32
32
|
"pretest": "npm run build",
|
|
33
33
|
"test-native": "node ./scripts/test-native-code.js",
|
|
34
34
|
"test-js": "node ./scripts/test-js-code.js",
|
|
35
|
-
"test": "
|
|
35
|
+
"test-string-lifetime": "node ./scripts/test-string-lifetime.js",
|
|
36
|
+
"test-object-arguments": "node ./scripts/test-object-arguments.js",
|
|
37
|
+
"test": "npm run test-native && npm run test-js && npm run test-string-lifetime && npm run test-object-arguments",
|
|
36
38
|
"make-clangd-config": "node ./scripts/make-clangd-config.js",
|
|
37
|
-
"preinstall": "npm run build-scripts && npm run make-clangd-config"
|
|
39
|
+
"preinstall-disabled": "npm run build-scripts && npm run make-clangd-config"
|
|
38
40
|
},
|
|
39
|
-
"version": "0.0.
|
|
41
|
+
"version": "0.0.3",
|
|
40
42
|
"description": "Objective-C bridge for Node.js",
|
|
41
43
|
"main": "dist/index.js",
|
|
42
44
|
"devDependencies": {
|