javonet-nodejs-sdk 2.6.8 → 2.6.9
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/core/handler/CreateClassInstanceHandler.cjs +35 -1
- package/dist/core/handler/Handler.cjs +26 -2
- package/dist/sdk/InvocationContext.cjs +64 -11
- package/dist/types/core/handler/CreateClassInstanceHandler.d.ts +8 -0
- package/dist/types/sdk/InvocationContext.d.ts +9 -8
- package/dist/types/utils/CommandType.d.ts +1 -0
- package/dist/utils/CommandType.cjs +2 -1
- package/lib/core/handler/CreateClassInstanceHandler.js +46 -1
- package/lib/core/handler/Handler.js +32 -2
- package/lib/sdk/InvocationContext.js +87 -14
- package/lib/utils/CommandType.js +1 -0
- package/package.json +4 -3
|
@@ -24,9 +24,23 @@ module.exports = __toCommonJS(CreateClassInstanceHandler_exports);
|
|
|
24
24
|
var import_AbstractHandler = require("./AbstractHandler.cjs");
|
|
25
25
|
class CreateClassInstanceHandler extends import_AbstractHandler.AbstractHandler {
|
|
26
26
|
requiredParametersCount = 1;
|
|
27
|
+
// Add a simple invocation contexts store (Map GUID -> object)
|
|
28
|
+
static _invocationContexts = /* @__PURE__ */ new Map();
|
|
29
|
+
static getOrCreateContextDictionary() {
|
|
30
|
+
return CreateClassInstanceHandler._invocationContexts;
|
|
31
|
+
}
|
|
27
32
|
constructor() {
|
|
28
33
|
super();
|
|
29
34
|
}
|
|
35
|
+
// Helper to detect GUID in payload (standard format)
|
|
36
|
+
/**
|
|
37
|
+
* @param {{ toString: () => any; } | null} value
|
|
38
|
+
*/
|
|
39
|
+
static isGuid(value) {
|
|
40
|
+
if (value == null) return false;
|
|
41
|
+
const s = value.toString();
|
|
42
|
+
return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(s);
|
|
43
|
+
}
|
|
30
44
|
/**
|
|
31
45
|
* @param {Command} command
|
|
32
46
|
*/
|
|
@@ -36,7 +50,23 @@ class CreateClassInstanceHandler extends import_AbstractHandler.AbstractHandler
|
|
|
36
50
|
throw new Error("Create Class Instance parameters mismatch");
|
|
37
51
|
}
|
|
38
52
|
let clazz = command.payload[0];
|
|
39
|
-
let
|
|
53
|
+
let payloadLength = command.payload.length;
|
|
54
|
+
let contextGuid = null;
|
|
55
|
+
let constructorArguments = [];
|
|
56
|
+
if (payloadLength > 1 && CreateClassInstanceHandler.isGuid(command.payload[1])) {
|
|
57
|
+
contextGuid = command.payload[1].toString();
|
|
58
|
+
if (payloadLength > 2) {
|
|
59
|
+
constructorArguments = command.payload.slice(2);
|
|
60
|
+
} else {
|
|
61
|
+
constructorArguments = [];
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
if (payloadLength > 1) {
|
|
65
|
+
constructorArguments = command.payload.slice(1);
|
|
66
|
+
} else {
|
|
67
|
+
constructorArguments = [];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
40
70
|
let instance = new clazz(...constructorArguments);
|
|
41
71
|
if (typeof instance === "undefined") {
|
|
42
72
|
let methods = Object.getOwnPropertyNames(clazz).filter(function(property) {
|
|
@@ -50,6 +80,10 @@ class CreateClassInstanceHandler extends import_AbstractHandler.AbstractHandler
|
|
|
50
80
|
});
|
|
51
81
|
throw new Error(message);
|
|
52
82
|
} else {
|
|
83
|
+
if (contextGuid) {
|
|
84
|
+
const contextDict = CreateClassInstanceHandler.getOrCreateContextDictionary();
|
|
85
|
+
contextDict.set(contextGuid, instance);
|
|
86
|
+
}
|
|
53
87
|
return instance;
|
|
54
88
|
}
|
|
55
89
|
} catch (error) {
|
|
@@ -167,13 +167,37 @@ class Handler {
|
|
|
167
167
|
return this.parseCommand(resolvedResponse, runtimeName);
|
|
168
168
|
});
|
|
169
169
|
}
|
|
170
|
+
let responseCommand;
|
|
170
171
|
if (import_TypesHandler.TypesHandler.isPrimitiveOrNullOrUndefined(response)) {
|
|
171
|
-
|
|
172
|
+
responseCommand = import_Command.Command.createResponse(response, runtimeName);
|
|
172
173
|
} else {
|
|
173
174
|
let cache = import_ReferencesCache.ReferencesCache.getInstance();
|
|
174
175
|
let uuid = cache.cacheReference(response);
|
|
175
|
-
|
|
176
|
+
responseCommand = import_Command.Command.createReference(uuid, runtimeName);
|
|
176
177
|
}
|
|
178
|
+
const invocationContexts = import_CreateClassInstanceHandler.CreateClassInstanceHandler._invocationContexts;
|
|
179
|
+
if (invocationContexts && typeof invocationContexts.size === "number" && invocationContexts.size > 0) {
|
|
180
|
+
const refCache = import_ReferencesCache.ReferencesCache.getInstance();
|
|
181
|
+
for (const [contextKey, instance] of invocationContexts.entries()) {
|
|
182
|
+
const instanceGuid = refCache.cacheReference(instance);
|
|
183
|
+
const updateContextCommand = new import_Command.Command(
|
|
184
|
+
runtimeName,
|
|
185
|
+
import_CommandType.CommandType.UpdateInvocationContext,
|
|
186
|
+
[
|
|
187
|
+
contextKey.toString(),
|
|
188
|
+
instanceGuid
|
|
189
|
+
]
|
|
190
|
+
);
|
|
191
|
+
if (typeof responseCommand.addArgToPayload === "function") {
|
|
192
|
+
responseCommand = responseCommand.addArgToPayload(updateContextCommand);
|
|
193
|
+
} else {
|
|
194
|
+
responseCommand.payload = responseCommand.payload || [];
|
|
195
|
+
responseCommand.payload.push(updateContextCommand);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
invocationContexts.clear();
|
|
199
|
+
}
|
|
200
|
+
return responseCommand;
|
|
177
201
|
}
|
|
178
202
|
}
|
|
179
203
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -25,10 +25,10 @@ var import_DelegatesCache = require("../core/delegatesCache/DelegatesCache.cjs")
|
|
|
25
25
|
var import_Interpreter = require("../core/interpreter/Interpreter.cjs");
|
|
26
26
|
var import_Command = require("../utils/Command.cjs");
|
|
27
27
|
var import_CommandType = require("../utils/CommandType.cjs");
|
|
28
|
-
var import_ConnectionType = require("../utils/ConnectionType.cjs");
|
|
29
28
|
var import_ExceptionThrower = require("../utils/exception/ExceptionThrower.cjs");
|
|
30
29
|
var import_RuntimeName = require("../utils/RuntimeName.cjs");
|
|
31
30
|
var import_TypesHandler = require("../utils/TypesHandler.cjs");
|
|
31
|
+
var import_uuid = require("uuid");
|
|
32
32
|
class InvocationContext {
|
|
33
33
|
/** @type {RuntimeNameType} */
|
|
34
34
|
#runtimeName;
|
|
@@ -42,6 +42,10 @@ class InvocationContext {
|
|
|
42
42
|
#isExecuted = false;
|
|
43
43
|
/** @type {Interpreter | null} */
|
|
44
44
|
#interpreter = null;
|
|
45
|
+
/** @type {string | null} */
|
|
46
|
+
#guid = null;
|
|
47
|
+
// Static map holding contexts waiting for materialization (guid -> InvocationContext)
|
|
48
|
+
static _invocationContexts = /* @__PURE__ */ new Map();
|
|
45
49
|
/**
|
|
46
50
|
*
|
|
47
51
|
* @param {RuntimeNameType} runtimeName
|
|
@@ -56,6 +60,13 @@ class InvocationContext {
|
|
|
56
60
|
this.#responseCommand = null;
|
|
57
61
|
this.#isExecuted = isExecuted;
|
|
58
62
|
this.#interpreter = null;
|
|
63
|
+
this.#guid = (0, import_uuid.v4)();
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* @returns {string} guid of this InvocationContext
|
|
67
|
+
*/
|
|
68
|
+
getGuid() {
|
|
69
|
+
return this.#guid;
|
|
59
70
|
}
|
|
60
71
|
/**
|
|
61
72
|
* @param {Command} localCommand
|
|
@@ -101,13 +112,8 @@ class InvocationContext {
|
|
|
101
112
|
}
|
|
102
113
|
/**
|
|
103
114
|
* Executes the current command.
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* Commands are becoming nested through each invocation of methods on Invocation Context.
|
|
107
|
-
* Each invocation triggers the creation of new Invocation Context instance wrapping the current command with new parent command valid for invoked method.
|
|
108
|
-
* Developer can decide on any moment of the materialization for the context taking full control of the chunks of the expression being transferred and processed on target runtime.
|
|
109
|
-
* @returns {Promise<InvocationContext>} the InvocationContext after executing the command.
|
|
110
|
-
* @see [Javonet Guides](https://www.javonet.com/guides/v2/javascript/foundations/execute-method)
|
|
115
|
+
* Returns the InvocationContext after executing the command.
|
|
116
|
+
* @returns {Promise<InvocationContext>}
|
|
111
117
|
* @method
|
|
112
118
|
*/
|
|
113
119
|
async execute() {
|
|
@@ -124,6 +130,7 @@ class InvocationContext {
|
|
|
124
130
|
if (this.#responseCommand.commandType === import_CommandType.CommandType.Exception) {
|
|
125
131
|
throw import_ExceptionThrower.ExceptionThrower.throwException(this.#responseCommand);
|
|
126
132
|
}
|
|
133
|
+
this.#responseCommand = this.#processUpdateInvocationContextCommands(this.#responseCommand);
|
|
127
134
|
if (this.#responseCommand.commandType === import_CommandType.CommandType.CreateClassInstance) {
|
|
128
135
|
this.#currentCommand = this.#responseCommand;
|
|
129
136
|
this.#isExecuted = true;
|
|
@@ -171,14 +178,24 @@ class InvocationContext {
|
|
|
171
178
|
}
|
|
172
179
|
/**
|
|
173
180
|
* Creates a new instance of a class in the target runtime.
|
|
181
|
+
* Adds the newly created context to the static invocation contexts map and
|
|
182
|
+
* includes the context GUID as the first argument of CreateClassInstance command payload.
|
|
174
183
|
* @param {...any} args - The arguments to pass to the class constructor
|
|
175
184
|
* @returns {InvocationContext} A new InvocationContext instance that wraps the command to create the instance.
|
|
176
|
-
* @see [Javonet Guides](https://www.javonet.com/guides/v2/javascript/calling-methods/creating-instance-and-calling-instance-methods)
|
|
177
185
|
* @method
|
|
178
186
|
*/
|
|
179
187
|
createInstance(...args) {
|
|
180
|
-
|
|
181
|
-
|
|
188
|
+
const dummyCommand = new import_Command.Command(this.#runtimeName, import_CommandType.CommandType.CreateClassInstance, [
|
|
189
|
+
...args
|
|
190
|
+
]);
|
|
191
|
+
const createInstanceContext = new InvocationContext(this.#runtimeName, this.#connectionData, dummyCommand);
|
|
192
|
+
let localCommand = new import_Command.Command(this.#runtimeName, import_CommandType.CommandType.CreateClassInstance, [
|
|
193
|
+
createInstanceContext.getGuid(),
|
|
194
|
+
...args
|
|
195
|
+
]);
|
|
196
|
+
createInstanceContext.#currentCommand = this.#buildCommand(localCommand);
|
|
197
|
+
InvocationContext._invocationContexts.set(createInstanceContext.getGuid(), createInstanceContext);
|
|
198
|
+
return createInstanceContext;
|
|
182
199
|
}
|
|
183
200
|
/**
|
|
184
201
|
* Retrieves the value of an instance field from the target runtime.
|
|
@@ -470,6 +487,42 @@ class InvocationContext {
|
|
|
470
487
|
);
|
|
471
488
|
}
|
|
472
489
|
}
|
|
490
|
+
/**
|
|
491
|
+
* Process UpdateInvocationContext commands in the provided responseCommand payload.
|
|
492
|
+
* For each UpdateInvocationContext command, set the referenced InvocationContext's currentCommand to a Reference command,
|
|
493
|
+
* remove that InvocationContext from the static map and remove UpdateInvocationContext items from response payload.
|
|
494
|
+
* @param {Command} responseCommand
|
|
495
|
+
* @returns {Command}
|
|
496
|
+
*/
|
|
497
|
+
#processUpdateInvocationContextCommands(responseCommand) {
|
|
498
|
+
if (!responseCommand?.payload?.length) {
|
|
499
|
+
return responseCommand;
|
|
500
|
+
}
|
|
501
|
+
const commandsToUpdate = responseCommand.payload.filter(
|
|
502
|
+
(item) => item instanceof import_Command.Command && item.commandType === import_CommandType.CommandType.UpdateInvocationContext
|
|
503
|
+
);
|
|
504
|
+
if (commandsToUpdate.length === 0) {
|
|
505
|
+
return responseCommand;
|
|
506
|
+
}
|
|
507
|
+
const updatedPayload = new Set(responseCommand.payload);
|
|
508
|
+
for (const cmd of commandsToUpdate) {
|
|
509
|
+
if (cmd.payload?.length >= 2) {
|
|
510
|
+
const contextGuid = String(cmd.payload[0]);
|
|
511
|
+
const instanceGuid = cmd.payload[1];
|
|
512
|
+
const invCtx = InvocationContext._invocationContexts.get(contextGuid);
|
|
513
|
+
if (invCtx) {
|
|
514
|
+
invCtx.#currentCommand = new import_Command.Command(invCtx.#runtimeName, import_CommandType.CommandType.Reference, [instanceGuid]);
|
|
515
|
+
InvocationContext._invocationContexts.delete(contextGuid);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
updatedPayload.delete(cmd);
|
|
519
|
+
}
|
|
520
|
+
return new import_Command.Command(
|
|
521
|
+
responseCommand.runtimeName,
|
|
522
|
+
responseCommand.commandType,
|
|
523
|
+
Array.from(updatedPayload)
|
|
524
|
+
);
|
|
525
|
+
}
|
|
473
526
|
}
|
|
474
527
|
// Annotate the CommonJS export names for ESM import in node:
|
|
475
528
|
0 && (module.exports = {
|
|
@@ -3,6 +3,14 @@ export type Command = import("../../utils/Command.js").Command;
|
|
|
3
3
|
* @typedef {import('../../utils/Command.js').Command} Command
|
|
4
4
|
*/
|
|
5
5
|
export class CreateClassInstanceHandler extends AbstractHandler {
|
|
6
|
+
static _invocationContexts: Map<any, any>;
|
|
7
|
+
static getOrCreateContextDictionary(): Map<any, any>;
|
|
8
|
+
/**
|
|
9
|
+
* @param {{ toString: () => any; } | null} value
|
|
10
|
+
*/
|
|
11
|
+
static isGuid(value: {
|
|
12
|
+
toString: () => any;
|
|
13
|
+
} | null): boolean;
|
|
6
14
|
requiredParametersCount: number;
|
|
7
15
|
/**
|
|
8
16
|
* @param {Command} command
|
|
@@ -12,6 +12,7 @@ export type IConnectionData = import("../utils/connectionData/IConnectionData.js
|
|
|
12
12
|
* @class
|
|
13
13
|
*/
|
|
14
14
|
export class InvocationContext {
|
|
15
|
+
static _invocationContexts: Map<any, any>;
|
|
15
16
|
/**
|
|
16
17
|
*
|
|
17
18
|
* @param {RuntimeNameType} runtimeName
|
|
@@ -20,19 +21,18 @@ export class InvocationContext {
|
|
|
20
21
|
* @param {boolean} isExecuted
|
|
21
22
|
*/
|
|
22
23
|
constructor(runtimeName: RuntimeNameType, connectionData: IConnectionData, command: Command, isExecuted?: boolean);
|
|
24
|
+
/**
|
|
25
|
+
* @returns {string} guid of this InvocationContext
|
|
26
|
+
*/
|
|
27
|
+
getGuid(): string;
|
|
23
28
|
/**
|
|
24
29
|
* @returns {Command|null}
|
|
25
30
|
*/
|
|
26
31
|
get_current_command(): Command | null;
|
|
27
32
|
/**
|
|
28
33
|
* Executes the current command.
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* Commands are becoming nested through each invocation of methods on Invocation Context.
|
|
32
|
-
* Each invocation triggers the creation of new Invocation Context instance wrapping the current command with new parent command valid for invoked method.
|
|
33
|
-
* Developer can decide on any moment of the materialization for the context taking full control of the chunks of the expression being transferred and processed on target runtime.
|
|
34
|
-
* @returns {Promise<InvocationContext>} the InvocationContext after executing the command.
|
|
35
|
-
* @see [Javonet Guides](https://www.javonet.com/guides/v2/javascript/foundations/execute-method)
|
|
34
|
+
* Returns the InvocationContext after executing the command.
|
|
35
|
+
* @returns {Promise<InvocationContext>}
|
|
36
36
|
* @method
|
|
37
37
|
*/
|
|
38
38
|
execute(): Promise<InvocationContext>;
|
|
@@ -64,9 +64,10 @@ export class InvocationContext {
|
|
|
64
64
|
setStaticField(fieldName: string, value: any): InvocationContext;
|
|
65
65
|
/**
|
|
66
66
|
* Creates a new instance of a class in the target runtime.
|
|
67
|
+
* Adds the newly created context to the static invocation contexts map and
|
|
68
|
+
* includes the context GUID as the first argument of CreateClassInstance command payload.
|
|
67
69
|
* @param {...any} args - The arguments to pass to the class constructor
|
|
68
70
|
* @returns {InvocationContext} A new InvocationContext instance that wraps the command to create the instance.
|
|
69
|
-
* @see [Javonet Guides](https://www.javonet.com/guides/v2/javascript/calling-methods/creating-instance-and-calling-instance-methods)
|
|
70
71
|
* @method
|
|
71
72
|
*/
|
|
72
73
|
createInstance(...args: any[]): InvocationContext;
|
|
@@ -8,10 +8,28 @@ import { AbstractHandler } from './AbstractHandler.js'
|
|
|
8
8
|
class CreateClassInstanceHandler extends AbstractHandler {
|
|
9
9
|
requiredParametersCount = 1
|
|
10
10
|
|
|
11
|
+
// Add a simple invocation contexts store (Map GUID -> object)
|
|
12
|
+
static _invocationContexts = new Map()
|
|
13
|
+
|
|
14
|
+
static getOrCreateContextDictionary() {
|
|
15
|
+
// In a simple approach we keep a single map for the process.
|
|
16
|
+
return CreateClassInstanceHandler._invocationContexts
|
|
17
|
+
}
|
|
18
|
+
|
|
11
19
|
constructor() {
|
|
12
20
|
super()
|
|
13
21
|
}
|
|
14
22
|
|
|
23
|
+
// Helper to detect GUID in payload (standard format)
|
|
24
|
+
/**
|
|
25
|
+
* @param {{ toString: () => any; } | null} value
|
|
26
|
+
*/
|
|
27
|
+
static isGuid(value) {
|
|
28
|
+
if (value == null) return false
|
|
29
|
+
const s = value.toString()
|
|
30
|
+
return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(s)
|
|
31
|
+
}
|
|
32
|
+
|
|
15
33
|
/**
|
|
16
34
|
* @param {Command} command
|
|
17
35
|
*/
|
|
@@ -20,8 +38,29 @@ class CreateClassInstanceHandler extends AbstractHandler {
|
|
|
20
38
|
if (command.payload.length < this.requiredParametersCount) {
|
|
21
39
|
throw new Error('Create Class Instance parameters mismatch')
|
|
22
40
|
}
|
|
41
|
+
|
|
23
42
|
let clazz = command.payload[0]
|
|
24
|
-
|
|
43
|
+
|
|
44
|
+
// Extract optional GUID and constructor arguments
|
|
45
|
+
let payloadLength = command.payload.length
|
|
46
|
+
let contextGuid = null
|
|
47
|
+
let constructorArguments = []
|
|
48
|
+
|
|
49
|
+
if (payloadLength > 1 && CreateClassInstanceHandler.isGuid(command.payload[1])) {
|
|
50
|
+
contextGuid = command.payload[1].toString()
|
|
51
|
+
if (payloadLength > 2) {
|
|
52
|
+
constructorArguments = command.payload.slice(2)
|
|
53
|
+
} else {
|
|
54
|
+
constructorArguments = []
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
if (payloadLength > 1) {
|
|
58
|
+
constructorArguments = command.payload.slice(1)
|
|
59
|
+
} else {
|
|
60
|
+
constructorArguments = []
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
25
64
|
let instance = new clazz(...constructorArguments)
|
|
26
65
|
if (typeof instance === 'undefined') {
|
|
27
66
|
let methods = Object.getOwnPropertyNames(clazz).filter(function (property) {
|
|
@@ -33,6 +72,12 @@ class CreateClassInstanceHandler extends AbstractHandler {
|
|
|
33
72
|
})
|
|
34
73
|
throw new Error(message)
|
|
35
74
|
} else {
|
|
75
|
+
// If GUID provided, store instance in context dictionary
|
|
76
|
+
if (contextGuid) {
|
|
77
|
+
const contextDict = CreateClassInstanceHandler.getOrCreateContextDictionary()
|
|
78
|
+
// Overwrite or add entry
|
|
79
|
+
contextDict.set(contextGuid, instance)
|
|
80
|
+
}
|
|
36
81
|
return instance
|
|
37
82
|
}
|
|
38
83
|
} catch (error) {
|
|
@@ -164,13 +164,43 @@ class Handler {
|
|
|
164
164
|
})
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
// Create base responseCommand (either primitive response or a reference)
|
|
168
|
+
let responseCommand
|
|
167
169
|
if (TypesHandler.isPrimitiveOrNullOrUndefined(response)) {
|
|
168
|
-
|
|
170
|
+
responseCommand = Command.createResponse(response, runtimeName)
|
|
169
171
|
} else {
|
|
170
172
|
let cache = ReferencesCache.getInstance()
|
|
171
173
|
let uuid = cache.cacheReference(response)
|
|
172
|
-
|
|
174
|
+
responseCommand = Command.createReference(uuid, runtimeName)
|
|
173
175
|
}
|
|
176
|
+
|
|
177
|
+
// If any invocation contexts were created during instance creation, attach UpdateInvocationContext commands
|
|
178
|
+
const invocationContexts = CreateClassInstanceHandler._invocationContexts
|
|
179
|
+
if (invocationContexts && typeof invocationContexts.size === 'number' && invocationContexts.size > 0) {
|
|
180
|
+
const refCache = ReferencesCache.getInstance()
|
|
181
|
+
for (const [contextKey, instance] of invocationContexts.entries()) {
|
|
182
|
+
const instanceGuid = refCache.cacheReference(instance)
|
|
183
|
+
const updateContextCommand = new Command(
|
|
184
|
+
runtimeName,
|
|
185
|
+
CommandType.UpdateInvocationContext,
|
|
186
|
+
[contextKey.toString(),
|
|
187
|
+
instanceGuid]
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
// Prefer using addArgToPayload if available, otherwise push into payload array
|
|
191
|
+
if (typeof responseCommand.addArgToPayload === 'function') {
|
|
192
|
+
responseCommand = responseCommand.addArgToPayload(updateContextCommand)
|
|
193
|
+
} else {
|
|
194
|
+
responseCommand.payload = responseCommand.payload || []
|
|
195
|
+
responseCommand.payload.push(updateContextCommand)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Clear contexts after attaching them to the response
|
|
200
|
+
invocationContexts.clear()
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return responseCommand
|
|
174
204
|
}
|
|
175
205
|
}
|
|
176
206
|
|
|
@@ -3,10 +3,10 @@ import { delegatesCacheInstance } from '../core/delegatesCache/DelegatesCache.js
|
|
|
3
3
|
import { Interpreter } from '../core/interpreter/Interpreter.js'
|
|
4
4
|
import { Command } from '../utils/Command.js'
|
|
5
5
|
import { CommandType } from '../utils/CommandType.js'
|
|
6
|
-
import { ConnectionType } from '../utils/ConnectionType.js'
|
|
7
6
|
import { ExceptionThrower } from '../utils/exception/ExceptionThrower.js'
|
|
8
7
|
import { RuntimeName } from '../utils/RuntimeName.js'
|
|
9
8
|
import { TypesHandler } from '../utils/TypesHandler.js'
|
|
9
|
+
import { v4 as uuidv4 } from 'uuid' // add lightweight uuid generation
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @typedef {import('../types.d.ts').RuntimeName} RuntimeNameType
|
|
@@ -33,6 +33,11 @@ class InvocationContext {
|
|
|
33
33
|
#isExecuted = false
|
|
34
34
|
/** @type {Interpreter | null} */
|
|
35
35
|
#interpreter = null
|
|
36
|
+
/** @type {string | null} */
|
|
37
|
+
#guid = null
|
|
38
|
+
|
|
39
|
+
// Static map holding contexts waiting for materialization (guid -> InvocationContext)
|
|
40
|
+
static _invocationContexts = new Map()
|
|
36
41
|
|
|
37
42
|
/**
|
|
38
43
|
*
|
|
@@ -48,6 +53,15 @@ class InvocationContext {
|
|
|
48
53
|
this.#responseCommand = null
|
|
49
54
|
this.#isExecuted = isExecuted
|
|
50
55
|
this.#interpreter = null
|
|
56
|
+
this.#guid = uuidv4()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @returns {string} guid of this InvocationContext
|
|
61
|
+
*/
|
|
62
|
+
getGuid() {
|
|
63
|
+
// @ts-ignore
|
|
64
|
+
return this.#guid
|
|
51
65
|
}
|
|
52
66
|
|
|
53
67
|
/**
|
|
@@ -99,13 +113,8 @@ class InvocationContext {
|
|
|
99
113
|
|
|
100
114
|
/**
|
|
101
115
|
* Executes the current command.
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* Commands are becoming nested through each invocation of methods on Invocation Context.
|
|
105
|
-
* Each invocation triggers the creation of new Invocation Context instance wrapping the current command with new parent command valid for invoked method.
|
|
106
|
-
* Developer can decide on any moment of the materialization for the context taking full control of the chunks of the expression being transferred and processed on target runtime.
|
|
107
|
-
* @returns {Promise<InvocationContext>} the InvocationContext after executing the command.
|
|
108
|
-
* @see [Javonet Guides](https://www.javonet.com/guides/v2/javascript/foundations/execute-method)
|
|
116
|
+
* Returns the InvocationContext after executing the command.
|
|
117
|
+
* @returns {Promise<InvocationContext>}
|
|
109
118
|
* @method
|
|
110
119
|
*/
|
|
111
120
|
async execute() {
|
|
@@ -117,6 +126,7 @@ class InvocationContext {
|
|
|
117
126
|
this.#interpreter = new Interpreter()
|
|
118
127
|
}
|
|
119
128
|
|
|
129
|
+
// Execute command on interpreter
|
|
120
130
|
this.#responseCommand = await this.#interpreter.execute(this.#currentCommand, this.#connectionData)
|
|
121
131
|
|
|
122
132
|
if (!this.#responseCommand) {
|
|
@@ -125,6 +135,10 @@ class InvocationContext {
|
|
|
125
135
|
if (this.#responseCommand.commandType === CommandType.Exception) {
|
|
126
136
|
throw ExceptionThrower.throwException(this.#responseCommand)
|
|
127
137
|
}
|
|
138
|
+
|
|
139
|
+
// Process UpdateInvocationContext commands (if any) coming from runtime
|
|
140
|
+
this.#responseCommand = this.#processUpdateInvocationContextCommands(this.#responseCommand)
|
|
141
|
+
|
|
128
142
|
if (this.#responseCommand.commandType === CommandType.CreateClassInstance) {
|
|
129
143
|
this.#currentCommand = this.#responseCommand
|
|
130
144
|
this.#isExecuted = true
|
|
@@ -176,14 +190,30 @@ class InvocationContext {
|
|
|
176
190
|
|
|
177
191
|
/**
|
|
178
192
|
* Creates a new instance of a class in the target runtime.
|
|
193
|
+
* Adds the newly created context to the static invocation contexts map and
|
|
194
|
+
* includes the context GUID as the first argument of CreateClassInstance command payload.
|
|
179
195
|
* @param {...any} args - The arguments to pass to the class constructor
|
|
180
196
|
* @returns {InvocationContext} A new InvocationContext instance that wraps the command to create the instance.
|
|
181
|
-
* @see [Javonet Guides](https://www.javonet.com/guides/v2/javascript/calling-methods/creating-instance-and-calling-instance-methods)
|
|
182
197
|
* @method
|
|
183
198
|
*/
|
|
184
199
|
createInstance(...args) {
|
|
185
|
-
|
|
186
|
-
|
|
200
|
+
const dummyCommand = new Command(this.#runtimeName, CommandType.CreateClassInstance, [
|
|
201
|
+
...args,
|
|
202
|
+
])
|
|
203
|
+
const createInstanceContext = new InvocationContext(this.#runtimeName, this.#connectionData, dummyCommand)
|
|
204
|
+
// include guid as first payload element followed by constructor args
|
|
205
|
+
let localCommand = new Command(this.#runtimeName, CommandType.CreateClassInstance, [
|
|
206
|
+
createInstanceContext.getGuid(),
|
|
207
|
+
...args,
|
|
208
|
+
])
|
|
209
|
+
|
|
210
|
+
// set current command for the new context
|
|
211
|
+
createInstanceContext.#currentCommand = this.#buildCommand(localCommand)
|
|
212
|
+
|
|
213
|
+
// register context for materialization
|
|
214
|
+
InvocationContext._invocationContexts.set(createInstanceContext.getGuid(), createInstanceContext)
|
|
215
|
+
|
|
216
|
+
return createInstanceContext
|
|
187
217
|
}
|
|
188
218
|
|
|
189
219
|
/**
|
|
@@ -429,7 +459,7 @@ class InvocationContext {
|
|
|
429
459
|
await localInvCtx.execute()
|
|
430
460
|
|
|
431
461
|
const resolve = (/** @type {any} */ item) => {
|
|
432
|
-
return item?.commandType === CommandType.Reference ?
|
|
462
|
+
return item?.commandType === CommandType.Reference ?
|
|
433
463
|
new InvocationContext(
|
|
434
464
|
this.#runtimeName,
|
|
435
465
|
this.#connectionData,
|
|
@@ -441,11 +471,11 @@ class InvocationContext {
|
|
|
441
471
|
if (!respCommand) {
|
|
442
472
|
return []
|
|
443
473
|
}
|
|
444
|
-
|
|
474
|
+
|
|
445
475
|
if (respCommand.payload) {
|
|
446
476
|
return respCommand.payload.map((/** @type {any} */ item) => resolve(item))
|
|
447
477
|
}
|
|
448
|
-
|
|
478
|
+
|
|
449
479
|
return respCommand.payload || []
|
|
450
480
|
}
|
|
451
481
|
|
|
@@ -507,6 +537,49 @@ class InvocationContext {
|
|
|
507
537
|
)
|
|
508
538
|
}
|
|
509
539
|
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Process UpdateInvocationContext commands in the provided responseCommand payload.
|
|
543
|
+
* For each UpdateInvocationContext command, set the referenced InvocationContext's currentCommand to a Reference command,
|
|
544
|
+
* remove that InvocationContext from the static map and remove UpdateInvocationContext items from response payload.
|
|
545
|
+
* @param {Command} responseCommand
|
|
546
|
+
* @returns {Command}
|
|
547
|
+
*/
|
|
548
|
+
#processUpdateInvocationContextCommands(responseCommand) {
|
|
549
|
+
if (!responseCommand?.payload?.length) {
|
|
550
|
+
return responseCommand
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
const commandsToUpdate = responseCommand.payload.filter(
|
|
554
|
+
(/** @type {unknown} */ item) => item instanceof Command && item.commandType === CommandType.UpdateInvocationContext
|
|
555
|
+
)
|
|
556
|
+
|
|
557
|
+
if (commandsToUpdate.length === 0) {
|
|
558
|
+
return responseCommand
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
const updatedPayload = new Set(responseCommand.payload)
|
|
562
|
+
|
|
563
|
+
for (const cmd of commandsToUpdate) {
|
|
564
|
+
if (cmd.payload?.length >= 2) {
|
|
565
|
+
const contextGuid = String(cmd.payload[0])
|
|
566
|
+
const instanceGuid = cmd.payload[1]
|
|
567
|
+
const invCtx = InvocationContext._invocationContexts.get(contextGuid)
|
|
568
|
+
|
|
569
|
+
if (invCtx) {
|
|
570
|
+
invCtx.#currentCommand = new Command(invCtx.#runtimeName, CommandType.Reference, [instanceGuid])
|
|
571
|
+
InvocationContext._invocationContexts.delete(contextGuid)
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
updatedPayload.delete(cmd)
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
return new Command(
|
|
578
|
+
responseCommand.runtimeName,
|
|
579
|
+
responseCommand.commandType,
|
|
580
|
+
Array.from(updatedPayload)
|
|
581
|
+
)
|
|
582
|
+
}
|
|
510
583
|
}
|
|
511
584
|
|
|
512
585
|
export { InvocationContext }
|
package/lib/utils/CommandType.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "javonet-nodejs-sdk",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.9",
|
|
4
4
|
"description": "Javonet allows you to reference and use modules or packages written in (Java/Kotlin/Groovy/Clojure, C#/VB.NET, Ruby, Perl, Python, JavaScript/TypeScript) like they were created in your technology. It works on Linux/Windows and MacOS for applications created in JVM, CLR/Netcore, Perl, Python, Ruby, NodeJS, C++ or GoLang and gives you unparalleled freedom and flexibility with native performance in building your mixed-technologies products. Let it be accessing best AI or cryptography libraries, devices SDKs, legacy client modules, internal custom packages or anything from public repositories available on NPM, Nuget, PyPI, Maven/Gradle, RubyGems or GitHub. Get free from programming languages barriers today! For more information check out our guides at https://www.javonet.com/guides/v2/",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "SdNCenter Sp. z o. o.",
|
|
@@ -40,12 +40,13 @@
|
|
|
40
40
|
"format": "prettier --write ."
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
+
"@types/uuid": "^10.0.0",
|
|
43
44
|
"@types/ws": "^8.18.1",
|
|
44
45
|
"buffer": "^6.0.3",
|
|
45
46
|
"glob": "^10.4.5",
|
|
46
47
|
"js-yaml": "^4.1.0",
|
|
47
48
|
"uuid": "^10.0.0",
|
|
48
|
-
"ws": "^8.
|
|
49
|
+
"ws": "^8.18.1"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@babel/cli": "^7.25.9",
|
|
@@ -58,7 +59,7 @@
|
|
|
58
59
|
"@types/js-yaml": "^4.0.9",
|
|
59
60
|
"babel-loader": "^9.2.1",
|
|
60
61
|
"cross-env": "^7.0.3",
|
|
61
|
-
"esbuild": "^0.
|
|
62
|
+
"esbuild": "^0.27.0",
|
|
62
63
|
"eslint": "^9.15.0",
|
|
63
64
|
"eslint-config-prettier": "^9.1.0",
|
|
64
65
|
"eslint-plugin-jest": "^28.9.0",
|