@deephaven-enterprise/query-utils 2026.1.40 → 2026.1.42

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.
@@ -11,3 +11,40 @@
11
11
  * @returns An array of tokens. Returns an empty array for empty/whitespace input.
12
12
  */
13
13
  export declare function tokenizeArgs(args: string): string[];
14
+ /**
15
+ * Joins a flat alternating key/value array into a space-separated
16
+ * `KEY=VALUE` string. Values are shell-quoted as needed so the output can be
17
+ * round-tripped back through {@link splitEnvVarEntries}.
18
+ *
19
+ * @param entries Flat alternating array: `["KEY1", "VALUE1", "KEY2", "VALUE2", …]`
20
+ * @returns Shell-safe string: `"KEY1=VALUE1 KEY2='value with spaces'"`
21
+ */
22
+ export declare function joinEnvVarEntries(entries: string[]): string;
23
+ /**
24
+ * Parses a space-separated `KEY=VALUE` string into a flat alternating
25
+ * key/value array. Uses shell quoting rules so that quoted spans are
26
+ * stripped and values may contain spaces or `=` signs (e.g.
27
+ * `MY_VAR="value=with spaces"` → `["MY_VAR", "value=with spaces"]`).
28
+ * Each token must have a non-empty key; tokens with an empty key or shell
29
+ * operators throw an error.
30
+ *
31
+ * @param envVars Space-separated `KEY=VALUE` string.
32
+ * @returns Flat alternating array: `["KEY1", "VALUE1", "KEY2", "VALUE2", …]`
33
+ * @throws {Error} If any token has an empty key or is a shell operator/glob.
34
+ */
35
+ export declare function splitEnvVarEntries(envVars: string): string[];
36
+ /**
37
+ * Joins an array of classpath entries into a colon-separated string.
38
+ *
39
+ * @param entries Array of classpath entries, one path per element.
40
+ * @returns Colon-separated string: `"path1:path2:path3"`
41
+ */
42
+ export declare function joinClasspathAdditions(entries: string[]): string;
43
+ /**
44
+ * Splits a colon-separated classpath string into an array of entries,
45
+ * filtering out any empty segments.
46
+ *
47
+ * @param classpaths Colon-separated string: `"path1:path2:path3"`
48
+ * @returns Array of classpath entries, one path per element.
49
+ */
50
+ export declare function splitClasspathAdditions(classpaths: string): string[];
@@ -1,3 +1,4 @@
1
+ import ShellQuote from 'shell-quote';
1
2
  /**
2
3
  * Tokenizes a string of arguments by whitespace, respecting quoted spans.
3
4
  * Whitespace that appears inside `"..."` or `'...'` is treated as a literal
@@ -10,8 +11,77 @@
10
11
  * @param args The argument string to tokenize (e.g. JVM args or env vars).
11
12
  * @returns An array of tokens. Returns an empty array for empty/whitespace input.
12
13
  */
13
- // eslint-disable-next-line import/prefer-default-export
14
14
  export function tokenizeArgs(args) {
15
15
  var _a;
16
16
  return (_a = args.match(/(?:[^\s"']+|"[^"]*"|'[^']*'|["'])+/g)) !== null && _a !== void 0 ? _a : [];
17
17
  }
