@sheetxl/runner 0.8.0-beta.2 → 0.8.0-beta.21

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/LICENSE.md CHANGED
@@ -1,11 +1,21 @@
1
- # Repository Licensing
1
+ MIT License
2
2
 
3
- SheetXL contains a mix of open-source and commercially licensed packages. Each package is individually licensed and contains its own license file.
3
+ Copyright (c) 2026-present SheetXL Inc. & Michael T. Ford
4
4
 
5
- For the specific terms and conditions applicable to a package, please see the `LICENSE.md` file located in that package's root directory.
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
6
11
 
7
- Generally, packages intended for public distribution (such as CLIs, adapters, and vanilla wrappers) are licensed under the MIT license. All other core packages are proprietary and require a commercial license for use.
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
8
14
 
9
- For more details on commercial licensing, please visit our website:
10
-
11
- https://www.sheetxl.com/docs/guides/licensing-pricing
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -58,7 +58,7 @@ import Runner, { type RunContext } from '@sheetxl/runner';
58
58
 
59
59
  export default async function main(ctx: RunContext) {
60
60
  const { wb, log, args } = ctx;
61
- wb.getSelectedSheet().getRange('A1').setValue(args.region);
61
+ wb.getWorksheet().getRange('A1').setValue(args.region);
62
62
  log('updated value');
63
63
  }
