java-bridge 2.2.3-beta.2 → 2.2.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/dist/native.d.ts CHANGED
@@ -3,6 +3,16 @@
3
3
 
4
4
  /* auto-generated by NAPI-RS */
5
5
 
6
+ /** Options for the interface proxies */
7
+ export interface InterfaceProxyOptions {
8
+ /**
9
+ * If true, the proxy will be kept as a daemon
10
+ * proxy after the interface has been destroyed
11
+ */
12
+ keepAsDaemon?: boolean
13
+ }
14
+ /** Clears the list of daemon proxies. */
15
+ export function clearDaemonProxies(): void
6
16
  /**
7
17
  * Options for the Java VM.
8
18
  * Not the same as vm arguments.
@@ -22,6 +32,10 @@ export interface JavaOptions {
22
32
  * Throws an error if the library could not be found.
23
33
  */
24
34
  export function getJavaLibPath(): string
35
+ export class JavaInterfaceProxy {
36
+ get proxy(): object | null
37
+ reset(force?: boolean | undefined | null): void
38
+ }
25
39
  /**
26
40
  * The main java class.
27
41
  * This should only be created once per process.
@@ -63,15 +77,15 @@ export class Java {
63
77
  appendClasspath(classpath: string | string[]): void
64
78
  /** Set the stdout/stderr callbacks */
65
79
  setStdoutCallbacks(stdoutCallback?: ((err: Error | null, data?: string) => void) | undefined | null, stderrCallback?: ((err: Error | null, data?: string) => void) | undefined | null): StdoutRedirect
66
- createInterfaceProxy(classname: string, methods: Record<string, (err: null | Error, callback: (err: Error | null, data?: any | null) => void, ...args: any[]) => void>): JavaInterfaceProxy
80
+ createInterfaceProxy(classname: string, methods: Record<string, (err: null | Error, callback: (err: Error | null, data?: any | null) => void, ...args: any[]) => void>, options?: InterfaceProxyOptions | undefined | null): JavaInterfaceProxy
67
81
  /** Check if `this` is instance of `other` */
68
82
  isInstanceOf(thisObj: object, other: string | object): boolean
69
83
  get classLoader(): object
70
84
  set classLoader(classLoader: object)
71
85
  }