18
+ /**
19
+ * Joins a flat alternating key/value array into a space-separated
20
+ * `KEY=VALUE` string. Values are shell-quoted as needed so the output can be
21
+ * round-tripped back through {@link splitEnvVarEntries}.
22
+ *
23
+ * @param entries Flat alternating array: `["KEY1", "VALUE1", "KEY2", "VALUE2", …]`
24
+ * @returns Shell-safe string: `"KEY1=VALUE1 KEY2='value with spaces'"`
25
+ */
26
+ export function joinEnvVarEntries(entries) {
27
+ const pairs = [];
28
+ for (let i = 0; i + 1 < entries.length; i += 2) {
29
+ const key = entries[i];
30
+ const value = entries[i + 1];
31
+ const quotedValue = ShellQuote.quote([value]);
32
+ pairs.push(`${key}=${quotedValue}`);
33
+ }
34
+ return pairs.join(' ');
35
+ }
36
+ /**
37
+ * Parses a space-separated `KEY=VALUE` string into a flat alternating
38
+ * key/value array. Uses shell quoting rules so that quoted spans are
39
+ * stripped and values may contain spaces or `=` signs (e.g.
40
+ * `MY_VAR="value=with spaces"` → `["MY_VAR", "value=with spaces"]`).
41
+ * Each token must have a non-empty key; tokens with an empty key or shell
42
+ * operators throw an error.
43
+ *
44
+ * @param envVars Space-separated `KEY=VALUE` string.
45
+ * @returns Flat alternating array: `["KEY1", "VALUE1", "KEY2", "VALUE2", …]`
46
+ * @throws {Error} If any token has an empty key or is a shell operator/glob.
47
+ */
48
+ export function splitEnvVarEntries(envVars) {
49
+ const parsed = ShellQuote.parse(envVars);
50
+ const entries = [];
51
+ for (let i = 0; i < parsed.length; i += 1) {
52
+ const token = parsed[i];
53
+ if (typeof token !== 'string') {
54
+ throw new Error(`Invalid environment variable entry: "${JSON.stringify(token)}"`);
55
+ }
56
+ const eqIndex = token.indexOf('=');
57
+ if (eqIndex === 0) {
58
+ throw new Error(`Invalid environment variable entry: "${token}"`);
59
+ }
60
+ if (eqIndex === -1) {
61
+ entries.push(token, '');
62
+ }
63
+ else {
64
+ entries.push(token.slice(0, eqIndex), token.slice(eqIndex + 1));
65
+ }
66
+ }
67
+ return entries;
68
+ }
69
+ /**
70
+ * Joins an array of classpath entries into a colon-separated string.
71
+ *
72
+ * @param entries Array of classpath entries, one path per element.
73
+ * @returns Colon-separated string: `"path1:path2:path3"`
74
+ */
75
+ export function joinClasspathAdditions(entries) {
76
+ return entries.join(':');
77
+ }
78
+ /**
79
+ * Splits a colon-separated classpath string into an array of entries,
80
+ * filtering out any empty segments.
81
+ *
82
+ * @param classpaths Colon-separated string: `"path1:path2:path3"`
83
+ * @returns Array of classpath entries, one path per element.
84
+ */
85
+ export function splitClasspathAdditions(classpaths) {
86
+ return classpaths.split(':').filter(Boolean);
87
+ }
@@ -26,6 +26,7 @@ export type DraftQueryConstructorObject = Partial<IDraftQuery> & Pick<IDraftQuer
26
26
  * A Draft Query is a client side object that contains mutable data for a Peristent Query along with some metadata.
27
27
  */
