stone-lang 0.1.0
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/README.md +52 -0
- package/StoneEngine.js +879 -0
- package/StoneEngineService.js +1727 -0
- package/adapters/FileSystemAdapter.js +230 -0
- package/adapters/OutputAdapter.js +208 -0
- package/adapters/index.js +6 -0
- package/cli/CLIOutputAdapter.js +196 -0
- package/cli/DaemonClient.js +349 -0
- package/cli/JSONOutputAdapter.js +135 -0
- package/cli/ReplSession.js +567 -0
- package/cli/ViewerServer.js +590 -0
- package/cli/commands/check.js +84 -0
- package/cli/commands/daemon.js +189 -0
- package/cli/commands/kill.js +66 -0
- package/cli/commands/package.js +713 -0
- package/cli/commands/ps.js +65 -0
- package/cli/commands/run.js +537 -0
- package/cli/entry.js +169 -0
- package/cli/index.js +14 -0
- package/cli/stonec.js +358 -0
- package/cli/test-compiler.js +181 -0
- package/cli/viewer/index.html +495 -0
- package/daemon/IPCServer.js +455 -0
- package/daemon/ProcessManager.js +327 -0
- package/daemon/ProcessRunner.js +307 -0
- package/daemon/daemon.js +398 -0
- package/daemon/index.js +16 -0
- package/frontend/analysis/index.js +5 -0
- package/frontend/analysis/livenessAnalyzer.js +568 -0
- package/frontend/analysis/treeShaker.js +265 -0
- package/frontend/index.js +20 -0
- package/frontend/parsing/astBuilder.js +2196 -0
- package/frontend/parsing/index.js +7 -0
- package/frontend/parsing/sonParser.js +592 -0
- package/frontend/parsing/stoneAstTypes.js +703 -0
- package/frontend/parsing/terminal-registry.js +435 -0
- package/frontend/parsing/tokenizer.js +692 -0
- package/frontend/type-checker/OverloadedFunctionType.js +43 -0
- package/frontend/type-checker/TypeEnvironment.js +165 -0
- package/frontend/type-checker/bidirectionalInference.js +149 -0
- package/frontend/type-checker/index.js +10 -0
- package/frontend/type-checker/moduleAnalysis.js +248 -0
- package/frontend/type-checker/operatorMappings.js +35 -0
- package/frontend/type-checker/overloadResolution.js +605 -0
- package/frontend/type-checker/typeChecker.js +452 -0
- package/frontend/type-checker/typeCompatibility.js +389 -0
- package/frontend/type-checker/visitors/controlFlow.js +483 -0
- package/frontend/type-checker/visitors/functions.js +604 -0
- package/frontend/type-checker/visitors/index.js +38 -0
- package/frontend/type-checker/visitors/literals.js +341 -0
- package/frontend/type-checker/visitors/modules.js +159 -0
- package/frontend/type-checker/visitors/operators.js +109 -0
- package/frontend/type-checker/visitors/statements.js +768 -0
- package/frontend/types/index.js +5 -0
- package/frontend/types/operatorMap.js +134 -0
- package/frontend/types/types.js +2046 -0
- package/frontend/utils/errorCollector.js +244 -0
- package/frontend/utils/index.js +5 -0
- package/frontend/utils/moduleResolver.js +479 -0
- package/package.json +50 -0
- package/packages/browserCache.js +359 -0
- package/packages/fetcher.js +236 -0
- package/packages/index.js +130 -0
- package/packages/lockfile.js +271 -0
- package/packages/manifest.js +291 -0
- package/packages/packageResolver.js +356 -0
- package/packages/resolver.js +310 -0
- package/packages/semver.js +635 -0
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Registry
|
|
3
|
+
*
|
|
4
|
+
* Provides terminal handle class and constructor factories for Stone terminals.
|
|
5
|
+
* Terminals are first-class runtime objects that represent output channels
|
|
6
|
+
* (2D graphs, 3D scenes).
|
|
7
|
+
*
|
|
8
|
+
* Supports two modes:
|
|
9
|
+
* - Legacy: Direct executor.terminalsData mutation (backward compat)
|
|
10
|
+
* - Adapter: Stream via OutputAdapter (new CLI/daemon path)
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { StoneArray } from '../../backends/js-vm/stoneArray.js';
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// STONEARRAY CONVERSION UTILITIES
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Check if a value is a StoneArray
|
|
21
|
+
*/
|
|
22
|
+
function isStoneArray(value) {
|
|
23
|
+
return value instanceof StoneArray || value?._type === 'StoneArray';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Convert a StoneArray to a plain JavaScript array.
|
|
28
|
+
* Uses the built-in toNested() method for proper conversion.
|
|
29
|
+
*/
|
|
30
|
+
function stoneArrayToJS(arr) {
|
|
31
|
+
if (!isStoneArray(arr)) return arr;
|
|
32
|
+
|
|
33
|
+
// Use the built-in toNested() method if available (live StoneArray)
|
|
34
|
+
if (typeof arr.toNested === 'function') {
|
|
35
|
+
return arr.toNested();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Fallback: handle raw data directly
|
|
39
|
+
const data = ArrayBuffer.isView(arr.data) ? Array.from(arr.data) : arr.data;
|
|
40
|
+
|
|
41
|
+
if (arr.rank === 1) {
|
|
42
|
+
return Array.isArray(data) ? data : Array.from(data);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (arr.rank === 2) {
|
|
46
|
+
const [rows, cols] = arr.shape;
|
|
47
|
+
const result = [];
|
|
48
|
+
for (let i = 0; i < rows; i++) {
|
|
49
|
+
result.push(data.slice(i * cols, (i + 1) * cols));
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return data;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Recursively convert all StoneArrays in an object to plain JS arrays.
|
|
59
|
+
* This ensures data is stored in a format that serializes correctly to JSON
|
|
60
|
+
* and can be used directly by Plotly without further conversion.
|
|
61
|
+
*/
|
|
62
|
+
function deepConvertStoneArrays(obj) {
|
|
63
|
+
if (obj === null || obj === undefined) return obj;
|
|
64
|
+
|
|
65
|
+
// If it's a StoneArray, convert it
|
|
66
|
+
if (isStoneArray(obj)) {
|
|
67
|
+
return stoneArrayToJS(obj);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// If it's an array, recursively convert each element
|
|
71
|
+
if (Array.isArray(obj)) {
|
|
72
|
+
return obj.map(deepConvertStoneArrays);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// If it's an object, recursively convert each property
|
|
76
|
+
if (typeof obj === 'object') {
|
|
77
|
+
const result = {};
|
|
78
|
+
for (const key in obj) {
|
|
79
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
80
|
+
result[key] = deepConvertStoneArrays(obj[key]);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Primitive values pass through unchanged
|
|
87
|
+
return obj;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* TerminalHandle - Handle to a terminal instance
|
|
92
|
+
*
|
|
93
|
+
* Represents a reference to a terminal that can be used to send data
|
|
94
|
+
* via method calls: graph.add(data), graph.set(data), scene.add(obj), etc.
|
|
95
|
+
*/
|
|
96
|
+
export class TerminalHandle {
|
|
97
|
+
/**
|
|
98
|
+
* @param {string} type - Terminal type ('console', 'graph2d', 'graph3d')
|
|
99
|
+
* @param {Object} config - Terminal configuration
|
|
100
|
+
* @param {string} id - Unique terminal ID
|
|
101
|
+
* @param {Object} context - Either { executor } (legacy) or { outputAdapter } (new)
|
|
102
|
+
*/
|
|
103
|
+
constructor(type, config, id, context) {
|
|
104
|
+
this._type = 'TerminalHandle';
|
|
105
|
+
this.terminalType = type;
|
|
106
|
+
this.terminalId = id;
|
|
107
|
+
this.config = config || {};
|
|
108
|
+
this.ports = {}; // View port data (snapshots)
|
|
109
|
+
|
|
110
|
+
// Support both legacy executor mode and new adapter mode
|
|
111
|
+
if (context.outputAdapter) {
|
|
112
|
+
this.outputAdapter = context.outputAdapter;
|
|
113
|
+
this.executor = null;
|
|
114
|
+
// In adapter mode, ports are managed locally
|
|
115
|
+
this._initPorts();
|
|
116
|
+
} else if (context.executor) {
|
|
117
|
+
// Legacy mode - direct executor mutation
|
|
118
|
+
this.executor = context.executor;
|
|
119
|
+
this.outputAdapter = null;
|
|
120
|
+
} else {
|
|
121
|
+
throw new Error('TerminalHandle requires either executor or outputAdapter');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
_initPorts() {
|
|
126
|
+
switch (this.terminalType) {
|
|
127
|
+
case 'graph2d':
|
|
128
|
+
this.ports.plots = [];
|
|
129
|
+
break;
|
|
130
|
+
case 'graph3d':
|
|
131
|
+
this.ports.objects = [];
|
|
132
|
+
break;
|
|
133
|
+
case 'console':
|
|
134
|
+
this.ports.lines = [];
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
this.ports.config = { ...this.config };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Add data to the terminal's main port
|
|
142
|
+
* - graph2d: adds plot(s) to plots
|
|
143
|
+
* - graph3d: adds object(s) to objects
|
|
144
|
+
* - console: adds line(s) to lines
|
|
145
|
+
*
|
|
146
|
+
* If value is an array, adds each item. Otherwise adds the single item.
|
|
147
|
+
* StoneArrays are converted to plain JS arrays for proper JSON serialization.
|
|
148
|
+
*/
|
|
149
|
+
add(value) {
|
|
150
|
+
// Convert StoneArrays to plain JS arrays before storing
|
|
151
|
+
const converted = deepConvertStoneArrays(value);
|
|
152
|
+
const items = Array.isArray(converted) ? converted : [converted];
|
|
153
|
+
|
|
154
|
+
if (this.outputAdapter) {
|
|
155
|
+
// New adapter mode - stream via adapter
|
|
156
|
+
this.outputAdapter.addToTerminal(this.terminalId, items);
|
|
157
|
+
// Also update local ports for consistency
|
|
158
|
+
this._addToLocalPorts(items);
|
|
159
|
+
} else {
|
|
160
|
+
// Legacy mode - direct mutation
|
|
161
|
+
const terminalData = this.executor.terminalsData[this.terminalId];
|
|
162
|
+
switch (this.terminalType) {
|
|
163
|
+
case 'graph2d':
|
|
164
|
+
terminalData.plots.push(...items);
|
|
165
|
+
this.ports.plots = [...terminalData.plots];
|
|
166
|
+
break;
|
|
167
|
+
case 'graph3d':
|
|
168
|
+
terminalData.objects.push(...items);
|
|
169
|
+
this.ports.objects = [...terminalData.objects];
|
|
170
|
+
break;
|
|
171
|
+
case 'console':
|
|
172
|
+
terminalData.lines.push(...items);
|
|
173
|
+
this.ports.lines = [...terminalData.lines];
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return this; // Enable chaining
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
_addToLocalPorts(items) {
|
|
181
|
+
switch (this.terminalType) {
|
|
182
|
+
case 'graph2d':
|
|
183
|
+
this.ports.plots.push(...items);
|
|
184
|
+
break;
|
|
185
|
+
case 'graph3d':
|
|
186
|
+
this.ports.objects.push(...items);
|
|
187
|
+
break;
|
|
188
|
+
case 'console':
|
|
189
|
+
this.ports.lines.push(...items);
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Set the terminal's main port data (replaces existing)
|
|
196
|
+
* - graph2d: sets plots array
|
|
197
|
+
* - graph3d: sets objects array
|
|
198
|
+
* - console: sets lines array
|
|
199
|
+
* StoneArrays are converted to plain JS arrays for proper JSON serialization.
|
|
200
|
+
*/
|
|
201
|
+
set(value) {
|
|
202
|
+
// Convert StoneArrays to plain JS arrays before storing
|
|
203
|
+
const converted = deepConvertStoneArrays(value);
|
|
204
|
+
const arr = Array.isArray(converted) ? converted : [converted];
|
|
205
|
+
|
|
206
|
+
if (this.outputAdapter) {
|
|
207
|
+
// New adapter mode - stream via adapter
|
|
208
|
+
this.outputAdapter.setTerminal(this.terminalId, arr);
|
|
209
|
+
// Also update local ports for consistency
|
|
210
|
+
this._setLocalPorts(arr);
|
|
211
|
+
} else {
|
|
212
|
+
// Legacy mode - direct mutation
|
|
213
|
+
const terminalData = this.executor.terminalsData[this.terminalId];
|
|
214
|
+
switch (this.terminalType) {
|
|
215
|
+
case 'graph2d':
|
|
216
|
+
terminalData.plots = arr;
|
|
217
|
+
this.ports.plots = [...terminalData.plots];
|
|
218
|
+
break;
|
|
219
|
+
case 'graph3d':
|
|
220
|
+
terminalData.objects = arr;
|
|
221
|
+
this.ports.objects = [...terminalData.objects];
|
|
222
|
+
break;
|
|
223
|
+
case 'console':
|
|
224
|
+
terminalData.lines = arr;
|
|
225
|
+
this.ports.lines = [...terminalData.lines];
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return this;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
_setLocalPorts(arr) {
|
|
233
|
+
switch (this.terminalType) {
|
|
234
|
+
case 'graph2d':
|
|
235
|
+
this.ports.plots = [...arr];
|
|
236
|
+
break;
|
|
237
|
+
case 'graph3d':
|
|
238
|
+
this.ports.objects = [...arr];
|
|
239
|
+
break;
|
|
240
|
+
case 'console':
|
|
241
|
+
this.ports.lines = [...arr];
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Clear all data from the terminal's main port
|
|
248
|
+
*/
|
|
249
|
+
clear() {
|
|
250
|
+
if (this.outputAdapter) {
|
|
251
|
+
// New adapter mode - stream via adapter
|
|
252
|
+
this.outputAdapter.clearTerminal(this.terminalId);
|
|
253
|
+
// Also update local ports
|
|
254
|
+
this._clearLocalPorts();
|
|
255
|
+
} else {
|
|
256
|
+
// Legacy mode - direct mutation
|
|
257
|
+
const terminalData = this.executor.terminalsData[this.terminalId];
|
|
258
|
+
switch (this.terminalType) {
|
|
259
|
+
case 'graph2d':
|
|
260
|
+
terminalData.plots = [];
|
|
261
|
+
this.ports.plots = [];
|
|
262
|
+
break;
|
|
263
|
+
case 'graph3d':
|
|
264
|
+
terminalData.objects = [];
|
|
265
|
+
this.ports.objects = [];
|
|
266
|
+
break;
|
|
267
|
+
case 'console':
|
|
268
|
+
terminalData.lines = [];
|
|
269
|
+
this.ports.lines = [];
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return this;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
_clearLocalPorts() {
|
|
277
|
+
switch (this.terminalType) {
|
|
278
|
+
case 'graph2d':
|
|
279
|
+
this.ports.plots = [];
|
|
280
|
+
break;
|
|
281
|
+
case 'graph3d':
|
|
282
|
+
this.ports.objects = [];
|
|
283
|
+
break;
|
|
284
|
+
case 'console':
|
|
285
|
+
this.ports.lines = [];
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Custom serialization - exclude executor/adapter reference
|
|
291
|
+
toJSON() {
|
|
292
|
+
return {
|
|
293
|
+
_type: this._type,
|
|
294
|
+
terminalType: this.terminalType,
|
|
295
|
+
terminalId: this.terminalId,
|
|
296
|
+
config: this.config,
|
|
297
|
+
ports: this.ports
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Create terminal constructor functions.
|
|
304
|
+
*
|
|
305
|
+
* Supports two modes:
|
|
306
|
+
* - Legacy: Pass executor object with terminalsData and terminalCounter
|
|
307
|
+
* - Adapter: Pass object with outputAdapter and terminalCounter
|
|
308
|
+
*
|
|
309
|
+
* @param {Object} context - Either executor (legacy) or { outputAdapter, terminalCounter } (new)
|
|
310
|
+
* @returns {Object} - Object with console_terminal, graph2d, graph3d functions
|
|
311
|
+
*/
|
|
312
|
+
export function createTerminalConstructors(context) {
|
|
313
|
+
// Determine mode based on what's provided
|
|
314
|
+
// Check for both null and undefined to properly detect adapter mode
|
|
315
|
+
const isAdapterMode = context.outputAdapter != null;
|
|
316
|
+
|
|
317
|
+
// Get or create terminal counter
|
|
318
|
+
let counterRef;
|
|
319
|
+
if (isAdapterMode) {
|
|
320
|
+
// Adapter mode - counter passed in context or create new one
|
|
321
|
+
counterRef = { value: context.terminalCounter || 0 };
|
|
322
|
+
} else {
|
|
323
|
+
// Legacy mode - counter is on executor
|
|
324
|
+
counterRef = { get value() { return context.terminalCounter; }, set value(v) { context.terminalCounter = v; } };
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const getNextId = (prefix) => {
|
|
328
|
+
const id = `${prefix}_${counterRef.value}`;
|
|
329
|
+
counterRef.value++;
|
|
330
|
+
return id;
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
return {
|
|
334
|
+
console_terminal: (config = {}) => {
|
|
335
|
+
const terminalId = getNextId('console');
|
|
336
|
+
const fullConfig = {
|
|
337
|
+
title: config.title || 'Console',
|
|
338
|
+
max_lines: config.max_lines || 200,
|
|
339
|
+
...config
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
if (isAdapterMode) {
|
|
343
|
+
// New adapter mode - create via adapter
|
|
344
|
+
context.outputAdapter.createTerminal(terminalId, 'console', fullConfig);
|
|
345
|
+
return new TerminalHandle('console', fullConfig, terminalId, { outputAdapter: context.outputAdapter });
|
|
346
|
+
} else {
|
|
347
|
+
// Legacy mode - direct mutation
|
|
348
|
+
const handle = new TerminalHandle('console', fullConfig, terminalId, { executor: context });
|
|
349
|
+
context.terminalsData[terminalId] = {
|
|
350
|
+
type: 'console',
|
|
351
|
+
config: fullConfig,
|
|
352
|
+
lines: []
|
|
353
|
+
};
|
|
354
|
+
handle.ports = {
|
|
355
|
+
lines: [],
|
|
356
|
+
config: { ...fullConfig }
|
|
357
|
+
};
|
|
358
|
+
return handle;
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
|
|
362
|
+
graph2d: (config = {}) => {
|
|
363
|
+
const terminalId = getNextId('graph2d');
|
|
364
|
+
// Convert StoneArrays in config (e.g., axes.t.values) to plain JS arrays
|
|
365
|
+
const fullConfig = deepConvertStoneArrays({
|
|
366
|
+
title: config.title || 'Graph',
|
|
367
|
+
x_label: config.x_label || 'x',
|
|
368
|
+
y_label: config.y_label || 'y',
|
|
369
|
+
...config
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
if (isAdapterMode) {
|
|
373
|
+
// New adapter mode - create via adapter
|
|
374
|
+
context.outputAdapter.createTerminal(terminalId, 'graph2d', fullConfig);
|
|
375
|
+
return new TerminalHandle('graph2d', fullConfig, terminalId, { outputAdapter: context.outputAdapter });
|
|
376
|
+
} else {
|
|
377
|
+
// Legacy mode - direct mutation
|
|
378
|
+
const handle = new TerminalHandle('graph2d', fullConfig, terminalId, { executor: context });
|
|
379
|
+
context.terminalsData[terminalId] = {
|
|
380
|
+
type: 'graph2d',
|
|
381
|
+
config: fullConfig,
|
|
382
|
+
plots: []
|
|
383
|
+
};
|
|
384
|
+
handle.ports = {
|
|
385
|
+
plots: [],
|
|
386
|
+
config: { ...fullConfig }
|
|
387
|
+
};
|
|
388
|
+
return handle;
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
|
|
392
|
+
graph3d: (config = {}) => {
|
|
393
|
+
const terminalId = getNextId('graph3d');
|
|
394
|
+
// Convert StoneArrays in config (e.g., axes.t.values) to plain JS arrays
|
|
395
|
+
const fullConfig = deepConvertStoneArrays({
|
|
396
|
+
title: config.title || 'Scene',
|
|
397
|
+
...config
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
if (isAdapterMode) {
|
|
401
|
+
// New adapter mode - create via adapter
|
|
402
|
+
context.outputAdapter.createTerminal(terminalId, 'graph3d', fullConfig);
|
|
403
|
+
return new TerminalHandle('graph3d', fullConfig, terminalId, { outputAdapter: context.outputAdapter });
|
|
404
|
+
} else {
|
|
405
|
+
// Legacy mode - direct mutation
|
|
406
|
+
const handle = new TerminalHandle('graph3d', fullConfig, terminalId, { executor: context });
|
|
407
|
+
context.terminalsData[terminalId] = {
|
|
408
|
+
type: 'graph3d',
|
|
409
|
+
config: fullConfig,
|
|
410
|
+
objects: []
|
|
411
|
+
};
|
|
412
|
+
handle.ports = {
|
|
413
|
+
objects: [],
|
|
414
|
+
config: { ...fullConfig }
|
|
415
|
+
};
|
|
416
|
+
return handle;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Check if a value is a TerminalHandle
|
|
424
|
+
* @param {any} value - Value to check
|
|
425
|
+
* @returns {boolean}
|
|
426
|
+
*/
|
|
427
|
+
export function isTerminalHandle(value) {
|
|
428
|
+
return value instanceof TerminalHandle || value?._type === 'TerminalHandle';
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
export default {
|
|
432
|
+
TerminalHandle,
|
|
433
|
+
createTerminalConstructors,
|
|
434
|
+
isTerminalHandle
|
|
435
|
+
};
|