64
64
  ```
@@ -1,31 +1,31 @@
1
1
  /**
2
- * @license @sheetxl/runner - SheetXL - Programmatic execution for SheetXL scripts - v0.8.0-beta.2
2
+ * @license @sheetxl/runner - SheetXL - Programmatic execution for SheetXL scripts - v0.8.0-beta.21
3
3
  *
4
4
  * (C) 2026-present SheetXL Inc. & Michael T. Ford
5
- * License: The license can be found at https://www.sheetxl.com/license.
5
+ * License: MIT
6
6
  */
7
7
  import t from "node:path";
8
8
  import e from "node:fs";
9
9
  import { pathToFileURL as n } from "node:url";
10
10
  import { createLogChannels as r, resolveLogTimeout as s } from "@sheetxl/utils";
11
- var o = Object.defineProperty;
12
- function i(e, n = "SHEETXL_IN") {
11
+ var i = Object.defineProperty;
12
+ function o(e, n = "SHEETXL_IN") {
13
13
  if (t.isAbsolute(e)) return e;
14
14
  const r = n ? process.env[n] : void 0;
15
15
  return t.resolve(r ?? process.cwd(), e);
16
16
  }
17
17
  var a = ((t, e) => {
18
18
  let n = {};
19
- for (var r in t) o(n, r, {
19
+ for (var r in t) i(n, r, {
20
20
  get: t[r],
21
21
  enumerable: !0
22
22
  });
23
- return e || o(n, Symbol.toStringTag, { value: "Module" }), n;
23
+ return e || i(n, Symbol.toStringTag, { value: "Module" }), n;
24
24
  })({
25
- DEFAULT_DESCRIPTION: () => S,
26
- classify: () => x,
27
- prepare: () => E,
28
- toSnippetOffset: () => _
25
+ DEFAULT_DESCRIPTION: () => v,
26
+ classify: () => w,
27
+ prepare: () => T,
28
+ toSnippetOffset: () => b
29
29
  }), c = null;
30
30
  function l() {
31
31
  return c || (c = (async () => {
@@ -51,17 +51,17 @@ function p(t) {
51
51
  for (let n = 0; n < t.length; n++) "\n" === t[n] && e++;
52
52
  return e;
53
53
  }
54
- function f(t, e, n) {
54
+ function d(t, e, n) {
55
55
  let r = n.getStart(e);
56
56
  for (const s of n.declarationList.declarations) {
57
57
  const n = s.initializer;
58
58
  if (!n) continue;
59
- const o = n.getStart(e);
60
- t.copy(r, o), t.add("await ("), t.copy(o, n.end), t.add(")"), r = n.end;
59
+ const i = n.getStart(e);
60
+ t.copy(r, i), t.add("await ("), t.copy(i, n.end), t.add(")"), r = n.end;
61
61
  }
62
62
  t.copy(r, n.end), t.terminate();
63
63
  }
64
- var d = class {
64
+ var f = class {
65
65
  constructor(t) {
66
66
  this._code = t, this.spans = [], this._parts = [], this._length = 0;
67
67
  }
@@ -81,8 +81,12 @@ var d = class {
81
81
  toString() {
82
82
  return this._parts.join("");
83
83
  }
84
- }, m = "await wb?.whenCalculationReady?.(); ";
85
- function h(t, e) {
84
+ }, m = /* @__PURE__ */ new Set([
85
+ "log",
86
+ "warn",
87
+ "error"
88
+ ]), h = "await wb?.whenCalculationReady?.(); ";
89
+ function g(t, e) {
86
90
  const n = e.statements;
87
91
  let r = n.length - 1;
88
92
  for (; r >= 0 && n[r].kind === t.SyntaxKind.EmptyStatement;) r--;
@@ -97,8 +101,8 @@ function h(t, e) {
97
101
  to: s.expression.end
98
102
  };
99
103
  if (t.isFunctionDeclaration(s) && s.body) {
100
- const n = t.getModifiers(s) ?? [], o = n.some((e) => e.kind === t.SyntaxKind.ExportKeyword);
101
- if (n.some((e) => e.kind === t.SyntaxKind.DefaultKeyword) && !s.name || !o && function(t, e) {
104
+ const n = t.getModifiers(s) ?? [], i = n.some((e) => e.kind === t.SyntaxKind.ExportKeyword);
105
+ if (n.some((e) => e.kind === t.SyntaxKind.DefaultKeyword) && !s.name || !i && function(t, e) {
102
106
  let n = -1;
103
107
  for (let r = 0; r < e.statements.length; r++) {
104
108
  const s = e.statements[r];
@@ -109,20 +113,20 @@ function h(t, e) {
109
113
  }
110
114
  return n;
111
115
  }(t, e) === r) {
112
- let o = s.getStart(e);
113
- for (const e of n) e.kind !== t.SyntaxKind.ExportKeyword && e.kind !== t.SyntaxKind.DefaultKeyword || (o = e.end);
114
- for (; o < s.end && /\s/.test(e.text[o]);) o++;
116
+ let i = s.getStart(e);
117
+ for (const e of n) e.kind !== t.SyntaxKind.ExportKeyword && e.kind !== t.SyntaxKind.DefaultKeyword || (i = e.end);
118
+ for (; i < s.end && /\s/.test(e.text[i]);) i++;
115
119
  return {
116
120
  index: r,
117
- from: o,
121
+ from: i,
118
122
  to: s.end
119
123
  };
120
124
  }
121
125
  }
122
126
  return null;
123
127
  }
124
- var y = "const __entry: (ctx: SheetXL.IScript.ScriptContext) => unknown = (", g = (t) => `); ${t} = await __entry(ctx);`;
125
- async function x(t) {
128
+ var y = "const __entry: (ctx: SheetXL.IScript.ScriptContext) => unknown = (", x = (t) => `); ${t} = await __entry(ctx);`;
129
+ async function w(t) {
126
130
  const e = await u(t);
127
131
  if (!e) return function(t) {
128
132
  return /^\s*export\s+default\b/m.test(t) || /^\s*export\s*\{[^}]*\bas\s+default\b/m.test(t);
@@ -136,11 +140,11 @@ async function x(t) {
136
140
  }
137
141
  return !1;
138
142
  }(n, r) && !function(t, e) {
139
- const n = h(t, e);
143
+ const n = g(t, e);
140
144
  return !!n && e.statements.every((e, r) => r === n.index || !t.isExportAssignment(e) && !t.isExportDeclaration(e) && !(t.canHaveModifiers(e) && t.getModifiers(e)?.some((e) => e.kind === t.SyntaxKind.ExportKeyword)));
141
145
  }(n, r) ? "script" : "snippet";
142
146
  }
143
- var w = 3, S = "Run Snippet", v = (t, e, n = [], r) => {
147
+ var S = 3, v = "Run Snippet", E = (t, e, n = [], r) => {
144
148
  const s = [
145
149
  ...n,
146
150
  ...r ? [r] : [],
@@ -158,93 +162,103 @@ var w = 3, S = "Run Snippet", v = (t, e, n = [], r) => {
158
162
  bodyStart: s.length
159
163
  };
160
164
  };
161
- async function E(t, e) {
165
+ async function T(t, e) {
162
166
  const n = e?.epilogue ?? " return __result;", r = await u(t);
163
167
  if (!r) {
164
- const e = await l() ? void 0 : "TypeScript is unavailable, so this snippet ran without implicit await or a result value. Install the `typescript` peer dependency to restore them.", { source: r, bodyStart: s } = v(t, n);
168
+ const e = await l() ? void 0 : "TypeScript is unavailable, so this snippet ran without implicit await or a result value. Install the `typescript` peer dependency to restore them.", { source: r, bodyStart: s } = E(t, n);
165
169
  return {
166
170
  source: r,
167
171
  kind: "verbatim",
168
- lineOffset: w,
172
+ lineOffset: S,
169
173
  spans: [{
170
174
  at: s,
171
175
  from: 0,
172
176
  length: t.length
173
177
  }],
178
+ expectsValue: !1,
174
179
  warning: e
175
180
  };
176
181
  }
177
- const { ts: s, sf: o } = r, i = o.statements, a = function(t, e) {
182
+ const { ts: s, sf: i } = r, o = i.statements, a = function(t, e) {
178
183
  if (!e.statements[0]) return;
179
184
  const n = t.getLeadingCommentRanges(e.text, 0);
180
185
  if (n?.length) for (let r = n.length - 1; r >= 0; r--) {
181
186
  const s = n[r];
182
187
  if (s.kind !== t.SyntaxKind.MultiLineCommentTrivia) continue;
183
- const o = e.text.slice(s.pos, s.end);
184
- if (o.startsWith("/**")) return o;
188
+ const i = e.text.slice(s.pos, s.end);
189
+ if (i.startsWith("/**")) return i;
185
190
  }
186
- }(s, o), c = a ? p(a) + 1 : 0;
187
- if (1 === i.length && s.isBlock(i[0])) {
188
- const { source: r, bodyStart: s } = v(` __result = await (
191
+ }(s, i), c = a ? p(a) + 1 : 0;
192
+ if (1 === o.length && s.isBlock(o[0])) {
193
+ const { source: r, bodyStart: s } = E(` __result = await (
189
194
  ${t}\n );`, n, [], a);
190
195
  return {
191
196
  source: r,
192
197
  kind: "expression",
193
- lineOffset: w + c + 1,
198
+ lineOffset: S + c + 1,
194
199
  spans: [{
195
200
  at: s + 21,
196
201
  from: 0,
197
202
  length: t.length
198
- }]
203
+ }],
204
+ expectsValue: !0
199
205
  };