28
28
  export declare class DraftQuery implements IDraftQuery {
29
+ #private;
29
30
  static NO_SERIAL: null;
30
31
  static INVALID_SCRIPT_PATH: string;
31
32
  static RESTART_MODE: Readonly<{
@@ -40,11 +41,14 @@ export declare class DraftQuery implements IDraftQuery {
40
41
  readonly TYPE: "type";
41
42
  readonly ENABLED: "enabled";
42
43
  readonly ENABLED_GC_LOGS: "enableGcLogs";
44
+ /** @deprecated Use ENV_VAR_ENTRIES */
43
45
  readonly ENV_VARS: "envVars";
44
46
  readonly HEAP_SIZE: "heapSize";
45
47
  readonly ADDITIONAL_MEMORY: "additionalMemory";
46
48
  readonly DATA_MEMORY_RATIO: "dataMemoryRatio";
49
+ /** @deprecated Use JVM_ARGUMENTS */
47
50
  readonly JVM_ARGS: "jvmArgs";
51
+ /** @deprecated Use CLASSPATH_ADDITIONS */
48
52
  readonly EXTRA_CLASSPATHS: "extraClasspaths";
49
53
  readonly JVM_PROFILE: "jvmProfile";
50
54
  readonly DB_SERVER_NAME: "dbServerName";
@@ -68,6 +72,9 @@ export declare class DraftQuery implements IDraftQuery {
68
72
  readonly INITIALIZATION_THREADS: "initializationThreads";
69
73
  readonly UPDATE_THREADS: "updateThreads";
70
74
  readonly DEFAULTS: "defaults";
75
+ readonly ENV_VAR_ENTRIES: "envVarEntries";
76
+ readonly JVM_ARGUMENTS: "jvmArguments";
77
+ readonly CLASSPATH_ADDITIONS: "classpathAdditions";
71
78
  }>;
72
79
  /**
73
80
  * Checks if a serial id from the server is actually a draft id
@@ -81,7 +88,13 @@ export declare class DraftQuery implements IDraftQuery {
81
88
  * @param serial a serial that contains a draft id
82
89
  */
83
90
  static serialToDraftId(serial: string): string;
84
- constructor({ isModified, isClientSide, draftOwner, serial, name, owner, type, enabled, enableGcLogs, envVars, heapSize, additionalMemory, dataMemoryRatio, jvmArgs, extraClasspaths, jvmProfile, dbServerName, scriptLanguage, scriptPath, scriptCode, scheduling, adminGroups, viewerGroups, restartUsers, timeout, workerKind, kubernetesControl, pythonControl, genericWorkerControl, typeSpecificFields, replicaCount, spareCount, assignmentPolicy, assignmentPolicyParams, initializationThreads, updateThreads, defaults, }: DraftQueryConstructorObject);
91
+ constructor({ isModified, isClientSide, draftOwner, serial, name, owner, type, enabled, enableGcLogs,
92
+ /** @deprecated Use envVarEntries */
93
+ envVars, heapSize, additionalMemory, dataMemoryRatio,
94
+ /** @deprecated Use jvmArguments */
95
+ jvmArgs,
96
+ /** @deprecated Use classpathAdditions */
97
+ extraClasspaths, jvmProfile, dbServerName, scriptLanguage, scriptPath, scriptCode, scheduling, adminGroups, viewerGroups, restartUsers, timeout, workerKind, kubernetesControl, pythonControl, genericWorkerControl, typeSpecificFields, replicaCount, spareCount, assignmentPolicy, assignmentPolicyParams, initializationThreads, updateThreads, defaults, envVarEntries, jvmArguments, classpathAdditions, }: DraftQueryConstructorObject);
85
98
  id: string;
86
99
  isModified: boolean;
87
100
  isClientSide: boolean;
@@ -92,12 +105,21 @@ export declare class DraftQuery implements IDraftQuery {
92
105
  type: string;
93
106
  enabled: boolean;
94
107
  enableGcLogs: boolean;
108
+ get envVarEntries(): string[];
109
+ set envVarEntries(value: string[]);
110
+ get jvmArguments(): string[];
111
+ set jvmArguments(value: string[]);
112
+ get classpathAdditions(): string[];
113
+ set classpathAdditions(value: string[]);
114
+ /** @deprecated Use `envVarEntries` instead. */
95
115
  envVars: string;
116
+ /** @deprecated Use `jvmArguments` instead. */
117
+ jvmArgs: string;
118
+ /** @deprecated Use `classpathAdditions` instead. */
119
+ extraClasspaths: string;
96
120
  heapSize: number;
97
121
  additionalMemory: number;
98
122
  dataMemoryRatio: number;
99
- jvmArgs: string;
100
- extraClasspaths: string;
101
123
  jvmProfile: string;
102
124
  dbServerName: string;
103
125
  scriptLanguage: string | null;
@@ -1,5 +1,18 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
7
+ if (kind === "m") throw new TypeError("Private method is not writable");
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
+ };
12
+ var _DraftQuery_envVarEntries, _DraftQuery_jvmArguments, _DraftQuery_classpathAdditions;
1
13
  /* eslint-disable no-param-reassign */
2
14
  import { nanoid } from 'nanoid';
15
+ import { joinClasspathAdditions, joinEnvVarEntries, splitClasspathAdditions, splitEnvVarEntries, tokenizeArgs, } from './ArgumentUtils';
3
16
  import QueryColumns from './QueryColumns';
4
17
  import QueryScheduler from './QueryScheduler';
5
18
  import { QueryType } from './QueryType';
@@ -26,7 +39,22 @@ export class DraftQuery {
26
39
  // Remove the 'Draft ID: ' marking
27
40
  return serial === null || serial === void 0 ? void 0 : serial.substring(DRAFT_SERIAL_PREFIX.length);
28
41
  }
29
- constructor({ isModified = false, isClientSide = false, draftOwner, serial = DraftQuery.NO_SERIAL, name, owner, type = QueryType.SCRIPT, enabled = true, enableGcLogs = true, envVars = '', heapSize = 4.0, additionalMemory = 0.0, dataMemoryRatio = 0.25, jvmArgs = '', extraClasspaths = '', jvmProfile = 'Default', dbServerName, scriptLanguage = 'Groovy', scriptPath = null, scriptCode = '', scheduling, adminGroups = [], viewerGroups = [], restartUsers = DraftQuery.RESTART_MODE.ADMIN, timeout = 0, workerKind = null, kubernetesControl = null, pythonControl = null, genericWorkerControl = null, typeSpecificFields = null, replicaCount = 1, spareCount = 0, assignmentPolicy = null, assignmentPolicyParams = null, initializationThreads = undefined, updateThreads = undefined, defaults = undefined, }) {
42
+ constructor({ isModified = false, isClientSide = false, draftOwner, serial = DraftQuery.NO_SERIAL, name, owner, type = QueryType.SCRIPT, enabled = true, enableGcLogs = true,
43
+ /** @deprecated Use envVarEntries */
44
+ envVars = '', heapSize = 4.0, additionalMemory = 0.0, dataMemoryRatio = 0.25,
45
+ /** @deprecated Use jvmArguments */
46
+ jvmArgs = '',
47
+ /** @deprecated Use classpathAdditions */
48
+ extraClasspaths = '', jvmProfile = 'Default', dbServerName, scriptLanguage = 'Groovy', scriptPath = null, scriptCode = '', scheduling, adminGroups = [], viewerGroups = [], restartUsers = DraftQuery.RESTART_MODE.ADMIN, timeout = 0, workerKind = null, kubernetesControl = null, pythonControl = null, genericWorkerControl = null, typeSpecificFields = null, replicaCount = 1, spareCount = 0, assignmentPolicy = null, assignmentPolicyParams = null, initializationThreads = undefined, updateThreads = undefined, defaults = undefined, envVarEntries = undefined, jvmArguments = undefined, classpathAdditions = undefined, }) {
49
+ _DraftQuery_envVarEntries.set(this, []);
50
+ _DraftQuery_jvmArguments.set(this, []);
51
+ _DraftQuery_classpathAdditions.set(this, []);
52
+ /** @deprecated Use `envVarEntries` instead. */
53
+ this.envVars = '';
54
+ /** @deprecated Use `jvmArguments` instead. */
55
+ this.jvmArgs = '';
56
+ /** @deprecated Use `classpathAdditions` instead. */
57
+ this.extraClasspaths = '';
30
58
  this.scheduling = [];
31
59
  // Meta Data
32
60
  this.id = nanoid();
@@ -40,13 +68,26 @@ export class DraftQuery {
40
68
  this.type = type;
41
69
  this.enabled = enabled;
42
70
  this.enableGcLogs = enableGcLogs;
43
- this.envVars = envVars;
71
+ if (envVarEntries != null) {
72
+ this.envVarEntries = envVarEntries.slice();
73
+ }
74
+ else {
75
+ try {
76
+ this.envVarEntries = splitEnvVarEntries(envVars);
77
+ }
78
+ catch (e) {
79
+ this.envVarEntries = [];
80
+ }
81
+ }
44
82
  this.heapSize = heapSize;
45
83
  this.replicaCount = replicaCount;
46
84
  this.spareCount = spareCount;
47
85
  this.additionalMemory = additionalMemory;
48
86
  this.dataMemoryRatio = dataMemoryRatio;
49
- this.extraClasspaths = extraClasspaths;
87
+ this.classpathAdditions =
88
+ classpathAdditions != null
89
+ ? classpathAdditions.slice()
90
+ : splitClasspathAdditions(extraClasspaths);
50
91
  this.jvmProfile = jvmProfile;
51
92
  this.dbServerName = dbServerName;
52
93
  this.scriptLanguage = scriptLanguage;
@@ -66,12 +107,13 @@ export class DraftQuery {
66
107
  this.assignmentPolicyParams = assignmentPolicyParams;
67
108
  // If the thread counts are not provided, they are read from the JVM args
68
109
  // And they need to be removed from the JVM args
110
+ const jvmArgsArray = jvmArguments !== null && jvmArguments !== void 0 ? jvmArguments : tokenizeArgs(jvmArgs);
69
111
  this.initializationThreads =
70
- initializationThreads !== null && initializationThreads !== void 0 ? initializationThreads : WorkerThreadUtils.getDisplayStringFromJvmArgs(jvmArgs, WorkerThreadUtils.INITIALIZATION_THREADS_ARG);
112
+ initializationThreads !== null && initializationThreads !== void 0 ? initializationThreads : WorkerThreadUtils.getDisplayStringFromJvmArgs(jvmArgsArray, WorkerThreadUtils.INITIALIZATION_THREADS_ARG);
71
113
  this.updateThreads =
72
- updateThreads !== null && updateThreads !== void 0 ? updateThreads : WorkerThreadUtils.getDisplayStringFromJvmArgs(jvmArgs, WorkerThreadUtils.UPDATE_THREADS_ARG);
114
+ updateThreads !== null && updateThreads !== void 0 ? updateThreads : WorkerThreadUtils.getDisplayStringFromJvmArgs(jvmArgsArray, WorkerThreadUtils.UPDATE_THREADS_ARG);
73
115
  // The thread count args should always be removed from the JVM args as they are stored in the DraftQuery
74
- this.jvmArgs = WorkerThreadUtils.removeArgs(jvmArgs);
116
+ this.jvmArguments = WorkerThreadUtils.removeArgs(jvmArgsArray);
75
117
  // The scheduling array is parsed into a scheduler object
76
118
  this.scheduling = [];
77
119
  this.scheduler = new QueryScheduler(scheduling);
@@ -80,6 +122,31 @@ export class DraftQuery {
80
122
  // A copy should have defaults that need to be instantiated as a new DraftQuery
81
123
  this.defaults = defaults == null ? undefined : new DraftQuery(defaults);
82
124
  }
125
+ // The setters below keep the deprecated string fields in sync with their array replacements.
126
+ // This is for backwards compatibility with the old JS API which uses the deprecated fields.
127
+ // When the deprecated fields (envVars, jvmArgs, extraClasspaths) are removed, these can be
128
+ // replaced with plain properties.
129
+ get envVarEntries() {
130
+ return __classPrivateFieldGet(this, _DraftQuery_envVarEntries, "f");
131
+ }
132
+ set envVarEntries(value) {
133
+ __classPrivateFieldSet(this, _DraftQuery_envVarEntries, value, "f");
134
+ this.envVars = joinEnvVarEntries(value);
135
+ }
136
+ get jvmArguments() {
137
+ return __classPrivateFieldGet(this, _DraftQuery_jvmArguments, "f");
138
+ }
139
+ set jvmArguments(value) {
140
+ __classPrivateFieldSet(this, _DraftQuery_jvmArguments, value, "f");
141
+ this.jvmArgs = value.join(' ');
142
+ }
143
+ get classpathAdditions() {
144
+ return __classPrivateFieldGet(this, _DraftQuery_classpathAdditions, "f");
145
+ }
146
+ set classpathAdditions(value) {
147
+ __classPrivateFieldSet(this, _DraftQuery_classpathAdditions, value, "f");
148
+ this.extraClasspaths = joinClasspathAdditions(value);
149
+ }
83
150
  updateSchedule() {
84
151
  if (this.scheduler != null) {
85
152
  this.scheduling = this.scheduler.toStringArray();
@@ -117,12 +184,12 @@ export class DraftQuery {
117
184
  type: this.type,
118
185
  enabled: this.enabled,
119
186
  enableGcLogs: this.enableGcLogs,
120
- envVars: this.envVars,
187
+ envVarEntries: this.envVarEntries,
121
188
  heapSize: this.heapSize,
122
189
  dataMemoryRatio: this.dataMemoryRatio,
123
190
  additionalMemory: this.additionalMemory,
124
- jvmArgs: this.jvmArgs,
125
- extraClasspaths: this.extraClasspaths,
191
+ jvmArguments: this.jvmArguments,
192
+ classpathAdditions: this.classpathAdditions,
126
193
  jvmProfile: this.jvmProfile,
127
194
  dbServerName: this.dbServerName,
128
195
  scriptLanguage: this.scriptLanguage,
@@ -155,7 +222,7 @@ export class DraftQuery {
155
222
  */
156
223
  addThreadCountToJVMArgs() {
157
224
  const { initializationThreads, updateThreads } = this;
158
- this.jvmArgs = WorkerThreadUtils.addArgs(this.jvmArgs, initializationThreads, updateThreads);
225
+ this.jvmArguments = WorkerThreadUtils.addArgs(this.jvmArguments, initializationThreads, updateThreads);
159
226
  }
160
227
  /**
161
228
  * Get a PlainEditableQueryInfo object populated from this DraftQuery
@@ -194,6 +261,7 @@ export class DraftQuery {
194
261
  return `${DRAFT_SERIAL_PREFIX}${this.id}`;
195
262
  }
196
263
  }
264
+ _DraftQuery_envVarEntries = new WeakMap(), _DraftQuery_jvmArguments = new WeakMap(), _DraftQuery_classpathAdditions = new WeakMap();
197
265
  DraftQuery.NO_SERIAL = null;
198
266
  DraftQuery.INVALID_SCRIPT_PATH = '';
199
267
  DraftQuery.RESTART_MODE = Object.freeze({
@@ -208,11 +276,14 @@ DraftQuery.FIELDS = Object.freeze({
208
276
  TYPE: 'type',
209
277
  ENABLED: 'enabled',
210
278
  ENABLED_GC_LOGS: 'enableGcLogs',
279
+ /** @deprecated Use ENV_VAR_ENTRIES */
211
280
  ENV_VARS: 'envVars',
212
281
  HEAP_SIZE: 'heapSize',
213
282
  ADDITIONAL_MEMORY: 'additionalMemory',
214
283
  DATA_MEMORY_RATIO: 'dataMemoryRatio',
284
+ /** @deprecated Use JVM_ARGUMENTS */
215
285
  JVM_ARGS: 'jvmArgs',
286
+ /** @deprecated Use CLASSPATH_ADDITIONS */
216
287
  EXTRA_CLASSPATHS: 'extraClasspaths',
217
288
  JVM_PROFILE: 'jvmProfile',
218
289
  DB_SERVER_NAME: 'dbServerName',
@@ -236,5 +307,8 @@ DraftQuery.FIELDS = Object.freeze({
236
307
  INITIALIZATION_THREADS: 'initializationThreads',
237
308
  UPDATE_THREADS: 'updateThreads',
238
309
  DEFAULTS: 'defaults',
310
+ ENV_VAR_ENTRIES: 'envVarEntries',
311
+ JVM_ARGUMENTS: 'jvmArguments',
312
+ CLASSPATH_ADDITIONS: 'classpathAdditions',
239
313
  });
240
314
  export default DraftQuery;
@@ -20,11 +20,11 @@ export function getPlainEditableQueryInfo(query) {
20
20
  dbServerName: query.dbServerName,
21
21
  enabled: query.enabled,
22
22
  enableGcLogs: query.enableGcLogs,
23
- envVars: query.envVars,
24
- extraClasspaths: query.extraClasspaths,
23
+ envVarEntries: [...query.envVarEntries],
24
+ classpathAdditions: [...query.classpathAdditions],
25
25
  heapSize: query.heapSize,
26
26
  additionalMemory: query.additionalMemory,
27
- jvmArgs: query.jvmArgs,
27
+ jvmArguments: [...query.jvmArguments],
28
28
  jvmProfile: query.jvmProfile,
29
29
  name: query.name,
30
30
  owner: query.owner,
@@ -14,7 +14,6 @@ import Log from '@deephaven/log';
14
14
  import { nanoid } from 'nanoid';
15
15
  import QueryScheduler from './QueryScheduler';
16
16
  import DraftQuery from './DraftQuery';
17
- import { WorkerThreadUtils } from './WorkerThreadUtils';
18
17
  import { QueryStatus } from './QueryStatus';
19
18
  const log = Log.module('QueryUtils');
20
19
  // 600 seconds is based on default `auto_delete_timeout` in
@@ -71,16 +70,9 @@ export function createTemporaryDraftQuery(_a) {
71
70
  heapSize,
72
71
  isClientSide,
73
72
  scheduling,
74
- timeout, workerKind: engine,
75
- // TODO: DH-22081: createTemporaryDraftQuery converts initializationThreads/
76
- // updateThreads with WorkerThreadUtils.getValue(...) before storing them on
77
- // the DraftQuery. DraftQuery later calls WorkerThreadUtils.addArgs, which
78
- // expects display strings
79
- initializationThreads: isCommunityWorker && initializationThreads != null
80
- ? WorkerThreadUtils.getValue(initializationThreads)
81
- : undefined, updateThreads: isCommunityWorker && updateThreads != null
82
- ? WorkerThreadUtils.getValue(updateThreads)
83
- : undefined }));
73
+ timeout, workerKind: engine, initializationThreads: isCommunityWorker
74
+ ? initializationThreads
75
+ : undefined, updateThreads: isCommunityWorker ? updateThreads : undefined }));
84
76
  draftQuery.addThreadCountToJVMArgs();
85
77
  draftQuery.updateSchedule();
86
78
  return draftQuery;
@@ -21,27 +21,27 @@ export declare abstract class WorkerThreadUtils {
21
21
  /**
22
22
  * Gets the display string for the provided JVM arguments and argument name.
23
23
  *
24
- * @param jvmArgs the JVM arguments
24
+ * @param jvmArgs the JVM arguments array
25
25
  * @param argName the name of the argument to search for
26
26
  * @returns the display string or the system default string if not found
27
27
  */
28
- static getDisplayStringFromJvmArgs(jvmArgs: string, argName: string): string;
28
+ static getDisplayStringFromJvmArgs(jvmArgs: string[], argName: string): string;
29
29
  /**
30
- * Removes the thread count arguments from the provided jvmArgs string.
30
+ * Removes the thread count arguments from the provided jvmArgs array.
31
31
  *
32
- * @param jvmArgs the string containing JVM arguments
33
- * @returns a new string with the thread count arguments removed
32
+ * @param jvmArgs the array of JVM arguments
33
+ * @returns a new array with the thread count arguments removed
34
34
  */
35
- static removeArgs(jvmArgs: string): string;
35
+ static removeArgs(jvmArgs: string[]): string[];
36
36
  /**
37
- * Adds the thread count arguments to the provided jvmArgs string.
37
+ * Adds the thread count arguments to the provided jvmArgs array.
38
38
  *
39
- * @param jvmArgs the string containing JVM arguments
39
+ * @param jvmArgs the array of JVM arguments
40
40
  * @param initializationThreads the display string for the initialization threads
41
41
  * @param updateThreads the display string for the update threads
42
- * @returns the new string with the thread count arguments added
42
+ * @returns a new array with the thread count arguments added
43
43
  */
44
- static addArgs(jvmArgs: string, initializationThreads: string, updateThreads: string): string;
44
+ static addArgs(jvmArgs: string[], initializationThreads: string, updateThreads: string): string[];
45
45
  /**
46
46
  * Gets the display string for the provided value.
47
47
  *
@@ -1,4 +1,3 @@
1
- import { tokenizeArgs } from './ArgumentUtils';
2
1
  /**
3
2
  * Utility class for managing worker thread configuration arguments.
4
3
  */
@@ -18,50 +17,48 @@ export class WorkerThreadUtils {
18
17
  /**
19
18
  * Gets the display string for the provided JVM arguments and argument name.
20
19
  *
21
- * @param jvmArgs the JVM arguments
20
+ * @param jvmArgs the JVM arguments array
22
21
  * @param argName the name of the argument to search for
23
22
  * @returns the display string or the system default string if not found
24
23
  */
25
24
  static getDisplayStringFromJvmArgs(jvmArgs, argName) {
26
- const args = tokenizeArgs(jvmArgs);
27
- for (let i = 0; i < args.length; i += 1) {
28
- if (args[i].startsWith(`-D${argName}=`)) {
29
- return WorkerThreadUtils.getDisplayString(args[i].split('=')[1]);
25
+ for (let i = 0; i < jvmArgs.length; i += 1) {
26
+ if (jvmArgs[i].startsWith(`-D${argName}=`)) {
27
+ return WorkerThreadUtils.getDisplayString(jvmArgs[i].split('=')[1]);
30
28
  }
31
29
  }
32
30
  // If the value is not found, return the system default string
33
31
  return WorkerThreadUtils.SYSTEM_DEFAULT_STRING;
34
32
  }
35
33
  /**
36
- * Removes the thread count arguments from the provided jvmArgs string.
34
+ * Removes the thread count arguments from the provided jvmArgs array.
37
35
  *
38
- * @param jvmArgs the string containing JVM arguments
39
- * @returns a new string with the thread count arguments removed
36
+ * @param jvmArgs the array of JVM arguments
37
+ * @returns a new array with the thread count arguments removed
40
38
  */
41
39
  static removeArgs(jvmArgs) {
42
- const args = tokenizeArgs(jvmArgs);
43
- const filteredArgs = args.filter(arg => !WorkerThreadUtils.ALL_ARGS.some(argName => arg.startsWith(`-D${argName}=`)));
44
- return filteredArgs.join(' ');
40
+ return jvmArgs.filter(arg => !WorkerThreadUtils.ALL_ARGS.some(argName => arg.startsWith(`-D${argName}=`)));
45
41
  }
46
42
  /**
47
- * Adds the thread count arguments to the provided jvmArgs string.
43
+ * Adds the thread count arguments to the provided jvmArgs array.
48
44
  *
49
- * @param jvmArgs the string containing JVM arguments
45
+ * @param jvmArgs the array of JVM arguments
50
46
  * @param initializationThreads the display string for the initialization threads
51
47
  * @param updateThreads the display string for the update threads
52
- * @returns the new string with the thread count arguments added
48
+ * @returns a new array with the thread count arguments added
53
49
  */
54
50
  static addArgs(jvmArgs, initializationThreads, updateThreads) {
51
+ const result = [...jvmArgs];
55
52
  // The default value means "do not set an extra JVM arg"
56
53
  if (WorkerThreadUtils.isValidThreadCount(initializationThreads) &&
57
54
  initializationThreads !== WorkerThreadUtils.SYSTEM_DEFAULT_STRING) {
58
- jvmArgs += ` -D${WorkerThreadUtils.INITIALIZATION_THREADS_ARG}=${WorkerThreadUtils.getValue(initializationThreads)}`;
55
+ result.push(`-D${WorkerThreadUtils.INITIALIZATION_THREADS_ARG}=${WorkerThreadUtils.getValue(initializationThreads)}`);
59
56
  }
60
57
  if (WorkerThreadUtils.isValidThreadCount(updateThreads) &&
61
58
  updateThreads !== WorkerThreadUtils.SYSTEM_DEFAULT_STRING) {
62
- jvmArgs += ` -D${WorkerThreadUtils.UPDATE_THREADS_ARG}=${WorkerThreadUtils.getValue(updateThreads)}`;
59
+ result.push(`-D${WorkerThreadUtils.UPDATE_THREADS_ARG}=${WorkerThreadUtils.getValue(updateThreads)}`);
63
60
  }
64
- return jvmArgs.trim();
61
+ return result;
65
62
  }
66
63
  /**
67
64
  * Gets the display string for the provided value.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deephaven-enterprise/query-utils",
3
- "version": "2026.1.40",
3
+ "version": "2026.1.42",
4
4
  "description": "Deephaven Enterprise Query Utils",
5
5
  "author": "Deephaven Data Labs LLC",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
@@ -17,14 +17,18 @@
17
17
  "build": "tsc --build"
18
18
  },
19
19
  "dependencies": {
20
- "@deephaven/jsapi-types": "^1.0.0-dev0.36.1",
21
20
  "@deephaven-enterprise/jsapi-types": "file:../jsapi-types",
21
+ "@deephaven/jsapi-types": "^1.0.0-dev0.36.1",
22
22
  "@deephaven/log": "^0.97.0",
23
23
  "@deephaven/utils": "^0.97.0",
24
24
  "@internationalized/date": "^3.12.2",
25
- "nanoid": "^5.1.6"
25
+ "nanoid": "^5.1.6",
26
+ "shell-quote": "^1.8.4"
26
27
  },
27
28
  "publishConfig": {
28
29
  "access": "public"
30
+ },
31
+ "devDependencies": {
32
+ "@types/shell-quote": "^1.7.5"
29
33
  }
30
34
  }