mrmd-js 2.0.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.
Files changed (52) hide show
  1. package/README.md +842 -0
  2. package/dist/index.cjs +7613 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.js +7530 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/mrmd-js.iife.js +7618 -0
  7. package/dist/mrmd-js.iife.js.map +1 -0
  8. package/package.json +47 -0
  9. package/src/analysis/format.js +371 -0
  10. package/src/analysis/index.js +18 -0
  11. package/src/analysis/is-complete.js +394 -0
  12. package/src/constants.js +44 -0
  13. package/src/execute/css.js +205 -0
  14. package/src/execute/html.js +162 -0
  15. package/src/execute/index.js +41 -0
  16. package/src/execute/interface.js +144 -0
  17. package/src/execute/javascript.js +197 -0
  18. package/src/execute/registry.js +245 -0
  19. package/src/index.js +136 -0
  20. package/src/lsp/complete.js +353 -0
  21. package/src/lsp/format.js +310 -0
  22. package/src/lsp/hover.js +126 -0
  23. package/src/lsp/index.js +55 -0
  24. package/src/lsp/inspect.js +466 -0
  25. package/src/lsp/parse.js +455 -0
  26. package/src/lsp/variables.js +283 -0
  27. package/src/runtime.js +518 -0
  28. package/src/session/console-capture.js +181 -0
  29. package/src/session/context/iframe.js +407 -0
  30. package/src/session/context/index.js +12 -0
  31. package/src/session/context/interface.js +38 -0
  32. package/src/session/context/main.js +357 -0
  33. package/src/session/index.js +16 -0
  34. package/src/session/manager.js +327 -0
  35. package/src/session/session.js +678 -0
  36. package/src/transform/async.js +133 -0
  37. package/src/transform/extract.js +251 -0
  38. package/src/transform/index.js +10 -0
  39. package/src/transform/persistence.js +176 -0
  40. package/src/types/analysis.js +24 -0
  41. package/src/types/capabilities.js +44 -0
  42. package/src/types/completion.js +47 -0
  43. package/src/types/execution.js +62 -0
  44. package/src/types/index.js +16 -0
  45. package/src/types/inspection.js +39 -0
  46. package/src/types/session.js +32 -0
  47. package/src/types/streaming.js +74 -0
  48. package/src/types/variables.js +54 -0
  49. package/src/utils/ansi-renderer.js +301 -0
  50. package/src/utils/css-applicator.js +149 -0
  51. package/src/utils/html-renderer.js +355 -0
  52. package/src/utils/index.js +25 -0