200
206
  }
201
- const { body: x, spans: S, hoisted: E } = function(t, e, n) {
207
+ const { body: w, spans: v, hoisted: T, expectsValue: b } = function(t, e, n) {
202
208
  const r = e.text, s = e.statements;
203
- let o = -1;
209
+ let i = -1;
204
210
  for (let e = s.length - 1; e >= 0; e--) if (s[e].kind !== t.SyntaxKind.EmptyStatement) {
205
- t.isExpressionStatement(s[e]) && (o = e);
211
+ t.isExpressionStatement(s[e]) && (i = e);
206
212
  break;
207
213
  }
208
- const i = h(t, e), a = [], c = new d(r);
209
- let l = 0, u = !1;
210
- for (let d = 0; d < s.length; d++) {
211
- const h = s[d], x = h.getStart(e);
212
- if (c.copy(l, x), l = h.end, t.isImportDeclaration(h) || t.isImportEqualsDeclaration(h)) {
213
- const t = r.slice(x, h.end);
214
- a.push({
214
+ const o = g(t, e);
215
+ let a = !1;
216
+ if (!o && -1 !== i) {
217
+ const e = s[i].expression;
218
+ a = !(t.isCallExpression(e) && t.isIdentifier(e.expression) && m.has(e.expression.text));
219
+ }
220
+ const c = [], l = new f(r);
221
+ let u = 0, w = !1;
222
+ for (let a = 0; a < s.length; a++) {
223
+ const f = s[a], m = f.getStart(e);
224
+ if (l.copy(u, m), u = f.end, t.isImportDeclaration(f) || t.isImportEqualsDeclaration(f)) {
225
+ const t = r.slice(m, f.end);
226
+ c.push({
215
227
  text: t,
216
- from: x
217
- }), c.add("\n".repeat(p(t)));
228
+ from: m
229
+ }), l.add("\n".repeat(p(t)));
218
230
  continue;
219
231
  }
220
- u && c.add(m), u = !0, i?.index !== d ? t.isVariableStatement(h) ? f(c, e, h) : t.isExpressionStatement(h) ? (c.add(d === o ? `${n} = await (` : "await ("), c.copy(h.expression.getStart(e), h.expression.end), c.add(");")) : (c.copy(x, h.end), c.terminate()) : (c.add(y), c.copy(i.from, i.to), c.add(g(n)));
232
+ w && l.add(h), w = !0, o?.index !== a ? t.isVariableStatement(f) ? d(l, e, f) : t.isExpressionStatement(f) ? (l.add(a === i ? `${n} = await (` : "await ("), l.copy(f.expression.getStart(e), f.expression.end), l.add(");")) : (l.copy(m, f.end), l.terminate()) : (l.add(y), l.copy(o.from, o.to), l.add(x(n)));
221
233
  }
222
- return c.copy(l, r.length), {
223
- body: c.toString(),
224
- spans: c.spans,
225
- hoisted: a
234
+ return l.copy(u, r.length), {
235
+ body: l.toString(),
236
+ spans: l.spans,
237
+ hoisted: c,
238
+ expectsValue: a
226
239
  };
227
- }(s, o, "__result"), _ = E.map((t) => t.text), b = E.length > 0 ? p(_.join("\n")) + E.length : 0, { source: k, bodyStart: K } = v(x, n, _, a);
228
- let D = 0;
229
- const R = E.map((t) => {
240
+ }(s, i, "__result"), _ = T.map((t) => t.text), k = T.length > 0 ? p(_.join("\n")) + T.length : 0, { source: D, bodyStart: K } = E(w, n, _, a);
241
+ let R = 0;
242
+ const I = T.map((t) => {
230
243
  const e = {
231
- at: D,
244
+ at: R,
232
245
  from: t.from,
233
246
  length: t.text.length
234
247
  };
235
- return D += t.text.length + 1, e;
248
+ return R += t.text.length + 1, e;
236
249
  });
237
250
  return {
238
- source: k,
251
+ source: D,
239
252
  kind: "statements",
240
- lineOffset: w + b + c,
241
- spans: [...R, ...S.map((t) => ({
253
+ lineOffset: S + k + c,
254
+ spans: [...I, ...v.map((t) => ({
242
255
  ...t,
243
256
  at: t.at + K
244
- }))]
257
+ }))],
258
+ expectsValue: b
245
259
  };
246
260
  }
247
- function _(t, e) {
261
+ function b(t, e) {
248
262
  let n = null;
249
263
  for (const r of t.spans) {
250
264
  if (r.at > e) return null !== n && e < n.at + n.length ? n.from + (e - n.at) : r.from;
@@ -252,7 +266,51 @@ function _(t, e) {
252
266
  }
253
267
  return n ? n.from + Math.min(e - n.at, n.length) : 0;
254
268
  }
255
- async function b(t, e, n = "Runner timed out") {
269
+ var _ = /* @__PURE__ */ new Set(["TS2339", "TS2551"]), k = /* @__PURE__ */ new Set([
270
+ ..._,
271
+ "TS2304",
272
+ "TS2552",
273
+ "TS2448",
274
+ "TS2588",
275
+ "TS2531",
276
+ "TS2532",
277
+ "TS2533",
278
+ "TS18047",
279
+ "TS18048",
280
+ "TS18049",
281
+ "TS2349",
282
+ "TS2351",
283
+ "TS2721",
284
+ "TS2722",
285
+ "TS2723"
286
+ ]), D = /on type '(never|\{\})'/;
287
+ function K(t) {
288
+ return void 0 === t || "TypeError" === t || "ReferenceError" === t;
289
+ }
290
+ async function R(t, e) {
291
+ try {
292
+ const n = "snippet" === await w(t) ? await T(t) : null;
293
+ if ("undefined" === e && !n?.expectsValue) return [];
294
+ const [{ ScriptCompiler: r }, { getScriptingDeclarations: s }] = await Promise.all([import("@sheetxl/scripting"), import("@sheetxl/sdk")]), { diagnostics: i } = await r.compile({
295
+ source: n?.source ?? t,
296
+ ambientTypes: await s(),
297
+ lenient: !0,
298
+ disableBundle: !0,
299
+ disableSourceMap: !0
300
+ }), o = "threw" === e ? k : _;
301
+ return i.filter((t) => "error" === t.severity && o.has(t.code) && !(_.has(t.code) && D.test(t.message))).map((t) => ({
302
+ ...t,
303
+ start: n ? b(n, t.start) : t.start,
304
+ ..."undefined" === e ? {
305
+ severity: "warning",
306
+ message: `${t.message} It reads as undefined.`
307
+ } : {}
308
+ }));
309
+ } catch {
310
+ return [];
311
+ }
312
+ }
313
+ async function I(t, e, n = "Runner timed out") {
256
314
  if (!e || e <= 0) return t;
257
315
  let r;
258
316
  const s = new Promise((t, s) => r = setTimeout(() => s(new Error(n)), e));
@@ -262,31 +320,31 @@ async function b(t, e, n = "Runner timed out") {
262
320
  clearTimeout(r);
263
321
  }
264
322
  }
265
- var k = null;
266
- function K() {
267
- return k || (k = (async () => {
323
+ var C = null;
324
+ function $() {
325
+ return C || (C = (async () => {
268
326
  const { register: t } = await import("tsx/esm/api");
269
327
  t({ tsconfig: !1 });
270
- })()), k;
328
+ })()), C;
271
329
  }
272
- var D = "data:text/typescript,", R = "data:text/javascript,", I = null;
273
- function $() {
274
- return I || (I = (async () => {
330
+ var L = "data:text/typescript,", M = "data:text/javascript,", W = null;
331
+ function P() {
332
+ return W || (W = (async () => {
275
333
  const { registerHooks: e, stripTypeScriptTypes: r } = await import("node:module"), s = r;
276
334
  e({
277
335
  resolve(e, r, s) {
278
- const o = r.parentURL;
279
- if (o && (o.startsWith(D) || o.startsWith(R))) {
280
- const o = n(t.join(process.cwd(), "_inline_.ts")).href;
336
+ const i = r.parentURL;
337
+ if (i && (i.startsWith(L) || i.startsWith(M))) {
338
+ const i = n(t.join(process.cwd(), "_inline_.ts")).href;
281
339
  return s(e, {
282
340
  ...r,
283
- parentURL: o
341
+ parentURL: i
284
342
  });
285
343
  }
286
344
  return s(e, r);
287
345
  },
288
346
  load(t, e, n) {
289
- if (t.startsWith(D)) {
347
+ if (t.startsWith(L)) {
290
348
  const e = decodeURIComponent(t.slice(21)), n = process.emitWarning;
291
349
  let r;
292
350
  process.emitWarning = () => {};
@@ -304,16 +362,16 @@ function $() {
304
362
  return n(t, e);
305
363
  }
306
364
  });
307
- })()), I;
365
+ })()), W;
308
366
  }
309
- async function C(e) {
367
+ async function A(e) {
310
368
  const r = "string" == typeof (s = e) ? s.startsWith("file:") ? s : n(t.resolve(process.cwd(), s)).href : s.href;
311
369
  var s;
312
- const o = t.extname(new URL(r).pathname).toLowerCase();
313
- return ".ts" !== o && ".tsx" !== o || await K(), import(r);
370
+ const i = t.extname(new URL(r).pathname).toLowerCase();
371
+ return ".ts" !== i && ".tsx" !== i || await $(), import(r);
314
372
  }
315
- async function L(t, e, n) {
316
- const s = n.notifier ?? (await import("@sheetxl/sdk")).Notifier, o = r({
373
+ async function U(t, e, n) {
374
+ const s = n.notifier ?? (await import("@sheetxl/sdk")).Notifier, i = r({
317
375
  debug: (t) => s.debug(t),
318
376
  log: (t) => s.log(t),
319
377
  info: (t) => s.log(t),
@@ -328,65 +386,68 @@ async function L(t, e, n) {
328
386
  _: []
329
387
  },
330
388
  wb: t,
331
- log: o.log,
332
- warn: o.warn,
333
- error: o.error
389
+ log: i.log,
390
+ warn: i.warn,
391
+ error: i.error
334
392
  },
335
- channels: o,
393
+ channels: i,
336
394
  notifier: s
337
395
  };
338
396
  }
339
- var T = async (n, r, o) => {
340
- const i = o.target, a = Array.isArray(i) ? i : [i], c = await Promise.all(a.map((n) => (async (n, r = {}) => {
397
+ var j = async (n, r, i) => {
398
+ const o = i.target, a = Array.isArray(o) ? o : [o], c = await Promise.all(a.map((n) => (async (n, r = {}) => {
341
399
  let s = null;
342
- const o = (t, e) => {
400
+ const i = (t, e) => {
343
401
  let n = t?.default;
344
402
  if (n && "function" != typeof n && "function" == typeof n.default && (n = n.default), "function" != typeof n) throw new Error(`Script '${e}' has no runnable entry: export a default function, e.g. \`export default function main(ctx) { … }\`.`);
345
403
  return n;
346
404
  };
347
405
  if ("function" == typeof n) s = n;
348
406
  else if ("string" == typeof n || n instanceof URL) {
349
- let i = null;
350
- if ("string" != typeof n || /^[a-z]+:\/\//i.test(n)) i = await C(n);
407
+ let o = null;
408
+ if ("string" != typeof n || /^[a-z]+:\/\//i.test(n)) o = await A(n);
351
409
  else {
352
410
  const s = t.resolve(r.cwd ?? process.cwd(), n);
353
411
  if (!e.existsSync(s)) throw new Error(`Script not found: ${s}`);
354
- e.accessSync(s, e.constants.R_OK), i = await C(s);
412
+ e.accessSync(s, e.constants.R_OK), o = await A(s);
355
413
  }
356
- s = o(i, String(n));
414
+ s = i(o, String(n));
357
415
  } else if ("code" in n) {
358
416
  const t = n.filename ?? "inline.ts";
359
417
  let e, r = null;
360
- t.endsWith(".ts") || t.endsWith(".tsx") ? (await K(), await $(), e = `${D}${encodeURIComponent(n.code)}`, r = await import(e)) : (await $(), e = `${R}${encodeURIComponent(n.code)}`, r = await import(e)), s = o(r, t);
418
+ t.endsWith(".ts") || t.endsWith(".tsx") ? (await $(), await P(), e = `${L}${encodeURIComponent(n.code)}`, r = await import(e)) : (await P(), e = `${M}${encodeURIComponent(n.code)}`, r = await import(e)), s = i(r, t);
361
419
  } else {
362
420
  if (!("runner" in n)) throw new Error("Invalid run target specified.");
363
421
  s = n.runner;
364
422
  }
365
423
  return s;
366
- })(n, o))), l = Date.now();
367
- let u, p = n, f = null;
368
- const d = c.length;
369
- for (let t = 0; t < d; t++) {
370
- const e = c[t], { ctx: n, channels: i, notifier: a } = await L(p, r, o);
371
- f = a;
424
+ })(n, i))), l = Date.now();
425
+ let u, p = n, d = null;
426
+ const f = c.length;
427
+ for (let t = 0; t < f; t++) {
428
+ const e = c[t], { ctx: n, channels: o, notifier: a } = await U(p, r, i);
429
+ d = a;
372
430
  const l = Date.now();
373
431
  let m;
374
- const h = p, y = () => Promise.resolve().then(() => e(n));
432
+ const h = p, g = (t) => Promise.resolve().then(() => e(t));
375
433
  try {
376
- m = await b(null !== h ? Promise.resolve(h.doBatch(y, "Run Script")) : y(), o.timeoutMs, "Runner timed out");
434
+ m = await I(null !== h ? Promise.resolve(h.doBatch((t, e) => g({
435
+ ...n,
436
+ wb: e
437
+ }), "Run Script")) : g(n), i.timeoutMs, "Runner timed out");
377
438
  } finally {
378
- await i.flush({ timeoutMs: s(o.logTimeoutMs) });
439
+ await o.flush({ timeoutMs: s(i.logTimeoutMs) });
379
440
  }
380
- const g = Date.now();
381
- u = m, null != m && m.isIWorkbook && (p = m), a.debug(`Run ${1 === d ? "" : `${t + 1}/${d} `}completed in ${g - l} ms.`);
441
+ const y = Date.now();
442
+ u = m, null != m && m.isIWorkbook && (p = m), a.debug(`Run ${1 === f ? "" : `${t + 1}/${f} `}completed in ${y - l} ms.`);
382
443
  }
383
- if (d > 1 && f) {
444
+ if (f > 1 && d) {
384
445
  const t = Date.now();
385
- f.debug(`All runs completed in ${t - l} ms.`);
446
+ d.debug(`All runs completed in ${t - l} ms.`);
386
447
  }
387
448
  return u;
388
- }, W = { run: async (t, e, n) => {
449
+ }, O = { run: async (t, e, n) => {
389
450
  const { withScriptRuntime: r } = await import("@sheetxl/sdk");
390
- return r(() => T(t, e, n));
451
+ return r(() => j(t, e, n));
391
452
  } };
392
- export { a as Snippet, W as default, i as resolvePath };
453
+ export { a as Snippet, O as default, R as diagnoseRun, K as isExplainable, o as resolvePath };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@sheetxl/runner",
3
3
  "description": "SheetXL - Programmatic execution for SheetXL scripts",
4
- "version": "0.8.0-beta.2",
5
- "license": "SEE LICENSE IN <LICENSE>",
4
+ "version": "0.8.0-beta.21",
5
+ "license": "MIT",
6
6
  "type": "module",
7
7
  "exports": {
8
8
  ".": {
@@ -36,18 +36,23 @@
36
36
  "runner"
37
37
  ],
38
38
  "dependencies": {
39
- "@sheetxl/io": "^0.8.0-beta.2",
40
- "@sheetxl/primitives": "^0.8.0-beta.2",
41
- "@sheetxl/scripting": "^0.8.0-beta.2",
42
- "@sheetxl/sdk": "^0.8.0-beta.2",
43
- "@sheetxl/utils": "^0.8.0-beta.2"
39
+ "@sheetxl/io": "^0.8.0-beta.21",
40
+ "@sheetxl/primitives": "^0.8.0-beta.21",
41
+ "@sheetxl/scripting": "^0.8.0-beta.21",
42
+ "@sheetxl/sdk": "^0.8.0-beta.21",
43
+ "@sheetxl/utils": "^0.8.0-beta.21",
44
+ "tsx": "^4.23.15"
44
45
  },
45
46
  "peerDependencies": {
46
47
  "typescript": "^5.9.0 || ^6.0.0"
47
48
  },
49
+ "peerDependenciesMeta": {
50
+ "typescript": {
51
+ "optional": true
52
+ }
53
+ },
48
54
  "devDependencies": {
49
- "@types/node": "^26.1.2",
50
- "tsx": "^4.23.1",
55
+ "@types/node": "^26.6.4",
51
56
  "typescript": "^5.9.0 || ^6.0.0"
52
57
  }
53
58
  }
@@ -0,0 +1,33 @@
1
+ import { Diagnostic } from '@sheetxl/scripting';
2
+ /**
3
+ * What a run did that a type check may explain: it threw, or a snippet's final expression came
4
+ * back `undefined`.
5
+ *
6
+ * @remarks
7
+ * `undefined` is a symptom because the SheetXL API never returns it - `null` is the empty answer.
8
+ * A read that produced `undefined` read something that is not there.
9
+ */
10
+ export type RunSymptom = 'threw' | 'undefined';
11
+ /**
12
+ * Whether a failure is one a type check can explain, by the error's `name`. A failure with no
13
+ * name (a thrown string, an error that crossed a wire as its message) is checked too.
14
+ */
15
+ export declare function isExplainable(errorName: string | undefined): boolean;
16
+ /**
17
+ * Type-checks the source of a run that has already gone wrong, and returns the findings that can
18
+ * explain it.
19
+ *
20
+ * @remarks
21
+ * A run is never type-checked before it executes: the types are for discovery, not enforcement,
22
+ * and most of what a strict check reports about code written to run once (an unannotated `[]`,
23
+ * `catch (e)`, a field added to `{}`) runs correctly. A failed run leaves nothing behind, so
24
+ * running first costs nothing, and the check is paid only by a run with a symptom.
25
+ *
26
+ * The one implementation behind `sheetxl -e` and the MCP `run` tool, so both answer alike.
27
+ *
28
+ * Positions are in `source` as given - a snippet is checked in its wrapper and mapped back.
29
+ * A `threw` finding is an error; an `undefined` one is a warning, as the run completed.
30
+ * Never throws: a diagnosis that fails must not replace the failure it was diagnosing.
31
+ */
32
+ export declare function diagnoseRun(source: string, symptom: RunSymptom): Promise<Diagnostic[]>;
33
+ //# sourceMappingURL=RunDiagnosis.d.ts.map
@@ -83,6 +83,12 @@ export interface Prepared {
83
83
  lineOffset: number;
84
84
  /** Where the author's text sits within {@link source}, in source order. */
85
85
  spans: Span[];
86
+ /**
87
+ * Whether the snippet ends in an expression whose value is its answer — not a statement, not a
88
+ * call to `log`/`warn`/`error`, and not an entry function, which may return nothing as a script
89
+ * may. Such a snippet answering `undefined` read something that is not there.
90
+ */
91
+ expectsValue: boolean;
86
92
  /**
87
93
  * Set only when the contract could not be honored — no implicit await, no result. Callers should
88
94
  * surface it; a snippet quietly returning `undefined` is worse than one that failed.
@@ -1,5 +1,6 @@
1
1
  export * from './Types';
2
2
  export * from './RunUtils';
3
3
  export * as Snippet from './Snippet';
4
+ export * from './RunDiagnosis';
4
5
  export { default } from './Runner';
5
6
  //# sourceMappingURL=index.d.ts.map