72
- export class JavaInterfaceProxy {
73
- get proxy(): object
74
- reset(): void
86
+ export class JavaConfig {
87
+ static setRunEventLoopWhenInterfaceProxyIsActive(value: boolean): void
88
+ static getRunEventLoopWhenInterfaceProxyIsActive(): boolean
75
89
  }
76
90
  export class StdoutRedirect {
77
91
  on(event: string, callback?: ((...args: any[]) => any) | null): void
@@ -2,6 +2,7 @@ export interface MethodDeclaration {
2
2
  returnType: string;
3
3
  parameters: string[];
4
4
  isStatic: boolean;
5
+ isDefault: boolean;
5
6
  }
6
7
  /**
7
8
  * A java class declaration converted to typescript
@@ -41,8 +42,11 @@ export default class TypescriptDefinitionGenerator {
41
42
  private readonly progressCallback;
42
43
  private readonly resolvedImports;
43
44
  private usesBasicOrJavaType;
45
+ private usesNewProxy;
46
+ private usesInterfaceProxy;
44
47
  private readonly additionalImports;
45
48
  private readonly importsToResolve;
49
+ private readonly interfaceImports;
46
50
  /**
47
51
  * Create a new `TypescriptDefinitionGenerator` instance
48
52
  *
@@ -64,6 +68,9 @@ export default class TypescriptDefinitionGenerator {
64
68
  private convertParameter;
65
69
  private convertParameters;
66
70
  private static createMethodComment;
71
+ private createMethodSignature;
72
+ private createInterfaceMethodSignatures;
73
+ private createNewProxyMethod;
67
74
  private createMethod;
68
75
  private convertMethod;
69
76
  private getAdditionalImports;
@@ -9,7 +9,7 @@ export type { internal };
9
9
  export * from './java';
10
10
  import * as java from './java';
11
11
  export default java;
12
- export { getJavaLibPath } from '../native';
12
+ export { getJavaLibPath, InterfaceProxyOptions } from '../native';
13
13
  export { getJavaVersion, getJavaVersionSync } from './util';
14
14
  import TypescriptDefinitionGenerator from './TypescriptDefinitionGenerator';
15
15
  export { TypescriptDefinitionGenerator };
@@ -1,5 +1,6 @@
1
- import { Java, JavaOptions } from '../native';
1
+ import { InterfaceProxyOptions, Java, JavaOptions } from '../native';
2
2
  import { JavaClass, JavaClassConstructorType, JavaVersion, UnknownJavaClass, UnknownJavaClassType } from './definitions';
3
+ export { clearDaemonProxies } from '../native';
3
4
  /**
4
5
  * Options for creating the Java VM.
5
6
  */
@@ -433,7 +434,12 @@ export declare namespace stdout {
433
434
  * ## See also
434
435
  * * {@link newProxy}
435
436
  */
436
- export interface JavaInterfaceProxy {
437
+ export interface JavaInterfaceProxy<T extends ProxyRecord<T> = AnyProxyRecord> {
438
+ /**
439
+ * A dummy property to make sure the type is correct.
440
+ * This property will never be set.
441
+ */
442
+ _dummy?: T;
437
443
  /**
438
444
  * Destroy the proxy class.
439
445
  * After this call any call to any method defined by the
@@ -442,8 +448,11 @@ export interface JavaInterfaceProxy {
442
448
  * specifically implementing methods that will be called
443
449
  * from another (java) thread.
444
450
  * Throws an error if the proxy has already been destroyed.
451
+ *
452
+ * @param force whether to force the destruction of the proxy
453
+ * if it should be kept alive as a daemon
445
454
  */
446
- reset(): void;
455
+ reset(force?: boolean): void;
447
456
  }
448
457
  /**
449
458
  * An interface proxy method.
@@ -454,6 +463,8 @@ export interface JavaInterfaceProxy {
454
463
  * @return the value to pass back to the java process
455
464
  */
456
465
  export type ProxyMethod = (...args: any[]) => any;
466
+ export type ProxyRecord<T> = Partial<Record<keyof T, ProxyMethod>>;
467
+ export type AnyProxyRecord = Record<string, ProxyMethod>;
457
468
  /**
458
469
  * Create a new java interface proxy.
459
470
  * This allows you to implement java interfaces in javascript.
@@ -551,16 +562,92 @@ export type ProxyMethod = (...args: any[]) => any;
551
562
  * an exception will be thrown in the java process.
552
563
  * * Any errors thrown in the javascript process will be rethrown in the java process.
553
564
  *
565
+ * ### Possible deadlock warning
566
+ * When calling a java method that uses an interface defined by this, you must call
567
+ * that method using the interface asynchronously as Node.js is single threaded
568
+ * and can't wait for the java method to return while calling the proxy method at the
569
+ * same time.
570
+ *
571
+ * If you still want to call everything in a synchronous manner, make sure to enable
572
+ * running the event loop while waiting for a java method to return by setting
573
+ * {@link config.runEventLoopWhenInterfaceProxyIsActive} to true.
574
+ * **This may cause application crashes, so it is strongly recommended to just use async methods.**
575
+ *
576
+ * ### Keeping the proxy alive
577
+ * If you want to keep the proxy alive, you must keep this instance in scope.
578
+ * If that is not an option for you, you can manually keep the proxy alive
579
+ * by setting the {@link InterfaceProxyOptions}.keepAsDaemon option to true.
580
+ *
581
+ * ```ts
582
+ * const proxy = newProxy('java.lang.Runnable', {
583
+ * run: (): void => {
584
+ * console.log('Hello World!');
585
+ * }
586
+ * }, {
587
+ * keepAsDaemon: true
588
+ * });
589
+ *
590
+ * const TimeUnit = java.importClass('java.util.concurrent.TimeUnit');
591
+ * const ScheduledThreadPoolExecutor = java.importClass(
592
+ * 'java.util.concurrent.ScheduledThreadPoolExecutor'
593
+ * );
594
+ * const executor = new ScheduledThreadPoolExecutor(1);
595
+ *
596
+ * // 'proxy' will eventually be garbage collected,
597
+ * // but it will be kept alive due to this option.
598
+ * executor.scheduleAtFixedRateSync(proxy, 0, 1, TimeUnit.SECONDS);
599
+ * ```
600
+ *
601
+ * This will keep the proxy alive internally, thus the instance can be moved
602
+ * out of scope. However, this will also keep the JVM alive, so you should
603
+ * only use this if you are sure that you want to keep the JVM alive.
604
+ *
605
+ * If you want to destroy the proxy, you must call {@link clearDaemonProxies}.
606
+ * This will destroy all proxies which are kept alive by this option.
607
+ * Calling {@link JavaInterfaceProxy.reset} will not destroy a proxy
608
+ * kept alive by this option unless the force option is set to true.
609
+ *
554
610
  * ## See also
555
611
  * * {@link JavaInterfaceProxy}
612
+ * * {@link InterfaceProxyOptions}
556
613
  *
557
614
  * @param interfaceName the name of the java interface to implement
558
615
  * @param methods the methods to implement.
616
+ * @param opts the options to use
559
617
  * @returns a proxy class to pass back to the java process
560
618
  */
561
- export declare function newProxy(interfaceName: string, methods: Record<string, ProxyMethod>): JavaInterfaceProxy;
619
+ export declare function newProxy<T extends ProxyRecord<T> = AnyProxyRecord>(interfaceName: string, methods: T, opts?: InterfaceProxyOptions): JavaInterfaceProxy<T>;
562
620
  /**
563
621
  * Get the static java instance.
564
622
  * This has no real use, all important methods are exported explicitly.
565
623
  */
566
624
  export declare function getJavaInstance(): Java | null;
625
+ /**
626
+ * Configuration options for the java bridge.
627
+ */
628
+ export declare class config {
629
+ /**
630
+ * **Experimental Feature**
631
+ *
632
+ * Set whether to run the event loop when an interface proxy is active.
633
+ * This is disabled by default. Enabling this will cause the bridge
634
+ * to run the event loop when an interface proxy either as direct
635
+ * proxy or as daemon proxy is active. This is only required if the
636
+ * proxied method calls back into the javascript process in the same thread.
637
+ * If the proxy is used either in an async method or in a different thread,
638
+ * this is not required.
639
+ *
640
+ * **Note:** Enabling this may cause the application to crash. Use with caution.
641
+ *
642
+ * @experimental
643
+ * @param value whether to run the event loop when an interface proxy is active
644
+ */
645
+ static set runEventLoopWhenInterfaceProxyIsActive(value: boolean);
646
+ /**
647
+ * **Experimental Feature**
648
+ *
649
+ * Get whether to run the event loop when an interface proxy is active.
650
+ * @experimental
651
+ */
652
+ static get runEventLoopWhenInterfaceProxyIsActive(): boolean;
653
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "java-bridge",
3
- "version": "2.2.3-beta.2",
3
+ "version": "2.2.3",
4
4
  "main": "dist/index.prod.min.js",
5
5
  "types": "dist/ts-src/index.d.ts",
6
6
  "description": "A bridge between Node.js and Java APIs",
@@ -56,8 +56,9 @@
56
56
  "build:java:win32": "cd java-src && .\\gradlew.bat shadowJar",
57
57
  "prepublishOnly": "napi prepublish -t npm",
58
58
  "test": "npm run testOnly",
59
- "testOnly": "mocha -r ts-node/register test/*.test.ts --reporter mocha-multi-reporters --reporter-options configFile=mocha-reporter-config.json",
59
+ "testOnly": "npm run mocha",
60
60
  "pretestOnly": "npm run generateTestTypes",
61
+ "mocha": "mocha -r ts-node/register test/*.test.ts --reporter mocha-multi-reporters --reporter-options configFile=mocha-reporter-config.json",
61
62
  "pretest": "npm run build",
62
63
  "version": "napi version",
63
64
  "prettier": "prettier --write .",
@@ -73,29 +74,31 @@
73
74
  "glob": "^8.1.0",
74
75
  "ora": "^6.1.2",
75
76
  "typescript": "^4.9.5",
76
- "yargs": "^17.6.2"
77
+ "yargs": "^17.7.1"
77
78
  },
78
79
  "devDependencies": {
79
- "@napi-rs/cli": "^2.14.6",
80
+ "@napi-rs/cli": "^2.14.8",
80
81
  "@types/chai": "^4.3.4",
81
- "@types/glob": "^8.0.1",
82
+ "@types/folder-hash": "^4.0.2",
83
+ "@types/glob": "^8.1.0",
82
84
  "@types/is-ci": "^3.0.0",
83
85
  "@types/mocha": "^10.0.1",
84
- "@types/node": "^18.11.18",
86
+ "@types/node": "^18.14.1",
85
87
  "@types/semver": "^7.3.13",
86
- "@types/webpack-node-externals": "^2.5.3",
87
- "@types/which": "^2.0.1",
88
+ "@types/webpack-node-externals": "^3.0.0",
89
+ "@types/which": "^2.0.2",
88
90
  "@types/yargs": "^17.0.22",
89
91
  "chai": "^4.3.7",
90
92
  "cpy-cli": "^4.2.0",
91
93
  "expose-gc": "^1.0.0",
94
+ "folder-hash": "^4.0.4",
92
95
  "is-ci": "^3.0.1",
93
96
  "mocha": "^10.2.0",
94
97
  "mocha-junit-reporter": "^2.2.0",
95
98
  "mocha-multi-reporters": "^1.5.1",
96
99
  "nanobench": "^3.0.0",
97
100
  "node-loader": "^2.0.0",
98
- "prettier": "^2.8.3",
101
+ "prettier": "^2.8.4",
99
102
  "rimraf": "^4.1.2",
100
103
  "run-script-os": "^1.1.6",
101
104
  "semver": "^7.3.8",
@@ -103,18 +106,18 @@
103
106
  "ts-loader": "^9.4.2",
104
107
  "ts-node": "^10.9.1",
105
108
  "tslib": "^2.5.0",
106
- "typedoc": "^0.23.24",
109
+ "typedoc": "^0.23.25",
107
110
  "webpack": "^5.75.0",
108
111
  "webpack-cli": "^5.0.1",
109
112
  "webpack-node-externals": "^3.0.0",
110
113
  "which": "^3.0.0"
111
114
  },
112
115
  "optionalDependencies": {
113
- "java-bridge-win32-x64-msvc": "2.2.3-beta.2",
114
- "java-bridge-darwin-x64": "2.2.3-beta.2",
115
- "java-bridge-linux-x64-gnu": "2.2.3-beta.2",
116
- "java-bridge-darwin-arm64": "2.2.3-beta.2",
117
- "java-bridge-win32-ia32-msvc": "2.2.3-beta.2",
118
- "java-bridge-linux-arm64-gnu": "2.2.3-beta.2"
116
+ "java-bridge-win32-x64-msvc": "2.2.3",
117
+ "java-bridge-darwin-x64": "2.2.3",
118
+ "java-bridge-linux-x64-gnu": "2.2.3",
119
+ "java-bridge-darwin-arm64": "2.2.3",
120
+ "java-bridge-win32-ia32-msvc": "2.2.3",
121
+ "java-bridge-linux-arm64-gnu": "2.2.3"
119
122
  }
120
123
  }