@fnndsc/brasa 0.49.0 → 0.50.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/dist/buildinfo.json +1 -1
- package/dist/builtins/fs/cat.js +6 -5
- package/dist/builtins/fs/cat.js.map +1 -1
- package/dist/builtins/fs/configWrite.js +6 -5
- package/dist/builtins/fs/configWrite.js.map +1 -1
- package/dist/builtins/fs/cp.js +3 -2
- package/dist/builtins/fs/cp.js.map +1 -1
- package/dist/builtins/fs/download.js +5 -4
- package/dist/builtins/fs/download.js.map +1 -1
- package/dist/builtins/fs/du.js +4 -6
- package/dist/builtins/fs/du.js.map +1 -1
- package/dist/builtins/fs/edit.js +10 -9
- package/dist/builtins/fs/edit.js.map +1 -1
- package/dist/builtins/fs/find.js +3 -2
- package/dist/builtins/fs/find.js.map +1 -1
- package/dist/builtins/fs/ls.js +2 -1
- package/dist/builtins/fs/ls.js.map +1 -1
- package/dist/builtins/fs/mv.js +3 -2
- package/dist/builtins/fs/mv.js.map +1 -1
- package/dist/builtins/fs/pull.js +13 -12
- package/dist/builtins/fs/pull.js.map +1 -1
- package/dist/builtins/fs/rmdir.js +2 -1
- package/dist/builtins/fs/rmdir.js.map +1 -1
- package/dist/builtins/fs/tree.js +30 -39
- package/dist/builtins/fs/tree.js.map +1 -1
- package/dist/builtins/fs/upload.js +3 -2
- package/dist/builtins/fs/upload.js.map +1 -1
- package/dist/builtins/fs/url.js +2 -1
- package/dist/builtins/fs/url.js.map +1 -1
- package/dist/builtins/games/stdin.d.ts +8 -0
- package/dist/builtins/games/stdin.js +26 -14
- package/dist/builtins/games/stdin.js.map +1 -1
- package/dist/builtins/help.js +20 -4
- package/dist/builtins/help.js.map +1 -1
- package/dist/builtins/net/connect.js +2 -1
- package/dist/builtins/net/connect.js.map +1 -1
- package/dist/builtins/net/cubepath.js +5 -4
- package/dist/builtins/net/cubepath.js.map +1 -1
- package/dist/builtins/net/pacs.js +6 -5
- package/dist/builtins/net/pacs.js.map +1 -1
- package/dist/builtins/net/query.js +14 -13
- package/dist/builtins/net/query.js.map +1 -1
- package/dist/builtins/net/status.js +5 -4
- package/dist/builtins/net/status.js.map +1 -1
- package/dist/builtins/parametersofplugin.js +2 -1
- package/dist/builtins/parametersofplugin.js.map +1 -1
- package/dist/builtins/pluginExecute.js +2 -1
- package/dist/builtins/pluginExecute.js.map +1 -1
- package/dist/builtins/proc.js +31 -30
- package/dist/builtins/proc.js.map +1 -1
- package/dist/builtins/res/compute.js +4 -3
- package/dist/builtins/res/compute.js.map +1 -1
- package/dist/builtins/res/dicom.js +4 -3
- package/dist/builtins/res/dicom.js.map +1 -1
- package/dist/builtins/res/expect.js +8 -7
- package/dist/builtins/res/expect.js.map +1 -1
- package/dist/builtins/res/feed.diagram.js +4 -3
- package/dist/builtins/res/feed.diagram.js.map +1 -1
- package/dist/builtins/res/feed.js +13 -12
- package/dist/builtins/res/feed.js.map +1 -1
- package/dist/builtins/res/feed.tree.js +3 -2
- package/dist/builtins/res/feed.tree.js.map +1 -1
- package/dist/builtins/res/files.js +3 -2
- package/dist/builtins/res/files.js.map +1 -1
- package/dist/builtins/res/gather.js +2 -1
- package/dist/builtins/res/gather.js.map +1 -1
- package/dist/builtins/res/gather.process.js +2 -1
- package/dist/builtins/res/gather.process.js.map +1 -1
- package/dist/builtins/res/group.js +7 -6
- package/dist/builtins/res/group.js.map +1 -1
- package/dist/builtins/res/image.js +2 -1
- package/dist/builtins/res/image.js.map +1 -1
- package/dist/builtins/res/pipeline.d.ts +1 -1
- package/dist/builtins/res/pipeline.diagram.js +2 -1
- package/dist/builtins/res/pipeline.diagram.js.map +1 -1
- package/dist/builtins/res/pipeline.js +46 -37
- package/dist/builtins/res/pipeline.js.map +1 -1
- package/dist/builtins/res/play.js +40 -31
- package/dist/builtins/res/play.js.map +1 -1
- package/dist/builtins/res/plugin.js +7 -6
- package/dist/builtins/res/plugin.js.map +1 -1
- package/dist/builtins/res/plugininstance.js +6 -5
- package/dist/builtins/res/plugininstance.js.map +1 -1
- package/dist/builtins/res/pluginmeta.js +5 -4
- package/dist/builtins/res/pluginmeta.js.map +1 -1
- package/dist/builtins/res/record.js +6 -5
- package/dist/builtins/res/record.js.map +1 -1
- package/dist/builtins/res/tag.js +5 -4
- package/dist/builtins/res/tag.js.map +1 -1
- package/dist/builtins/res/user.js +2 -1
- package/dist/builtins/res/user.js.map +1 -1
- package/dist/builtins/res/workflow.js +5 -4
- package/dist/builtins/res/workflow.js.map +1 -1
- package/dist/builtins/store.js +5 -4
- package/dist/builtins/store.js.map +1 -1
- package/dist/builtins/sys/apropos.js +2 -1
- package/dist/builtins/sys/apropos.js.map +1 -1
- package/dist/builtins/sys/echo.js +4 -3
- package/dist/builtins/sys/echo.js.map +1 -1
- package/dist/builtins/sys/grep.js +3 -2
- package/dist/builtins/sys/grep.js.map +1 -1
- package/dist/builtins/sys/joblets.d.ts +28 -0
- package/dist/builtins/sys/joblets.js +95 -0
- package/dist/builtins/sys/joblets.js.map +1 -0
- package/dist/builtins/sys/tasks.d.ts +1 -1
- package/dist/builtins/sys/tasks.js +7 -1
- package/dist/builtins/sys/tasks.js.map +1 -1
- package/dist/builtins/sys/textFilters.js +5 -4
- package/dist/builtins/sys/textFilters.js.map +1 -1
- package/dist/builtins/sys/variables.js +6 -5
- package/dist/builtins/sys/variables.js.map +1 -1
- package/dist/builtins/sys/whoami.js +4 -3
- package/dist/builtins/sys/whoami.js.map +1 -1
- package/dist/chris/chiliDelegate.js +2 -1
- package/dist/chris/chiliDelegate.js.map +1 -1
- package/dist/chris/chrisCommands.d.ts +0 -1
- package/dist/chris/chrisCommands.js +13 -0
- package/dist/chris/chrisCommands.js.map +1 -1
- package/dist/chris/help.js +4 -4
- package/dist/chris/help.js.map +1 -1
- package/dist/core/assignment.js +2 -2
- package/dist/core/assignment.js.map +1 -1
- package/dist/core/cancellation.d.ts +10 -7
- package/dist/core/cancellation.js +39 -24
- package/dist/core/cancellation.js.map +1 -1
- package/dist/core/commandRegistry.d.ts +19 -0
- package/dist/core/commandRegistry.js +12 -0
- package/dist/core/commandRegistry.js.map +1 -1
- package/dist/core/coreCommands.d.ts +0 -1
- package/dist/core/coreCommands.js +22 -0
- package/dist/core/coreCommands.js.map +1 -1
- package/dist/core/dispatch.js +12 -18
- package/dist/core/dispatch.js.map +1 -1
- package/dist/core/elevation.js +7 -6
- package/dist/core/elevation.js.map +1 -1
- package/dist/core/engine.d.ts +43 -40
- package/dist/core/engine.js +43 -19
- package/dist/core/engine.js.map +1 -1
- package/dist/core/handlerRun.d.ts +16 -6
- package/dist/core/handlerRun.js +47 -2
- package/dist/core/handlerRun.js.map +1 -1
- package/dist/core/holds.d.ts +25 -0
- package/dist/core/holds.js +74 -0
- package/dist/core/holds.js.map +1 -0
- package/dist/core/joblets.d.ts +94 -0
- package/dist/core/joblets.js +363 -0
- package/dist/core/joblets.js.map +1 -0
- package/dist/core/lineOrigin.d.ts +31 -0
- package/dist/core/lineOrigin.js +38 -0
- package/dist/core/lineOrigin.js.map +1 -0
- package/dist/core/listing.d.ts +8 -0
- package/dist/core/listing.js +26 -14
- package/dist/core/listing.js.map +1 -1
- package/dist/core/runner.d.ts +15 -0
- package/dist/core/runner.js +25 -7
- package/dist/core/runner.js.map +1 -1
- package/dist/core/surface.d.ts +17 -2
- package/dist/core/surface.js +26 -3
- package/dist/core/surface.js.map +1 -1
- package/dist/core/variables.d.ts +7 -0
- package/dist/core/variables.js +9 -0
- package/dist/core/variables.js.map +1 -1
- package/dist/notes.json +1 -1
- package/dist/session/answer.d.ts +8 -11
- package/dist/session/answer.js +36 -25
- package/dist/session/answer.js.map +1 -1
- package/dist/session/cwdScope.d.ts +25 -0
- package/dist/session/cwdScope.js +36 -0
- package/dist/session/cwdScope.js.map +1 -0
- package/dist/session/index.js +14 -4
- package/dist/session/index.js.map +1 -1
- package/dist/session/recorder.d.ts +7 -4
- package/dist/session/recorder.js +16 -21
- package/dist/session/recorder.js.map +1 -1
- package/package.json +4 -4
- package/dist/core/turn.d.ts +0 -61
- package/dist/core/turn.js +0 -83
- package/dist/core/turn.js.map +0 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file What a line holds of the session while it runs.
|
|
3
|
+
*
|
|
4
|
+
* Lines from several surfaces share one session, and one line's work must
|
|
5
|
+
* not stop another's: a listing read in a browser should not wait behind a
|
|
6
|
+
* PACS pull typed in a console. So a host runs lines side by side unless
|
|
7
|
+
* they change the same piece of the session, and asks the kernel, before
|
|
8
|
+
* a line runs, what it holds (#1273). A line holds what its commands hold:
|
|
9
|
+
* nothing for a read, the working directory for `cd`, the cohort for
|
|
10
|
+
* `gather`. Whatever cannot be read off the line (a command that has not
|
|
11
|
+
* said, a host shell, a capture inside a word) holds the whole session, as
|
|
12
|
+
* every line did before.
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import { commandHolds_get } from './commandRegistry.js';
|
|
17
|
+
import { pipes_parse } from './preprocess.js';
|
|
18
|
+
import { semicolons_parse } from '../lib/semicolonParser.js';
|
|
19
|
+
import { assignment_parse } from './variables.js';
|
|
20
|
+
import { jobletLine_parse } from './joblets.js';
|
|
21
|
+
/**
|
|
22
|
+
* What a line holds of the session while it runs.
|
|
23
|
+
*
|
|
24
|
+
* @param line - The line, as the operator typed it.
|
|
25
|
+
* @returns The pieces its commands change (none for a read), or 'all'.
|
|
26
|
+
*/
|
|
27
|
+
export function lineHolds_get(line) {
|
|
28
|
+
// A line sent to the background only starts a joblet, which takes its
|
|
29
|
+
// own hold when it runs.
|
|
30
|
+
if (jobletLine_parse(line) !== null)
|
|
31
|
+
return [];
|
|
32
|
+
const pieces = new Set();
|
|
33
|
+
for (const command of semicolons_parse(line)) {
|
|
34
|
+
const held = commandLine_holds(command.trim());
|
|
35
|
+
if (held === 'all')
|
|
36
|
+
return 'all';
|
|
37
|
+
for (const piece of held)
|
|
38
|
+
pieces.add(piece);
|
|
39
|
+
}
|
|
40
|
+
return [...pieces];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* What one command line (no semicolons) holds.
|
|
44
|
+
*
|
|
45
|
+
* @param command - The trimmed command line.
|
|
46
|
+
* @returns Its pieces, or 'all'.
|
|
47
|
+
*/
|
|
48
|
+
function commandLine_holds(command) {
|
|
49
|
+
if (command === '')
|
|
50
|
+
return [];
|
|
51
|
+
// A host shell may do anything, the session's own tools included.
|
|
52
|
+
if (command.startsWith('!'))
|
|
53
|
+
return 'all';
|
|
54
|
+
const assignment = assignment_parse(command);
|
|
55
|
+
if (assignment !== null) {
|
|
56
|
+
// A store is one step: the assignment holds what its capture holds.
|
|
57
|
+
if ('capture' in assignment)
|
|
58
|
+
return lineHolds_get(assignment.capture);
|
|
59
|
+
return 'literal' in assignment && !/\$\(|`/.test(assignment.literal) ? [] : 'all';
|
|
60
|
+
}
|
|
61
|
+
if (/\$\(|`/.test(command))
|
|
62
|
+
return 'all';
|
|
63
|
+
const pieces = new Set();
|
|
64
|
+
for (const segment of pipes_parse(command)) {
|
|
65
|
+
const name = segment.trim().split(/\s+/)[0] ?? '';
|
|
66
|
+
const held = commandHolds_get(name);
|
|
67
|
+
if (held === null)
|
|
68
|
+
return 'all';
|
|
69
|
+
for (const piece of held)
|
|
70
|
+
pieces.add(piece);
|
|
71
|
+
}
|
|
72
|
+
return [...pieces];
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=holds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"holds.js","sourceRoot":"","sources":["../../src/core/holds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,gBAAgB,EAAqB,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAmB,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAKhD;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,sEAAsE;IACtE,yBAAyB;IACzB,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAC/C,MAAM,MAAM,GAAsB,IAAI,GAAG,EAAE,CAAC;IAC5C,KAAK,MAAM,OAAO,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAc,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,IAAI,IAAI,KAAK,KAAK;YAAE,OAAO,KAAK,CAAC;QACjC,KAAK,MAAM,KAAK,IAAI,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,OAAe;IACxC,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IAC9B,kEAAkE;IAClE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,UAAU,GAAsB,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAChE,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,oEAAoE;QACpE,IAAI,SAAS,IAAI,UAAU;YAAE,OAAO,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACtE,OAAO,SAAS,IAAI,UAAU,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACpF,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,MAAM,MAAM,GAAsB,IAAI,GAAG,EAAE,CAAC;IAC5C,KAAK,MAAM,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAW,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,MAAM,IAAI,GAAmC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACpE,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAChC,KAAK,MAAM,KAAK,IAAI,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Joblets: lines run in the background, `line &` (#1273).
|
|
3
|
+
*
|
|
4
|
+
* A long line (a PACS pull, a feed's creation, a teardown) need not hold the
|
|
5
|
+
* console it was typed in. Ended with `&`, it runs as a joblet: the runner
|
|
6
|
+
* keeps it as `/proc/joblets/<N>`, its output goes to its log rather than to
|
|
7
|
+
* a console someone is typing in, and its surface hears one line when it
|
|
8
|
+
* starts (`[1] pull … &`) and one when it ends (`[1]+ Done pull …`).
|
|
9
|
+
*
|
|
10
|
+
* A joblet is a subshell, as POSIX's is: it stands where its line was typed
|
|
11
|
+
* and starts with that line's variables, and its own `cd`s and assignments
|
|
12
|
+
* stay inside it. What lives in CUBE (a feed, the cohort) is shared, and a
|
|
13
|
+
* joblet holds what its line changes while it works, as a foreground line
|
|
14
|
+
* does, so it waits for, and is waited for by, the lines it conflicts with.
|
|
15
|
+
*
|
|
16
|
+
* A joblet that needs an answer pauses and says so (`[1]+ Waiting for an
|
|
17
|
+
* answer: … · fg %1 to answer`), as a POSIX background job that reads the
|
|
18
|
+
* terminal is stopped: a question asked out of the blue in a console would
|
|
19
|
+
* be answered by accident. `fg %1`, from any surface, asks it there.
|
|
20
|
+
*
|
|
21
|
+
* Joblets belong to the session: they outlive the surface that started them,
|
|
22
|
+
* and a daemon restart ends them, their logs kept ("ended by restart").
|
|
23
|
+
*
|
|
24
|
+
* @module
|
|
25
|
+
*/
|
|
26
|
+
import { type CommandEnvelope } from '@fnndsc/menu';
|
|
27
|
+
import { type JobSource } from './runner.js';
|
|
28
|
+
import { type PromptRequest } from './surface.js';
|
|
29
|
+
/** The runner source joblets are kept in: `/proc/joblets/<N>`. */
|
|
30
|
+
export declare const JOBLETS_SOURCE_ID: string;
|
|
31
|
+
/** A question a joblet waits on, until someone `fg`s it. */
|
|
32
|
+
export interface JobletQuestion {
|
|
33
|
+
request: PromptRequest;
|
|
34
|
+
answer(text: string): void;
|
|
35
|
+
refuse(reason: Error): void;
|
|
36
|
+
}
|
|
37
|
+
/** The joblets' source, which the core gives every session's runner. */
|
|
38
|
+
export declare const jobletsSource: JobSource;
|
|
39
|
+
/**
|
|
40
|
+
* The line a `&` sends to the background, when the line ends with one.
|
|
41
|
+
*
|
|
42
|
+
* @param line - The line as typed.
|
|
43
|
+
* @returns The line without its `&`, or null when it is not one (`&&`,
|
|
44
|
+
* `\&`, a `&` inside quotes, a bare `&`).
|
|
45
|
+
*/
|
|
46
|
+
export declare function jobletLine_parse(line: string): string | null;
|
|
47
|
+
/**
|
|
48
|
+
* Starts a line as a joblet.
|
|
49
|
+
*
|
|
50
|
+
* @param line - The line, without its `&`.
|
|
51
|
+
* @returns The start notice, `[1] line &`, or why it could not start.
|
|
52
|
+
*/
|
|
53
|
+
export declare function joblet_start(line: string): Promise<CommandEnvelope>;
|
|
54
|
+
/**
|
|
55
|
+
* The question a joblet waits on now, if any.
|
|
56
|
+
*
|
|
57
|
+
* @param number - The joblet.
|
|
58
|
+
* @returns Its question, or null.
|
|
59
|
+
*/
|
|
60
|
+
export declare function jobletQuestion_get(number: number): JobletQuestion | null;
|
|
61
|
+
/**
|
|
62
|
+
* Waits until a joblet asks a question, or the wait is called off.
|
|
63
|
+
*
|
|
64
|
+
* @param number - The joblet.
|
|
65
|
+
* @param until - Calls the wait off when it settles.
|
|
66
|
+
* @returns The question, or null when called off first.
|
|
67
|
+
*/
|
|
68
|
+
export declare function jobletQuestion_await(number: number, until: Promise<unknown>): Promise<JobletQuestion | null>;
|
|
69
|
+
/** A joblet still running, as a restart's warning counts it. */
|
|
70
|
+
export interface JobletRunning {
|
|
71
|
+
number: number;
|
|
72
|
+
line: string;
|
|
73
|
+
waiting: boolean;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The joblets running now: what a restart would end.
|
|
77
|
+
*
|
|
78
|
+
* @returns Them, by number.
|
|
79
|
+
*/
|
|
80
|
+
export declare function joblets_running(): JobletRunning[];
|
|
81
|
+
/**
|
|
82
|
+
* Whether a joblet waits on an answer.
|
|
83
|
+
*
|
|
84
|
+
* @param number - The joblet.
|
|
85
|
+
* @returns True while it waits.
|
|
86
|
+
*/
|
|
87
|
+
export declare function joblet_isWaiting(number: number): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* The joblet a word names: `%3`, `%%`/`%+` (the most recent), or `3`.
|
|
90
|
+
*
|
|
91
|
+
* @param word - The word.
|
|
92
|
+
* @returns The joblet's number, or null when the word names none.
|
|
93
|
+
*/
|
|
94
|
+
export declare function jobletWord_parse(word: string): number | null;
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Joblets: lines run in the background, `line &` (#1273).
|
|
3
|
+
*
|
|
4
|
+
* A long line (a PACS pull, a feed's creation, a teardown) need not hold the
|
|
5
|
+
* console it was typed in. Ended with `&`, it runs as a joblet: the runner
|
|
6
|
+
* keeps it as `/proc/joblets/<N>`, its output goes to its log rather than to
|
|
7
|
+
* a console someone is typing in, and its surface hears one line when it
|
|
8
|
+
* starts (`[1] pull … &`) and one when it ends (`[1]+ Done pull …`).
|
|
9
|
+
*
|
|
10
|
+
* A joblet is a subshell, as POSIX's is: it stands where its line was typed
|
|
11
|
+
* and starts with that line's variables, and its own `cd`s and assignments
|
|
12
|
+
* stay inside it. What lives in CUBE (a feed, the cohort) is shared, and a
|
|
13
|
+
* joblet holds what its line changes while it works, as a foreground line
|
|
14
|
+
* does, so it waits for, and is waited for by, the lines it conflicts with.
|
|
15
|
+
*
|
|
16
|
+
* A joblet that needs an answer pauses and says so (`[1]+ Waiting for an
|
|
17
|
+
* answer: … · fg %1 to answer`), as a POSIX background job that reads the
|
|
18
|
+
* terminal is stopped: a question asked out of the blue in a console would
|
|
19
|
+
* be answered by accident. `fg %1`, from any surface, asks it there.
|
|
20
|
+
*
|
|
21
|
+
* Joblets belong to the session: they outlive the surface that started them,
|
|
22
|
+
* and a daemon restart ends them, their logs kept ("ended by restart").
|
|
23
|
+
*
|
|
24
|
+
* @module
|
|
25
|
+
*/
|
|
26
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
27
|
+
import { EventEmitter } from 'node:events';
|
|
28
|
+
import { envelope_error, envelope_ok, taskState_isOver } from '@fnndsc/menu';
|
|
29
|
+
import { ambient_publish } from './ambient.js';
|
|
30
|
+
import { commandCancellation_abort } from './cancellation.js';
|
|
31
|
+
import { lineHolds_get } from './holds.js';
|
|
32
|
+
import { lineOrigin_get } from './lineOrigin.js';
|
|
33
|
+
import { JobRefusal, runner_get } from './runner.js';
|
|
34
|
+
import { ansi_strip, sinkScope_run } from './sink.js';
|
|
35
|
+
import { surfaceInstalled_get, surfaceScope_run } from './surface.js';
|
|
36
|
+
import { variableScope_fork } from './variables.js';
|
|
37
|
+
import { quoteOpen_find } from '../lib/quoting.js';
|
|
38
|
+
import { cwdScope_run } from '../session/cwdScope.js';
|
|
39
|
+
import { session } from '../session/index.js';
|
|
40
|
+
/** The runner source joblets are kept in: `/proc/joblets/<N>`. */
|
|
41
|
+
export const JOBLETS_SOURCE_ID = 'joblets';
|
|
42
|
+
/**
|
|
43
|
+
* Runs work outside every line's scope, as the kernel stood when it loaded:
|
|
44
|
+
* a joblet is its own line, not part of the one that started it.
|
|
45
|
+
*/
|
|
46
|
+
const rootContext_run = AsyncLocalStorage.snapshot();
|
|
47
|
+
const running = new Map();
|
|
48
|
+
const asking = new EventEmitter();
|
|
49
|
+
asking.setMaxListeners(0);
|
|
50
|
+
/**
|
|
51
|
+
* The line a joblet ends with, as its surface and `joblets` print it.
|
|
52
|
+
*
|
|
53
|
+
* @param record - The joblet's record.
|
|
54
|
+
* @returns The notice.
|
|
55
|
+
*/
|
|
56
|
+
function jobletNotice_render(record) {
|
|
57
|
+
if (record.state === 'done')
|
|
58
|
+
return `[${record.id}]+ Done ${record.label}`;
|
|
59
|
+
if (record.state === 'cancelled')
|
|
60
|
+
return `[${record.id}]+ Stopped ${record.label}`;
|
|
61
|
+
const exit = record.data.exit;
|
|
62
|
+
return `[${record.id}]+ Failed (exit ${typeof exit === 'number' ? exit : 1}): ${record.outcome ?? record.label}`;
|
|
63
|
+
}
|
|
64
|
+
/** The joblets' source, which the core gives every session's runner. */
|
|
65
|
+
export const jobletsSource = {
|
|
66
|
+
id: JOBLETS_SOURCE_ID,
|
|
67
|
+
label: 'joblets',
|
|
68
|
+
// A joblet runs the session's own lines, which need no tier in front.
|
|
69
|
+
ungated: true,
|
|
70
|
+
interrupted: 'ended by restart',
|
|
71
|
+
notice: jobletNotice_render,
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* The line a `&` sends to the background, when the line ends with one.
|
|
75
|
+
*
|
|
76
|
+
* @param line - The line as typed.
|
|
77
|
+
* @returns The line without its `&`, or null when it is not one (`&&`,
|
|
78
|
+
* `\&`, a `&` inside quotes, a bare `&`).
|
|
79
|
+
*/
|
|
80
|
+
export function jobletLine_parse(line) {
|
|
81
|
+
const trimmed = line.trimEnd();
|
|
82
|
+
if (!trimmed.endsWith('&') || trimmed.endsWith('&&'))
|
|
83
|
+
return null;
|
|
84
|
+
const body = trimmed.slice(0, -1);
|
|
85
|
+
if (body.endsWith('\\') || quoteOpen_find(body) !== null)
|
|
86
|
+
return null;
|
|
87
|
+
const command = body.trim();
|
|
88
|
+
return command === '' ? null : command;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Publishes a line to the surface a joblet came from.
|
|
92
|
+
*
|
|
93
|
+
* @param origin - The surface.
|
|
94
|
+
* @param text - The line.
|
|
95
|
+
*/
|
|
96
|
+
function notice_publish(origin, text, model) {
|
|
97
|
+
ambient_publish({ kind: 'envelope', envelope: envelope_ok(`${text}\n`, model), origin });
|
|
98
|
+
}
|
|
99
|
+
/** A sink that writes a joblet's output to its log, a line at a time. */
|
|
100
|
+
class JobletLogSink {
|
|
101
|
+
write;
|
|
102
|
+
progress;
|
|
103
|
+
relay;
|
|
104
|
+
pending = '';
|
|
105
|
+
/**
|
|
106
|
+
* @param write - Writes one line to the log.
|
|
107
|
+
* @param progress - Says how far the joblet has come, on its task.
|
|
108
|
+
* @param relay - Hands a progress event to the joblet's surface.
|
|
109
|
+
*/
|
|
110
|
+
constructor(write, progress, relay) {
|
|
111
|
+
this.write = write;
|
|
112
|
+
this.progress = progress;
|
|
113
|
+
this.relay = relay;
|
|
114
|
+
}
|
|
115
|
+
/** @inheritdoc */
|
|
116
|
+
data_write(chunk) {
|
|
117
|
+
this.text_take(typeof chunk === 'string' ? chunk : chunk.toString('utf-8'));
|
|
118
|
+
}
|
|
119
|
+
/** @inheritdoc */
|
|
120
|
+
err_write(chunk) {
|
|
121
|
+
this.text_take(typeof chunk === 'string' ? chunk : chunk.toString('utf-8'));
|
|
122
|
+
}
|
|
123
|
+
/** @inheritdoc */
|
|
124
|
+
status_write(_text) {
|
|
125
|
+
// A status line is for whoever watches now; a log keeps what happened.
|
|
126
|
+
}
|
|
127
|
+
/** @inheritdoc */
|
|
128
|
+
progress_write(event) {
|
|
129
|
+
// The surface it came from follows it as it would a line in front.
|
|
130
|
+
this.relay(event);
|
|
131
|
+
// A count goes on the joblet's task, where a tile or a watch reads it.
|
|
132
|
+
if (event.current === undefined)
|
|
133
|
+
return;
|
|
134
|
+
this.progress({ current: event.current, total: event.total ?? null, ...(event.unit !== undefined ? { unit: event.unit } : {}) });
|
|
135
|
+
}
|
|
136
|
+
/** @inheritdoc */
|
|
137
|
+
event_write(_kind, _data) {
|
|
138
|
+
// An event is live by contract.
|
|
139
|
+
}
|
|
140
|
+
/** Writes what is left of a line without its newline. */
|
|
141
|
+
flush() {
|
|
142
|
+
if (this.pending !== '')
|
|
143
|
+
this.write(this.pending);
|
|
144
|
+
this.pending = '';
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Splits text into the log's lines, keeping a part-line for the next chunk.
|
|
148
|
+
*
|
|
149
|
+
* @param text - The text.
|
|
150
|
+
*/
|
|
151
|
+
text_take(text) {
|
|
152
|
+
const lines = ansi_strip(this.pending + text).split('\n');
|
|
153
|
+
this.pending = lines.pop() ?? '';
|
|
154
|
+
for (const line of lines)
|
|
155
|
+
this.write(line);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* The number a new joblet takes: one past the highest still running, as a
|
|
160
|
+
* shell numbers its jobs.
|
|
161
|
+
*
|
|
162
|
+
* @param runner - The session's runner.
|
|
163
|
+
* @returns The number.
|
|
164
|
+
*/
|
|
165
|
+
function jobletNumber_next(runner) {
|
|
166
|
+
const numbers = runner.jobs_list(JOBLETS_SOURCE_ID)
|
|
167
|
+
.filter((record) => !taskState_isOver(record.state))
|
|
168
|
+
.map((record) => Number(record.id))
|
|
169
|
+
.filter((number) => Number.isInteger(number));
|
|
170
|
+
return numbers.length === 0 ? 1 : Math.max(...numbers) + 1;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Starts a line as a joblet.
|
|
174
|
+
*
|
|
175
|
+
* @param line - The line, without its `&`.
|
|
176
|
+
* @returns The start notice, `[1] line &`, or why it could not start.
|
|
177
|
+
*/
|
|
178
|
+
export async function joblet_start(line) {
|
|
179
|
+
const runner = runner_get();
|
|
180
|
+
if (runner === null)
|
|
181
|
+
return envelope_error('', undefined, `${line}: this session runs no joblets\n`);
|
|
182
|
+
const number = jobletNumber_next(runner);
|
|
183
|
+
const joblet = { number, line, origin: lineOrigin_get(), question: null };
|
|
184
|
+
// Where the line was typed: the joblet stands there whatever moves later.
|
|
185
|
+
const cwd = await session.getCWD();
|
|
186
|
+
try {
|
|
187
|
+
const started = runner.job_start(JOBLETS_SOURCE_ID, String(number), line, (context) => {
|
|
188
|
+
running.set(number, joblet);
|
|
189
|
+
return rootContext_run(() => joblet_run(joblet, context, cwd))
|
|
190
|
+
.finally(() => { running.delete(number); });
|
|
191
|
+
}, { origin: joblet.origin });
|
|
192
|
+
void started.finished;
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
if (error instanceof JobRefusal)
|
|
196
|
+
return envelope_error('', undefined, `${error.message}\n`);
|
|
197
|
+
throw error;
|
|
198
|
+
}
|
|
199
|
+
return envelope_ok(`[${number}] ${line} &\n`, { kind: 'joblet.started', data: { number, line, path: `/proc/${JOBLETS_SOURCE_ID}/${number}` } });
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* A joblet's work: its line, run as a line of its own, writing to its log.
|
|
203
|
+
*
|
|
204
|
+
* @param joblet - The joblet.
|
|
205
|
+
* @param context - What the runner hands it.
|
|
206
|
+
* @param cwd - Where it stands.
|
|
207
|
+
*/
|
|
208
|
+
async function joblet_run(joblet, context, cwd) {
|
|
209
|
+
const { line_execute } = await import('./engine.js');
|
|
210
|
+
const host = surfaceInstalled_get();
|
|
211
|
+
let release = null;
|
|
212
|
+
const hold_take = async () => {
|
|
213
|
+
release = host.hold !== undefined ? await host.hold(lineHolds_get(joblet.line)) : null;
|
|
214
|
+
};
|
|
215
|
+
const hold_give = () => {
|
|
216
|
+
const giving = release;
|
|
217
|
+
release = null;
|
|
218
|
+
giving?.();
|
|
219
|
+
};
|
|
220
|
+
const key = `joblet-${joblet.number}`;
|
|
221
|
+
context.signal.addEventListener('abort', () => {
|
|
222
|
+
commandCancellation_abort(key);
|
|
223
|
+
joblet.question?.refuse(new Error('the joblet was stopped'));
|
|
224
|
+
}, { once: true });
|
|
225
|
+
const standIn = jobletSurface_make(joblet, context, hold_take, hold_give);
|
|
226
|
+
const sink = new JobletLogSink((text) => context.log_write(text), (progress) => context.progress_set(progress), (event) => ambient_publish({ kind: 'progress', origin: joblet.origin, id: key, progress: event }));
|
|
227
|
+
let exit = 0;
|
|
228
|
+
await hold_take();
|
|
229
|
+
let envelopes;
|
|
230
|
+
try {
|
|
231
|
+
envelopes = await sinkScope_run(sink, () => surfaceScope_run(standIn, () => variableScope_fork(() => cwdScope_run(() => line_execute(joblet.line, { origin: `joblet:${joblet.number}`, id: key, ended: (code) => { exit = code; } }), cwd))));
|
|
232
|
+
}
|
|
233
|
+
finally {
|
|
234
|
+
hold_give();
|
|
235
|
+
}
|
|
236
|
+
// What the line answered with goes to the log after what it printed, and
|
|
237
|
+
// a model it answered with (a cohort its pull brought home) to its surface,
|
|
238
|
+
// whose views take it as they would from a line in front.
|
|
239
|
+
for (const envelope of envelopes) {
|
|
240
|
+
if (envelope.model !== undefined)
|
|
241
|
+
ambient_publish({ kind: 'envelope', envelope: { status: envelope.status, rendered: '', model: envelope.model }, origin: joblet.origin });
|
|
242
|
+
if (envelope.rendered !== '')
|
|
243
|
+
sink.data_write(envelope.rendered.endsWith('\n') ? envelope.rendered : `${envelope.rendered}\n`);
|
|
244
|
+
if (envelope.renderedErr)
|
|
245
|
+
sink.err_write(envelope.renderedErr.endsWith('\n') ? envelope.renderedErr : `${envelope.renderedErr}\n`);
|
|
246
|
+
}
|
|
247
|
+
sink.flush();
|
|
248
|
+
const failed = exit !== 0 || envelopes.some((envelope) => envelope.status === 'error');
|
|
249
|
+
if (!failed)
|
|
250
|
+
return;
|
|
251
|
+
context.data_set('exit', exit === 0 ? 1 : exit);
|
|
252
|
+
const lastErr = envelopes.map((envelope) => ansi_strip(envelope.renderedErr ?? '')).join('').trim().split('\n').pop() ?? '';
|
|
253
|
+
throw new Error(lastErr !== '' ? lastErr : `exit ${exit === 0 ? 1 : exit}`);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* The surface a joblet runs under: the host's, except that a question
|
|
257
|
+
* pauses the joblet until someone `fg`s it, giving up what it holds while
|
|
258
|
+
* it waits.
|
|
259
|
+
*
|
|
260
|
+
* @param joblet - The joblet.
|
|
261
|
+
* @param context - Its runner context.
|
|
262
|
+
* @param hold_take - Takes its hold again.
|
|
263
|
+
* @param hold_give - Gives its hold up.
|
|
264
|
+
* @returns The stand-in.
|
|
265
|
+
*/
|
|
266
|
+
function jobletSurface_make(joblet, context, hold_take, hold_give) {
|
|
267
|
+
const question_pause = async (request) => {
|
|
268
|
+
if (context.signal.aborted)
|
|
269
|
+
throw new Error('the joblet was stopped');
|
|
270
|
+
hold_give();
|
|
271
|
+
notice_publish(joblet.origin, `[${joblet.number}]+ Waiting for an answer: ${request.message.trim()} · fg %${joblet.number} to answer`, { kind: 'joblet.waiting', data: { number: joblet.number, line: joblet.line, question: request.message } });
|
|
272
|
+
context.log_write(`waiting for an answer: ${request.message.trim()}`);
|
|
273
|
+
try {
|
|
274
|
+
return await new Promise((resolve, reject) => {
|
|
275
|
+
joblet.question = {
|
|
276
|
+
request,
|
|
277
|
+
answer: (text) => { joblet.question = null; resolve(text); },
|
|
278
|
+
refuse: (reason) => { joblet.question = null; reject(reason); },
|
|
279
|
+
};
|
|
280
|
+
asking.emit(`asked:${joblet.number}`);
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
finally {
|
|
284
|
+
await hold_take();
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
return new Proxy(surfaceInstalled_get(), {
|
|
288
|
+
get: (_target, property) => {
|
|
289
|
+
if (property === 'prompt')
|
|
290
|
+
return question_pause;
|
|
291
|
+
const host = surfaceInstalled_get();
|
|
292
|
+
const value = Reflect.get(host, property);
|
|
293
|
+
return typeof value === 'function' ? value.bind(host) : value;
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* The question a joblet waits on now, if any.
|
|
299
|
+
*
|
|
300
|
+
* @param number - The joblet.
|
|
301
|
+
* @returns Its question, or null.
|
|
302
|
+
*/
|
|
303
|
+
export function jobletQuestion_get(number) {
|
|
304
|
+
return running.get(number)?.question ?? null;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Waits until a joblet asks a question, or the wait is called off.
|
|
308
|
+
*
|
|
309
|
+
* @param number - The joblet.
|
|
310
|
+
* @param until - Calls the wait off when it settles.
|
|
311
|
+
* @returns The question, or null when called off first.
|
|
312
|
+
*/
|
|
313
|
+
export async function jobletQuestion_await(number, until) {
|
|
314
|
+
const now = jobletQuestion_get(number);
|
|
315
|
+
if (now !== null)
|
|
316
|
+
return now;
|
|
317
|
+
let heard = null;
|
|
318
|
+
const asked = new Promise((resolve) => {
|
|
319
|
+
heard = () => resolve('asked');
|
|
320
|
+
asking.once(`asked:${number}`, heard);
|
|
321
|
+
});
|
|
322
|
+
const outcome = await Promise.race([asked, until.then(() => 'off', () => 'off')]);
|
|
323
|
+
if (heard !== null)
|
|
324
|
+
asking.off(`asked:${number}`, heard);
|
|
325
|
+
return outcome === 'asked' ? jobletQuestion_get(number) : null;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* The joblets running now: what a restart would end.
|
|
329
|
+
*
|
|
330
|
+
* @returns Them, by number.
|
|
331
|
+
*/
|
|
332
|
+
export function joblets_running() {
|
|
333
|
+
return [...running.values()]
|
|
334
|
+
.sort((a, b) => a.number - b.number)
|
|
335
|
+
.map((joblet) => ({ number: joblet.number, line: joblet.line, waiting: joblet.question !== null }));
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Whether a joblet waits on an answer.
|
|
339
|
+
*
|
|
340
|
+
* @param number - The joblet.
|
|
341
|
+
* @returns True while it waits.
|
|
342
|
+
*/
|
|
343
|
+
export function joblet_isWaiting(number) {
|
|
344
|
+
return jobletQuestion_get(number) !== null;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* The joblet a word names: `%3`, `%%`/`%+` (the most recent), or `3`.
|
|
348
|
+
*
|
|
349
|
+
* @param word - The word.
|
|
350
|
+
* @returns The joblet's number, or null when the word names none.
|
|
351
|
+
*/
|
|
352
|
+
export function jobletWord_parse(word) {
|
|
353
|
+
const runner = runner_get();
|
|
354
|
+
if (word === '%%' || word === '%+' || word === '%') {
|
|
355
|
+
const numbers = (runner?.jobs_list(JOBLETS_SOURCE_ID) ?? []).map((record) => Number(record.id)).filter(Number.isInteger);
|
|
356
|
+
const live = numbers.filter((number) => running.has(number));
|
|
357
|
+
const pool = live.length > 0 ? live : numbers;
|
|
358
|
+
return pool.length === 0 ? null : Math.max(...pool);
|
|
359
|
+
}
|
|
360
|
+
const match = word.match(/^%?(\d+)$/);
|
|
361
|
+
return match === null ? null : Number(match[1]);
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=joblets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"joblets.js","sourceRoot":"","sources":["../../src/core/joblets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Which surface a line came from.
|
|
3
|
+
*
|
|
4
|
+
* One session serves several surfaces at once: a console, a browser, a
|
|
5
|
+
* second terminal. What a line leaves behind for the operator who typed it
|
|
6
|
+
* (the listing `@3` counts) belongs to that operator's surface, not to the
|
|
7
|
+
* session: a listing one surface reads must not renumber the rows another
|
|
8
|
+
* is about to act on (#1273).
|
|
9
|
+
*
|
|
10
|
+
* The host names the origin when it hands the kernel a line; a line run
|
|
11
|
+
* inside it (a manifest's, a capture's) inherits it. A line with no host
|
|
12
|
+
* behind it (a test, a headless script) has the default origin.
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
/** The origin of a line no host named. */
|
|
17
|
+
export declare const ORIGIN_DEFAULT: string;
|
|
18
|
+
/**
|
|
19
|
+
* Runs an operation as lines from one origin.
|
|
20
|
+
*
|
|
21
|
+
* @param origin - The surface the line came from.
|
|
22
|
+
* @param operation - The work.
|
|
23
|
+
* @returns What the operation returns.
|
|
24
|
+
*/
|
|
25
|
+
export declare function lineOrigin_run<T>(origin: string, operation: () => Promise<T>): Promise<T>;
|
|
26
|
+
/**
|
|
27
|
+
* The origin of the line running now.
|
|
28
|
+
*
|
|
29
|
+
* @returns The surface it came from, or {@link ORIGIN_DEFAULT}.
|
|
30
|
+
*/
|
|
31
|
+
export declare function lineOrigin_get(): string;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Which surface a line came from.
|
|
3
|
+
*
|
|
4
|
+
* One session serves several surfaces at once: a console, a browser, a
|
|
5
|
+
* second terminal. What a line leaves behind for the operator who typed it
|
|
6
|
+
* (the listing `@3` counts) belongs to that operator's surface, not to the
|
|
7
|
+
* session: a listing one surface reads must not renumber the rows another
|
|
8
|
+
* is about to act on (#1273).
|
|
9
|
+
*
|
|
10
|
+
* The host names the origin when it hands the kernel a line; a line run
|
|
11
|
+
* inside it (a manifest's, a capture's) inherits it. A line with no host
|
|
12
|
+
* behind it (a test, a headless script) has the default origin.
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
17
|
+
/** The origin of a line no host named. */
|
|
18
|
+
export const ORIGIN_DEFAULT = '';
|
|
19
|
+
const originScope = new AsyncLocalStorage();
|
|
20
|
+
/**
|
|
21
|
+
* Runs an operation as lines from one origin.
|
|
22
|
+
*
|
|
23
|
+
* @param origin - The surface the line came from.
|
|
24
|
+
* @param operation - The work.
|
|
25
|
+
* @returns What the operation returns.
|
|
26
|
+
*/
|
|
27
|
+
export async function lineOrigin_run(origin, operation) {
|
|
28
|
+
return await originScope.run(origin, operation);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The origin of the line running now.
|
|
32
|
+
*
|
|
33
|
+
* @returns The surface it came from, or {@link ORIGIN_DEFAULT}.
|
|
34
|
+
*/
|
|
35
|
+
export function lineOrigin_get() {
|
|
36
|
+
return originScope.getStore() ?? ORIGIN_DEFAULT;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=lineOrigin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineOrigin.js","sourceRoot":"","sources":["../../src/core/lineOrigin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,0CAA0C;AAC1C,MAAM,CAAC,MAAM,cAAc,GAAW,EAAE,CAAC;AAEzC,MAAM,WAAW,GAA8B,IAAI,iBAAiB,EAAU,CAAC;AAE/E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAI,MAAc,EAAE,SAA2B;IACjF,OAAO,MAAM,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAClD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,WAAW,CAAC,QAAQ,EAAE,IAAI,cAAc,CAAC;AAClD,CAAC"}
|
package/dist/core/listing.d.ts
CHANGED
|
@@ -16,6 +16,14 @@ export interface ListingModel {
|
|
|
16
16
|
kind: string;
|
|
17
17
|
data: unknown;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Runs a pipe segment with the listing piped into it, in a slot of its own.
|
|
21
|
+
*
|
|
22
|
+
* @param model - The previous segment's listing, or null.
|
|
23
|
+
* @param operation - The segment.
|
|
24
|
+
* @returns What the segment returned.
|
|
25
|
+
*/
|
|
26
|
+
export declare function listingInScope_run<T>(model: ListingModel | null, operation: () => Promise<T>): Promise<T>;
|
|
19
27
|
/**
|
|
20
28
|
* Hands a listing to the next builtin in a pipe (null clears it).
|
|
21
29
|
*
|