@@ -0,0 +1,283 @@
1
+ /**
2
+ * Variable Inspection
3
+ *
4
+ * Provides variable listing and detailed inspection for the
5
+ * variables panel in notebook UIs.
6
+ *
7
+ * @module lsp/variables
8
+ */
9
+
10
+ import { splitObjectPath } from './parse.js';
11
+ import {
12
+ formatValue,
13
+ formatValueShort,
14
+ getTypeName,
15
+ isExpandable,
16
+ getSizeDescription,
17
+ } from './format.js';
18
+
19
+ /**
20
+ * @typedef {import('../session/context/interface.js').ExecutionContext} ExecutionContext
21
+ * @typedef {import('../types/variables.js').VariableFilter} VariableFilter
22
+ * @typedef {import('../types/variables.js').VariableInfo} VariableInfo
23
+ * @typedef {import('../types/variables.js').VariableDetailOptions} VariableDetailOptions
24
+ * @typedef {import('../types/variables.js').VariableDetail} VariableDetail
25
+ */
26
+
27
+ /**
28
+ * List all variables in the session namespace
29
+ *
30
+ * @param {ExecutionContext} context - Execution context
31
+ * @param {VariableFilter} [filter] - Optional filter
32
+ * @returns {VariableInfo[]}
33
+ */
34
+ export function listVariables(context, filter = {}) {
35
+ const vars = context.getVariables();
36
+ const tracked = context.getTrackedVariables();
37
+
38
+ /** @type {VariableInfo[]} */
39
+ const result = [];
40
+
41
+ for (const name of tracked) {
42
+ if (!(name in vars)) continue;
43
+
44
+ const value = vars[name];
45
+
46
+ // Apply filters
47
+ if (filter.excludePrivate && name.startsWith('_')) continue;
48
+ if (filter.namePattern && !new RegExp(filter.namePattern).test(name)) continue;
49
+ if (filter.types && !filter.types.includes(getTypeName(value))) continue;
50
+
51
+ result.push(formatVariableInfo(name, value));
52
+ }
53
+
54
+ // Sort by name
55
+ result.sort((a, b) => a.name.localeCompare(b.name));
56
+
57
+ return result;
58
+ }
59
+
60
+ /**
61
+ * Get detailed information about a variable
62
+ *
63
+ * @param {string} name - Variable name
64
+ * @param {ExecutionContext} context - Execution context
65
+ * @param {VariableDetailOptions} [options]
66
+ * @returns {VariableDetail | null}
67
+ */
68
+ export function getVariableDetail(name, context, options = {}) {
69
+ let value = context.getVariable(name);
70
+
71
+ // Navigate path
72
+ if (options.path && options.path.length > 0) {
73
+ for (const key of options.path) {
74
+ if (value == null) return null;
75
+
76
+ try {
77
+ if (value instanceof Map) {
78
+ value = value.get(key);
79
+ } else {
80
+ value = /** @type {*} */ (value)[key];
81
+ }
82
+ } catch {
83
+ return null;
84
+ }
85
+ }
86
+ }
87
+
88
+ // Check if exists
89
+ if (value === undefined && !context.hasVariable(name)) {
90
+ return null;
91
+ }
92
+
93
+ const maxChildren = options.maxChildren ?? 100;
94
+ const maxValueLength = options.maxValueLength ?? 1000;
95
+
96
+ const info = formatVariableInfo(name, value);
97
+
98
+ /** @type {VariableDetail} */
99
+ const detail = {
100
+ ...info,
101
+ fullValue: formatValue(value, maxValueLength),
102
+ truncated: false,
103
+ };
104
+
105
+ // Add children for expandable values
106
+ if (isExpandable(value)) {
107
+ const children = getChildren(value);
108
+ detail.children = children.slice(0, maxChildren).map(
109
+ ([k, v]) => formatVariableInfo(k, v)
110
+ );
111
+ detail.truncated = children.length > maxChildren;
112
+
113
+ // Get methods and attributes for objects
114
+ if (typeof value === 'object' && value !== null) {
115
+ detail.methods = getMethods(value);
116
+ detail.attributes = getAttributes(value);
117
+ }
118
+ }
119
+
120
+ return detail;
121
+ }
122
+
123
+ /**
124
+ * Expand a variable by path
125
+ *
126
+ * @param {string} baseName - Base variable name
127
+ * @param {string[]} path - Path to expand
128
+ * @param {ExecutionContext} context
129
+ * @param {number} [maxChildren=100]
130
+ * @returns {VariableInfo[] | null}
131
+ */
132
+ export function expandVariable(baseName, path, context, maxChildren = 100) {
133
+ let value = context.getVariable(baseName);
134
+
135
+ if (value === undefined) return null;
136
+
137
+ // Navigate path
138
+ for (const key of path) {
139
+ if (value == null) return null;
140
+
141
+ try {
142
+ if (value instanceof Map) {
143
+ value = value.get(key);
144
+ } else {
145
+ value = /** @type {*} */ (value)[key];
146
+ }
147
+ } catch {
148
+ return null;
149
+ }
150
+ }
151
+
152
+ if (!isExpandable(value)) {
153
+ return null;
154
+ }
155
+
156
+ const children = getChildren(value);
157
+ return children.slice(0, maxChildren).map(([k, v]) => formatVariableInfo(k, v));
158
+ }
159
+
160
+ /**
161
+ * Format a variable for display
162
+ * @param {string} name
163
+ * @param {*} value
164
+ * @returns {VariableInfo}
165
+ */
166
+ export function formatVariableInfo(name, value) {
167
+ /** @type {VariableInfo} */
168
+ const info = {
169
+ name,
170
+ type: getTypeName(value),
171
+ value: formatValueShort(value, 100),
172
+ expandable: isExpandable(value),
173
+ };
174
+
175
+ // Add size info
176
+ const size = getSizeDescription(value);
177
+ if (size) {
178
+ info.size = size;
179
+ }
180
+
181
+ // Add length for arrays/strings
182
+ if (Array.isArray(value)) {
183
+ info.length = value.length;
184
+ } else if (typeof value === 'string') {
185
+ info.length = value.length;
186
+ } else if (value instanceof Map || value instanceof Set) {
187
+ info.length = value.size;
188
+ }
189
+
190
+ // Add shape for typed arrays
191
+ if (ArrayBuffer.isView(value) && 'length' in value) {
192
+ // @ts-ignore
193
+ info.length = value.length;
194
+ info.dtype = value.constructor.name.replace('Array', '').toLowerCase();
195
+ }
196
+
197
+ // Add keys preview for objects
198
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
199
+ if (!(value instanceof Map) && !(value instanceof Set) && !ArrayBuffer.isView(value)) {
200
+ info.keys = Object.keys(value).slice(0, 10);
201
+ }
202
+ }
203
+
204
+ return info;
205
+ }
206
+
207
+ /**
208
+ * Get children of an expandable value
209
+ * @param {*} value
210
+ * @returns {Array<[string, *]>}
211
+ */
212
+ export function getChildren(value) {
213
+ if (value === null || value === undefined) return [];
214
+
215
+ if (Array.isArray(value)) {
216
+ return value.map((v, i) => [String(i), v]);
217
+ }
218
+
219
+ if (value instanceof Map) {
220
+ return Array.from(value.entries()).map(([k, v]) => [String(k), v]);
221
+ }
222
+
223
+ if (value instanceof Set) {
224
+ return Array.from(value).map((v, i) => [String(i), v]);
225
+ }
226
+
227
+ if (typeof value === 'object') {
228
+ return Object.entries(value);
229
+ }
230
+
231
+ return [];
232
+ }
233
+
234
+ /**
235
+ * Get method names of an object
236
+ * @param {*} value
237
+ * @returns {string[]}
238
+ */
239
+ export function getMethods(value) {
240
+ const methods = new Set();
241
+ let obj = value;
242
+ let depth = 0;
243
+
244
+ while (obj != null && obj !== Object.prototype && depth < 3) {
245
+ for (const name of Object.getOwnPropertyNames(obj)) {
246
+ if (name === 'constructor') continue;
247
+
248
+ try {
249
+ if (typeof obj[name] === 'function') {
250
+ methods.add(name);
251
+ }
252
+ } catch {
253
+ // Skip inaccessible
254
+ }
255
+ }
256
+
257
+ obj = Object.getPrototypeOf(obj);
258
+ depth++;
259
+ }
260
+
261
+ return Array.from(methods).sort();
262
+ }
263
+
264
+ /**
265
+ * Get attribute (non-method) names of an object
266
+ * @param {*} value
267
+ * @returns {string[]}
268
+ */
269
+ export function getAttributes(value) {
270
+ const attrs = [];
271
+
272
+ for (const name of Object.getOwnPropertyNames(value)) {
273
+ try {
274
+ if (typeof value[name] !== 'function') {
275
+ attrs.push(name);
276
+ }
277
+ } catch {
278
+ // Skip inaccessible
279
+ }
280
+ }
281
+
282
+ return attrs.sort();
283
+ }