@prestack/thread 0.1.3 → 0.1.5
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/CHANGELOG.md +563 -0
- package/dist/core/actor.d.ts +1 -1
- package/dist/core/actor.js +5 -4
- package/dist/core/actor.ts +5 -4
- package/dist/core/attach.d.ts +0 -7
- package/dist/core/attach.js +38 -67
- package/dist/core/attach.ts +34 -80
- package/dist/core/chain.js +13 -17
- package/dist/core/chain.ts +11 -15
- package/dist/core/condition.d.ts +4 -4
- package/dist/core/condition.js +2 -2
- package/dist/core/descend.d.ts +4 -2
- package/dist/core/descend.js +91 -23
- package/dist/core/descend.ts +90 -21
- package/dist/core/errors/catalogue.d.ts +52 -0
- package/dist/{operations/errors/errors.js → core/errors/catalogue.js} +1 -1
- package/dist/{operations/errors/errors.ts → core/errors/catalogue.ts} +1 -1
- package/dist/{operations/errors/catalog.d.ts → core/errors/error.d.ts} +2 -3
- package/dist/{operations/errors/catalog.js → core/errors/error.js} +1 -16
- package/dist/{operations/errors/catalog.ts → core/errors/error.ts} +3 -19
- package/dist/core/errors/namespaces.d.ts +3 -0
- package/dist/core/errors/namespaces.js +15 -0
- package/dist/core/errors/namespaces.ts +19 -0
- package/dist/core/finding.js +2 -2
- package/dist/core/finding.ts +1 -2
- package/dist/core/init.d.ts +1 -1
- package/dist/core/init.js +51 -5
- package/dist/core/init.ts +58 -5
- package/dist/core/invoked.d.ts +1 -1
- package/dist/core/invoked.js +3 -1
- package/dist/core/invoked.ts +5 -2
- package/dist/core/round.js +36 -22
- package/dist/core/round.ts +26 -9
- package/dist/core/rows.d.ts +4 -0
- package/dist/core/rows.js +31 -2
- package/dist/core/rows.ts +33 -1
- package/dist/core/scope.d.ts +1 -0
- package/dist/core/scope.js +1 -0
- package/dist/core/scope.ts +2 -0
- package/dist/core/thread.d.ts +3 -3
- package/dist/core/tree.d.ts +4 -1
- package/dist/core/tree.js +26 -6
- package/dist/core/tree.ts +29 -6
- package/dist/core/types.d.ts +3 -3
- package/dist/core/types.js +3 -1
- package/dist/core/types.ts +2 -1
- package/dist/derivation/attach.js +3 -2
- package/dist/derivation/attach.ts +2 -1
- package/dist/derivation/generators/build.js +6 -6
- package/dist/derivation/generators/build.ts +1 -1
- package/dist/derivation/generators/check.js +1 -1
- package/dist/derivation/generators/determinism.js +1 -1
- package/dist/derivation/generators/release.js +60 -47
- package/dist/derivation/generators/release.ts +66 -43
- package/dist/derivation/release.d.ts +7 -3
- package/dist/derivation/release.js +14 -1
- package/dist/derivation/release.ts +22 -2
- package/dist/integrations/attach.d.ts +4 -0
- package/dist/integrations/attach.js +37 -56
- package/dist/integrations/attach.ts +54 -60
- package/dist/integrations/cli.d.ts +37 -0
- package/dist/integrations/cli.js +440 -0
- package/dist/integrations/cli.ts +543 -0
- package/dist/{core/files.d.ts → integrations/disk.d.ts} +16 -24
- package/dist/integrations/disk.js +435 -0
- package/dist/integrations/disk.ts +465 -0
- package/dist/integrations/generators/read.js +6 -6
- package/dist/integrations/generators/read.ts +4 -4
- package/dist/integrations/generators/vault.js +10 -11
- package/dist/integrations/generators/vault.ts +4 -5
- package/dist/{operations/http.d.ts → integrations/https.d.ts} +10 -6
- package/dist/integrations/https.js +170 -0
- package/dist/integrations/https.ts +216 -0
- package/dist/integrations/pglite.d.ts +26 -0
- package/dist/integrations/pglite.js +143 -0
- package/dist/integrations/pglite.ts +206 -0
- package/dist/integrations/secret.d.ts +8 -2
- package/dist/integrations/secret.js +3 -5
- package/dist/integrations/secret.ts +10 -6
- package/dist/integrations/target.d.ts +155 -14
- package/dist/integrations/target.js +171 -50
- package/dist/integrations/target.ts +377 -61
- package/dist/integrations/vault.d.ts +1 -0
- package/dist/integrations/vault.js +20 -5
- package/dist/integrations/vault.ts +17 -5
- package/dist/integrity/attach.js +8 -77
- package/dist/integrity/attach.ts +7 -76
- package/dist/integrity/check-threads.js +5 -5
- package/dist/integrity/check-threads.ts +2 -2
- package/dist/integrity/constraint.d.ts +0 -1
- package/dist/integrity/constraint.js +267 -366
- package/dist/integrity/constraint.ts +267 -375
- package/dist/integrity/generators/compiler.js +14 -17
- package/dist/integrity/generators/compiler.ts +10 -15
- package/dist/integrity/generators/gate.js +15 -15
- package/dist/integrity/generators/gate.ts +10 -10
- package/dist/integrity/generators/issues.js +7 -7
- package/dist/integrity/generators/publish.js +39 -57
- package/dist/integrity/generators/publish.ts +44 -55
- package/dist/integrity/generators/trial.d.ts +3 -3
- package/dist/integrity/generators/trial.js +133 -165
- package/dist/integrity/generators/trial.ts +145 -169
- package/dist/integrity/lint.js +9 -13
- package/dist/integrity/lint.ts +7 -10
- package/dist/integrity/lsp/bin.js +5 -4
- package/dist/integrity/lsp/bin.ts +3 -1
- package/dist/integrity/lsp/diagnostics.js +3 -3
- package/dist/integrity/lsp/diagnostics.ts +1 -1
- package/dist/integrity/lsp/lint.js +19 -30
- package/dist/integrity/lsp/lint.ts +16 -32
- package/dist/integrity/lsp/server.js +3 -3
- package/dist/integrity/slopnator.d.ts +3 -13
- package/dist/integrity/slopnator.js +59 -38
- package/dist/integrity/slopnator.ts +54 -38
- package/dist/integrity/slopnators/sl_broken_lineage.js +2 -2
- package/dist/integrity/slopnators/sl_declared_elsewhere.js +1 -1
- package/dist/integrity/slopnators/sl_derived_drift.js +4 -4
- package/dist/integrity/slopnators/sl_derived_drift.ts +1 -1
- package/dist/integrity/slopnators/sl_door_in_a_node.js +220 -0
- package/dist/integrity/slopnators/sl_door_in_a_node.ts +250 -0
- package/dist/integrity/slopnators/sl_inert_island.js +10 -8
- package/dist/integrity/slopnators/sl_inert_island.ts +8 -6
- package/dist/integrity/slopnators/sl_missing_row.js +6 -51
- package/dist/integrity/slopnators/sl_missing_row.ts +4 -50
- package/dist/integrity/slopnators/sl_no_barrel.js +1 -1
- package/dist/integrity/slopnators/sl_no_child_process.js +36 -18
- package/dist/integrity/slopnators/sl_no_child_process.ts +44 -18
- package/dist/integrity/slopnators/sl_no_dispatch_bypass.js +80 -149
- package/dist/integrity/slopnators/sl_no_dispatch_bypass.ts +95 -147
- package/dist/integrity/slopnators/sl_no_import_cycle.js +15 -4
- package/dist/integrity/slopnators/sl_no_import_cycle.ts +20 -4
- package/dist/integrity/slopnators/sl_no_such_command.js +2 -2
- package/dist/integrity/slopnators/sl_no_such_command.ts +1 -1
- package/dist/integrity/slopnators/sl_outside_an_operation.js +20 -0
- package/dist/integrity/slopnators/sl_outside_an_operation.ts +25 -0
- package/dist/integrity/slopnators/sl_screen_holds_only_declared.d.ts +2 -0
- package/dist/integrity/slopnators/sl_screen_holds_only_declared.js +61 -0
- package/dist/integrity/slopnators/sl_screen_holds_only_declared.ts +70 -0
- package/dist/integrity/slopnators/sl_secret_literal.js +1 -33
- package/dist/integrity/slopnators/sl_secret_literal.ts +1 -33
- package/dist/integrity/slopnators/sl_stale_path.js +5 -22
- package/dist/integrity/slopnators/sl_stale_path.ts +4 -20
- package/dist/integrity/slopnators/sl_twice_meant.js +1 -1
- package/dist/integrity/slopnators/sl_twice_parented.js +29 -5
- package/dist/integrity/slopnators/sl_twice_parented.ts +28 -4
- package/dist/integrity/slopnators/sl_undeclared_crossing.d.ts +4 -1
- package/dist/integrity/slopnators/sl_undeclared_crossing.js +426 -62
- package/dist/integrity/slopnators/sl_undeclared_crossing.ts +454 -70
- package/dist/integrity/slopnators/sl_undeclared_destination.js +59 -25
- package/dist/integrity/slopnators/sl_undeclared_destination.ts +69 -21
- package/dist/integrity/slopnators/sl_undeclared_list.d.ts +2 -0
- package/dist/integrity/slopnators/sl_undeclared_list.js +363 -0
- package/dist/integrity/slopnators/sl_undeclared_list.ts +358 -0
- package/dist/integrity/slopnators/sl_undeclared_node.js +1 -11
- package/dist/integrity/slopnators/sl_undeclared_node.ts +0 -10
- package/dist/integrity/slopnators/sl_undeclared_operation.js +111 -29
- package/dist/integrity/slopnators/sl_undeclared_operation.ts +134 -26
- package/dist/integrity/slopnators/sl_undeclared_variant.js +2 -2
- package/dist/integrity/slopnators/sl_undeclared_webhook.d.ts +2 -0
- package/dist/integrity/slopnators/sl_undeclared_webhook.js +90 -0
- package/dist/integrity/slopnators/sl_undeclared_webhook.ts +108 -0
- package/dist/integrity/slopnators/sl_underived_route.d.ts +2 -0
- package/dist/integrity/slopnators/sl_underived_route.js +61 -0
- package/dist/integrity/slopnators/sl_underived_route.ts +72 -0
- package/dist/integrity/slopnators/sl_ungoverned_island.js +3 -3
- package/dist/integrity/slopnators/sl_ungoverned_island.ts +1 -1
- package/dist/integrity/slopnators/sl_unlisted_program.d.ts +2 -0
- package/dist/integrity/slopnators/sl_unlisted_program.js +39 -0
- package/dist/integrity/slopnators/sl_unlisted_program.ts +40 -0
- package/dist/integrity/slopnators/sl_unnamed_island.js +1 -1
- package/dist/integrity/slopnators/sl_unpaired_member.js +3 -3
- package/dist/integrity/slopnators/sl_unpaired_member.ts +1 -1
- package/dist/integrity/slopnators/sl_unpaired_slopnator.js +4 -4
- package/dist/integrity/slopnators/sl_unpaired_slopnator.ts +1 -1
- package/dist/integrity/slopnators/sl_unprefixed_member.js +5 -31
- package/dist/integrity/slopnators/sl_unprefixed_member.ts +2 -28
- package/dist/integrity/slopnators/sl_unthreaded.js +11 -7
- package/dist/integrity/slopnators/sl_unthreaded.ts +6 -7
- package/dist/integrity/slopnators/sl_untranslated_key.js +2 -25
- package/dist/integrity/slopnators/sl_untranslated_key.ts +1 -25
- package/dist/integrity/slopnators/sl_unvaulted_secret.d.ts +2 -0
- package/dist/integrity/slopnators/sl_unvaulted_secret.js +107 -0
- package/dist/integrity/slopnators/sl_unvaulted_secret.ts +132 -0
- package/dist/integrity/slopnators/sl_unversioned.js +6 -4
- package/dist/integrity/slopnators/sl_unversioned.ts +5 -3
- package/dist/integrity/sweep.d.ts +1 -0
- package/dist/integrity/sweep.js +105 -42
- package/dist/integrity/sweep.ts +115 -42
- package/dist/knowledge/attach.js +4 -3
- package/dist/knowledge/attach.ts +3 -2
- package/dist/knowledge/generators/docsgen.js +8 -6
- package/dist/knowledge/generators/docsgen.ts +4 -2
- package/dist/knowledge/generators/glossary.js +4 -4
- package/dist/knowledge/generators/glossary.ts +1 -1
- package/dist/operations/access.d.ts +23 -0
- package/dist/operations/access.js +28 -1
- package/dist/operations/access.ts +43 -0
- package/dist/operations/attach.js +33 -113
- package/dist/operations/attach.ts +51 -117
- package/dist/operations/capabilities.d.ts +14 -5
- package/dist/operations/capabilities.js +13 -4
- package/dist/operations/capabilities.ts +27 -8
- package/dist/operations/dispatch.d.ts +8 -2
- package/dist/operations/dispatch.js +128 -185
- package/dist/operations/dispatch.ts +138 -191
- package/dist/operations/error-results.d.ts +1 -1
- package/dist/operations/error-results.js +2 -2
- package/dist/operations/error-results.ts +2 -2
- package/dist/operations/generators/capability.d.ts +11 -1
- package/dist/operations/generators/capability.js +481 -224
- package/dist/operations/generators/capability.ts +562 -233
- package/dist/operations/generators/compile.js +66 -39
- package/dist/operations/generators/compile.ts +78 -39
- package/dist/operations/generators/permits.js +11 -12
- package/dist/operations/generators/permits.ts +3 -4
- package/dist/operations/generators/seed.d.ts +1 -0
- package/dist/operations/generators/seed.js +19 -17
- package/dist/operations/generators/seed.ts +22 -14
- package/dist/operations/generators/trial.d.ts +6 -8
- package/dist/operations/generators/trial.js +200 -70
- package/dist/operations/generators/trial.ts +230 -93
- package/dist/operations/nodes.d.ts +15 -16
- package/dist/operations/nodes.ts +16 -17
- package/dist/operations/operations.d.ts +40 -4
- package/dist/operations/operations.js +1 -0
- package/dist/operations/operations.ts +61 -4
- package/dist/operations/result.d.ts +2 -2
- package/dist/operations/result.ts +2 -2
- package/package.json +1 -4
- package/dist/core/answers.d.ts +0 -171
- package/dist/core/answers.js +0 -789
- package/dist/core/answers.ts +0 -999
- package/dist/core/client.d.ts +0 -63
- package/dist/core/client.js +0 -249
- package/dist/core/client.ts +0 -289
- package/dist/core/files.js +0 -171
- package/dist/core/files.ts +0 -222
- package/dist/integrations/module.d.ts +0 -6
- package/dist/integrations/module.js +0 -153
- package/dist/integrations/module.ts +0 -191
- package/dist/integrity/slopnators/sl_unkept_rows.js +0 -104
- package/dist/integrity/slopnators/sl_unkept_rows.ts +0 -111
- package/dist/integrity/slopnators/sl_unseamed_reach.js +0 -73
- package/dist/integrity/slopnators/sl_unseamed_reach.ts +0 -79
- package/dist/operations/cost.d.ts +0 -14
- package/dist/operations/cost.js +0 -37
- package/dist/operations/cost.ts +0 -58
- package/dist/operations/errors/errors.d.ts +0 -52
- package/dist/operations/http.js +0 -124
- package/dist/operations/http.ts +0 -169
- package/dist/operations/memory.d.ts +0 -104
- package/dist/operations/memory.js +0 -365
- package/dist/operations/memory.ts +0 -470
- package/dist/operations/metering.d.ts +0 -55
- package/dist/operations/metering.js +0 -247
- package/dist/operations/metering.ts +0 -328
- package/dist/operations/queue-policy.d.ts +0 -3
- package/dist/operations/queue-policy.js +0 -8
- package/dist/operations/queue-policy.ts +0 -10
- package/dist/operations/seams.d.ts +0 -239
- package/dist/operations/seams.js +0 -45
- package/dist/operations/seams.ts +0 -364
- package/dist/operations/store.d.ts +0 -14
- package/dist/operations/store.js +0 -1
- package/dist/operations/store.ts +0 -29
- /package/dist/{operations → core}/errors/classes.d.ts +0 -0
- /package/dist/{operations → core}/errors/classes.js +0 -0
- /package/dist/{operations → core}/errors/classes.ts +0 -0
- /package/dist/integrity/slopnators/{sl_unkept_rows.d.ts → sl_door_in_a_node.d.ts} +0 -0
- /package/dist/integrity/slopnators/{sl_unseamed_reach.d.ts → sl_outside_an_operation.d.ts} +0 -0
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import * as disk from 'node:fs';
|
|
2
|
+
import { basename, dirname, isAbsolute, relative, resolve } from 'node:path';
|
|
3
|
+
import { env, pid } from 'node:process';
|
|
4
|
+
import { ORDERS } from '../integrations/target.js';
|
|
5
|
+
export const CHANNEL = 'THREAD_CHANNEL';
|
|
6
|
+
export const FOLDER = 'THREAD_FOLDER';
|
|
7
|
+
const WAITING = 180_000;
|
|
8
|
+
const WORKING = 600_000;
|
|
9
|
+
const ASKING = '-asking';
|
|
10
|
+
const ORDER = '-order';
|
|
11
|
+
const ANSWER = '-answer';
|
|
12
|
+
function overFiles(dir) {
|
|
13
|
+
const idle = new Int32Array(new SharedArrayBuffer(4));
|
|
14
|
+
let spun = 0;
|
|
15
|
+
const ask = (body) => {
|
|
16
|
+
spun += 1;
|
|
17
|
+
const name = dir + '/' + String(pid) + '-' + String(spun);
|
|
18
|
+
const long = body.order === 'fetch' ? true : body.order === 'run';
|
|
19
|
+
const waits = long ? WORKING : WAITING;
|
|
20
|
+
disk.writeFileSync(name + ASKING, JSON.stringify(body));
|
|
21
|
+
disk.renameSync(name + ASKING, name + ORDER);
|
|
22
|
+
const until = Date.now() + waits;
|
|
23
|
+
for (;;) {
|
|
24
|
+
let held = '';
|
|
25
|
+
try {
|
|
26
|
+
held = disk.readFileSync(name + ANSWER, 'utf8');
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
held = '';
|
|
30
|
+
}
|
|
31
|
+
if (held !== '') {
|
|
32
|
+
disk.rmSync(name + ANSWER, { force: true });
|
|
33
|
+
const said = JSON.parse(held);
|
|
34
|
+
if (said.answered === 'refused')
|
|
35
|
+
throw new Error(String(said.because));
|
|
36
|
+
return said;
|
|
37
|
+
}
|
|
38
|
+
if (Date.now() > until) {
|
|
39
|
+
throw new Error('nothing answered ' + body.order + ' ' + body.at + ' for ' + String(Math.round(waits / 60_000)) +
|
|
40
|
+
' minutes, so this stopped waiting rather than spinning forever. Whoever was answering is gone. ' +
|
|
41
|
+
'Nothing here is half-written: one order is one file, and it was either answered or it was not.');
|
|
42
|
+
}
|
|
43
|
+
Atomics.wait(idle, 0, 0, 2);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const took = (body) => {
|
|
47
|
+
const said = ask(body);
|
|
48
|
+
const want = ORDERS[body.order];
|
|
49
|
+
if (said.answered !== want) {
|
|
50
|
+
throw new Error(body.order + ' ' + body.at + ' was answered as ' + said.answered + ', and that order is answered as ' + want +
|
|
51
|
+
'. Whatever answered is not the copy of prestack this server sends orders to.');
|
|
52
|
+
}
|
|
53
|
+
return said;
|
|
54
|
+
};
|
|
55
|
+
const kinds = new Map();
|
|
56
|
+
const listed = new Map();
|
|
57
|
+
const reals = new Map();
|
|
58
|
+
const listing = (at) => {
|
|
59
|
+
const held = listed.get(at);
|
|
60
|
+
if (held !== undefined)
|
|
61
|
+
return held;
|
|
62
|
+
const found = took({ order: 'list', at }).found;
|
|
63
|
+
listed.set(at, found);
|
|
64
|
+
return found;
|
|
65
|
+
};
|
|
66
|
+
const kindOf = (at) => {
|
|
67
|
+
const held = kinds.get(at);
|
|
68
|
+
if (held !== undefined)
|
|
69
|
+
return held;
|
|
70
|
+
const up = dirname(at);
|
|
71
|
+
if (up !== at && across(up)) {
|
|
72
|
+
const one = kindOf(up) === 'folder' ? listing(up).find((each) => each.name === basename(at)) : undefined;
|
|
73
|
+
if (one === undefined) {
|
|
74
|
+
kinds.set(at, 'none');
|
|
75
|
+
return 'none';
|
|
76
|
+
}
|
|
77
|
+
if (one.kind !== 'other') {
|
|
78
|
+
kinds.set(at, one.kind);
|
|
79
|
+
return one.kind;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const found = took({ order: 'kind', at }).found;
|
|
83
|
+
kinds.set(at, found);
|
|
84
|
+
return found;
|
|
85
|
+
};
|
|
86
|
+
const wrote = (at) => {
|
|
87
|
+
kinds.set(at, 'file');
|
|
88
|
+
for (let child = at, up = dirname(at); up !== child && across(up); child = up, up = dirname(up)) {
|
|
89
|
+
const inside = listed.get(up);
|
|
90
|
+
if (inside !== undefined && !inside.some((each) => each.name === basename(child))) {
|
|
91
|
+
listed.set(up, [...inside, { name: basename(child), kind: child === at ? 'file' : 'folder' }]);
|
|
92
|
+
}
|
|
93
|
+
kinds.set(up, 'folder');
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const removed = (at) => {
|
|
97
|
+
for (const key of [...kinds.keys()])
|
|
98
|
+
if (key.startsWith(at + '/'))
|
|
99
|
+
kinds.delete(key);
|
|
100
|
+
for (const key of [...listed.keys()])
|
|
101
|
+
if (key === at || key.startsWith(at + '/'))
|
|
102
|
+
listed.delete(key);
|
|
103
|
+
reals.clear();
|
|
104
|
+
kinds.set(at, 'none');
|
|
105
|
+
const inside = listed.get(dirname(at));
|
|
106
|
+
if (inside !== undefined)
|
|
107
|
+
listed.set(dirname(at), inside.filter((each) => each.name !== basename(at)));
|
|
108
|
+
};
|
|
109
|
+
const unknown = () => {
|
|
110
|
+
kinds.clear();
|
|
111
|
+
listed.clear();
|
|
112
|
+
reals.clear();
|
|
113
|
+
};
|
|
114
|
+
return {
|
|
115
|
+
kind: kindOf,
|
|
116
|
+
read: (at) => String(took({ order: 'read', at }).said),
|
|
117
|
+
write: (at, said, mode) => {
|
|
118
|
+
took(mode === undefined ? { order: 'write', at, said } : { order: 'write', at, said, mode });
|
|
119
|
+
wrote(at);
|
|
120
|
+
},
|
|
121
|
+
list: listing,
|
|
122
|
+
stat: (at) => took({ order: 'stat', at }).found,
|
|
123
|
+
remove: (at) => {
|
|
124
|
+
took({ order: 'remove', at });
|
|
125
|
+
removed(at);
|
|
126
|
+
},
|
|
127
|
+
real: (at) => {
|
|
128
|
+
const held = reals.get(at);
|
|
129
|
+
if (held !== undefined)
|
|
130
|
+
return held;
|
|
131
|
+
const found = String(took({ order: 'real', at }).at);
|
|
132
|
+
reals.set(at, found);
|
|
133
|
+
return found;
|
|
134
|
+
},
|
|
135
|
+
fetch: (at) => {
|
|
136
|
+
try {
|
|
137
|
+
return String(took({ order: 'fetch', at }).said);
|
|
138
|
+
}
|
|
139
|
+
finally {
|
|
140
|
+
unknown();
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
run: (at, words) => {
|
|
144
|
+
try {
|
|
145
|
+
return took({ order: 'run', at, words }).found;
|
|
146
|
+
}
|
|
147
|
+
finally {
|
|
148
|
+
unknown();
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const seam = {};
|
|
154
|
+
const WHERE = env[CHANNEL];
|
|
155
|
+
if (WHERE !== undefined && WHERE !== '')
|
|
156
|
+
seam.held = overFiles(WHERE);
|
|
157
|
+
export function answeredBy(one) {
|
|
158
|
+
seam.held = one;
|
|
159
|
+
}
|
|
160
|
+
const placed = (at) => {
|
|
161
|
+
const root = env[FOLDER] ?? '';
|
|
162
|
+
return root === '' ? at : resolve(root, at);
|
|
163
|
+
};
|
|
164
|
+
const within = (root, at) => {
|
|
165
|
+
const step = relative(resolve(root), resolve(root, at));
|
|
166
|
+
return step === '' || (!step.startsWith('..') && !isAbsolute(step));
|
|
167
|
+
};
|
|
168
|
+
export function across(at) {
|
|
169
|
+
const root = env[FOLDER] ?? '';
|
|
170
|
+
return seam.held !== undefined && root !== '' && within(root, at);
|
|
171
|
+
}
|
|
172
|
+
export function beyond(at) {
|
|
173
|
+
const root = env[FOLDER] ?? '';
|
|
174
|
+
return seam.held !== undefined && root !== '' && !within(root, at);
|
|
175
|
+
}
|
|
176
|
+
function asked(at) {
|
|
177
|
+
const one = seam.held;
|
|
178
|
+
if (one === undefined)
|
|
179
|
+
return undefined;
|
|
180
|
+
const root = env[FOLDER] ?? '';
|
|
181
|
+
if (root === '')
|
|
182
|
+
return typeof at === 'string' ? one : undefined;
|
|
183
|
+
if (typeof at !== 'string') {
|
|
184
|
+
throw new Error('a path given as anything but text cannot be held to ' + root + ', the folder this answers for, so it was not used.');
|
|
185
|
+
}
|
|
186
|
+
if (within(root, at))
|
|
187
|
+
return one;
|
|
188
|
+
throw new Error(at + ' is outside ' + root + ', the folder this answers for. A command answering for a folder on another machine ' +
|
|
189
|
+
'reaches that folder and nothing else, so nothing was read, written or removed.');
|
|
190
|
+
}
|
|
191
|
+
export function attached() {
|
|
192
|
+
return seam.held !== undefined;
|
|
193
|
+
}
|
|
194
|
+
export function here() {
|
|
195
|
+
return seam.held ?? HERE;
|
|
196
|
+
}
|
|
197
|
+
export function kind(at) {
|
|
198
|
+
const one = asked(at);
|
|
199
|
+
return one === undefined ? HERE.kind(at) : one.kind(placed(at));
|
|
200
|
+
}
|
|
201
|
+
export function existsSync(at) {
|
|
202
|
+
return typeof at === 'string' ? kind(at) !== 'none' : asked(at) === undefined && disk.existsSync(at);
|
|
203
|
+
}
|
|
204
|
+
export function readFileSync(at, how) {
|
|
205
|
+
const one = asked(at);
|
|
206
|
+
return one === undefined ? disk.readFileSync(at, how ?? 'utf8') : one.read(placed(at));
|
|
207
|
+
}
|
|
208
|
+
export function writeFileSync(at, said, how) {
|
|
209
|
+
const held = how === undefined || typeof how === 'string' ? { encoding: how, mode: undefined } : how;
|
|
210
|
+
const one = asked(at);
|
|
211
|
+
if (one !== undefined) {
|
|
212
|
+
one.write(placed(at), said, held.mode);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (typeof at === 'string')
|
|
216
|
+
disk.mkdirSync(dirname(at), { recursive: true });
|
|
217
|
+
disk.writeFileSync(at, said, { encoding: held.encoding ?? 'utf8', ...(held.mode === undefined ? {} : { mode: held.mode }) });
|
|
218
|
+
}
|
|
219
|
+
export function createFileSync(at, said) {
|
|
220
|
+
if (asked(at) !== undefined) {
|
|
221
|
+
throw new Error(at + ' is on a machine that answers orders, and only a file on this machine can be created for one command alone.');
|
|
222
|
+
}
|
|
223
|
+
disk.mkdirSync(dirname(at), { recursive: true });
|
|
224
|
+
try {
|
|
225
|
+
disk.writeFileSync(at, said, { encoding: 'utf8', flag: 'wx' });
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
catch (thrown) {
|
|
229
|
+
if (thrown.code === 'EEXIST')
|
|
230
|
+
return false;
|
|
231
|
+
throw thrown;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
export function readdirSync(at, how) {
|
|
235
|
+
const one = asked(at);
|
|
236
|
+
if (one === undefined)
|
|
237
|
+
return how === undefined ? disk.readdirSync(at) : disk.readdirSync(at, how);
|
|
238
|
+
const held = one.list(placed(at));
|
|
239
|
+
return how === undefined
|
|
240
|
+
? held.map((each) => each.name)
|
|
241
|
+
: held.map((each) => ({ name: each.name, isFile: () => each.kind === 'file', isDirectory: () => each.kind === 'folder' }));
|
|
242
|
+
}
|
|
243
|
+
export function statSync(at, how) {
|
|
244
|
+
const one = asked(at);
|
|
245
|
+
if (one === undefined)
|
|
246
|
+
return (how === undefined ? disk.statSync(at) : disk.statSync(at, how));
|
|
247
|
+
const path = placed(at);
|
|
248
|
+
const held = one.kind(path);
|
|
249
|
+
if (held === 'none') {
|
|
250
|
+
if (how !== undefined)
|
|
251
|
+
return undefined;
|
|
252
|
+
throw new Error(`${path} is not there, so nothing can be said about it.`);
|
|
253
|
+
}
|
|
254
|
+
const measured = one.stat(path);
|
|
255
|
+
return {
|
|
256
|
+
name: path,
|
|
257
|
+
size: measured.size,
|
|
258
|
+
modified: measured.modified,
|
|
259
|
+
mtimeMs: measured.modified,
|
|
260
|
+
isFile: () => held === 'file',
|
|
261
|
+
isDirectory: () => held === 'folder',
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
export function rmSync(at, how) {
|
|
265
|
+
const one = asked(at);
|
|
266
|
+
if (one === undefined)
|
|
267
|
+
disk.rmSync(at, how);
|
|
268
|
+
else
|
|
269
|
+
one.remove(placed(at));
|
|
270
|
+
}
|
|
271
|
+
export function rmdirSync(at) {
|
|
272
|
+
const one = asked(at);
|
|
273
|
+
if (one === undefined)
|
|
274
|
+
disk.rmdirSync(at);
|
|
275
|
+
else
|
|
276
|
+
one.remove(placed(at));
|
|
277
|
+
}
|
|
278
|
+
export function renameSync(from, to) {
|
|
279
|
+
const one = asked(from);
|
|
280
|
+
if (one === undefined) {
|
|
281
|
+
if (typeof to === 'string')
|
|
282
|
+
disk.mkdirSync(dirname(to), { recursive: true });
|
|
283
|
+
disk.renameSync(from, to);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
asked(to);
|
|
287
|
+
one.write(placed(to), one.read(placed(from)));
|
|
288
|
+
one.remove(placed(from));
|
|
289
|
+
}
|
|
290
|
+
export function appendFileSync(at, said) {
|
|
291
|
+
const one = asked(at);
|
|
292
|
+
if (one === undefined) {
|
|
293
|
+
disk.appendFileSync(at, said);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
const path = placed(at);
|
|
297
|
+
one.write(path, `${one.kind(path) === 'none' ? '' : one.read(path)}${said}`);
|
|
298
|
+
}
|
|
299
|
+
export function realpathSync(at) {
|
|
300
|
+
const one = asked(at);
|
|
301
|
+
return one === undefined ? disk.realpathSync(at) : one.real(placed(at));
|
|
302
|
+
}
|
|
303
|
+
const FILES_ONLY = ' is on this disk, and a disk holds files. ';
|
|
304
|
+
export const HERE = {
|
|
305
|
+
kind: (at) => {
|
|
306
|
+
let held;
|
|
307
|
+
try {
|
|
308
|
+
held = disk.statSync(at, { throwIfNoEntry: false });
|
|
309
|
+
}
|
|
310
|
+
catch (thrown) {
|
|
311
|
+
if (thrown.code === 'ERR_ACCESS_DENIED')
|
|
312
|
+
return 'none';
|
|
313
|
+
throw thrown;
|
|
314
|
+
}
|
|
315
|
+
if (held === undefined)
|
|
316
|
+
return 'none';
|
|
317
|
+
return held.isFile() ? 'file' : held.isDirectory() ? 'folder' : 'other';
|
|
318
|
+
},
|
|
319
|
+
read: (at) => disk.readFileSync(at, 'utf8'),
|
|
320
|
+
write: (at, said, mode) => {
|
|
321
|
+
disk.mkdirSync(dirname(at), { recursive: true });
|
|
322
|
+
disk.writeFileSync(at, said, { encoding: 'utf8', ...(mode === undefined ? {} : { mode }) });
|
|
323
|
+
},
|
|
324
|
+
list: (at) => disk.readdirSync(at, { withFileTypes: true }).map((one) => ({
|
|
325
|
+
name: one.name,
|
|
326
|
+
kind: one.isFile() ? 'file' : one.isDirectory() ? 'folder' : 'other',
|
|
327
|
+
})),
|
|
328
|
+
stat: (at) => {
|
|
329
|
+
const held = disk.statSync(at);
|
|
330
|
+
return { size: held.size, modified: held.mtimeMs };
|
|
331
|
+
},
|
|
332
|
+
remove: (at) => {
|
|
333
|
+
if (disk.lstatSync(at, { throwIfNoEntry: false })?.isDirectory() === true)
|
|
334
|
+
disk.rmdirSync(at);
|
|
335
|
+
else
|
|
336
|
+
disk.rmSync(at);
|
|
337
|
+
},
|
|
338
|
+
real: (at) => disk.realpathSync(at),
|
|
339
|
+
fetch: (at) => {
|
|
340
|
+
throw new Error(at + FILES_ONLY + 'Installing what a tree depends on happens where somebody typed the command, so it cannot be ordered of this disk.');
|
|
341
|
+
},
|
|
342
|
+
run: (at) => {
|
|
343
|
+
throw new Error(at + FILES_ONLY + 'A program is started where somebody typed the command, so running one cannot be ordered of this disk.');
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
const GONE = 'is not in the scenario this trial stands, and while it runs the scenario is the whole tree.';
|
|
347
|
+
const MADE_UP = 'a trial answers orders against a tree it made up, so there is nowhere here to ';
|
|
348
|
+
export function standing(root, given) {
|
|
349
|
+
const flat = (at) => {
|
|
350
|
+
let path = at;
|
|
351
|
+
while (path.length > 1 && path.endsWith('/'))
|
|
352
|
+
path = path.slice(0, -1);
|
|
353
|
+
return path;
|
|
354
|
+
};
|
|
355
|
+
const under = (at) => at.startsWith(root) || `${at}/` === root;
|
|
356
|
+
const own = (at) => under(at) && !at.slice(root.length).split('/').includes('node_modules');
|
|
357
|
+
const beside = (at) => {
|
|
358
|
+
try {
|
|
359
|
+
return HERE.list(at);
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
return [];
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
const held = new Map(given);
|
|
366
|
+
const folders = new Set();
|
|
367
|
+
const parents = (at) => {
|
|
368
|
+
for (let up = dirname(at); under(`${up}/`); up = dirname(up))
|
|
369
|
+
folders.add(up);
|
|
370
|
+
};
|
|
371
|
+
for (const at of held.keys())
|
|
372
|
+
parents(at);
|
|
373
|
+
const answers = {
|
|
374
|
+
kind: (at) => (held.has(at) ? 'file' : folders.has(at) ? 'folder' : own(at) ? 'none' : HERE.kind(at)),
|
|
375
|
+
read: (at) => {
|
|
376
|
+
const said = held.get(at);
|
|
377
|
+
if (said !== undefined)
|
|
378
|
+
return said;
|
|
379
|
+
if (own(at))
|
|
380
|
+
throw new Error(`${at} ${GONE}`);
|
|
381
|
+
return HERE.read(at);
|
|
382
|
+
},
|
|
383
|
+
write: (at, said) => {
|
|
384
|
+
held.set(at, said);
|
|
385
|
+
parents(at);
|
|
386
|
+
},
|
|
387
|
+
list: (at) => {
|
|
388
|
+
const inside = new Map();
|
|
389
|
+
const found = own(at) ? [] : folders.has(at) ? beside(at) : HERE.list(at);
|
|
390
|
+
for (const one of found)
|
|
391
|
+
inside.set(one.name, { name: one.name, kind: one.kind === 'folder' ? 'folder' : 'file' });
|
|
392
|
+
for (const path of folders)
|
|
393
|
+
if (dirname(path) === at)
|
|
394
|
+
inside.set(basename(path), { name: basename(path), kind: 'folder' });
|
|
395
|
+
for (const path of held.keys())
|
|
396
|
+
if (dirname(path) === at)
|
|
397
|
+
inside.set(basename(path), { name: basename(path), kind: 'file' });
|
|
398
|
+
return [...inside.values()];
|
|
399
|
+
},
|
|
400
|
+
stat: (at) => {
|
|
401
|
+
const said = held.get(at);
|
|
402
|
+
if (said !== undefined)
|
|
403
|
+
return { size: said.length, modified: 0 };
|
|
404
|
+
if (folders.has(at))
|
|
405
|
+
return { size: 0, modified: 0 };
|
|
406
|
+
if (own(at))
|
|
407
|
+
throw new Error(`${at} ${GONE}`);
|
|
408
|
+
return HERE.stat(at);
|
|
409
|
+
},
|
|
410
|
+
remove: (at) => {
|
|
411
|
+
held.delete(at);
|
|
412
|
+
folders.delete(at);
|
|
413
|
+
},
|
|
414
|
+
real: (at) => (own(at) || held.has(at) || folders.has(at) ? at : HERE.real(at)),
|
|
415
|
+
};
|
|
416
|
+
return {
|
|
417
|
+
kind: (at) => answers.kind(flat(at)),
|
|
418
|
+
read: (at) => answers.read(flat(at)),
|
|
419
|
+
write: (at, said) => {
|
|
420
|
+
answers.write(flat(at), said);
|
|
421
|
+
},
|
|
422
|
+
list: (at) => answers.list(flat(at)),
|
|
423
|
+
stat: (at) => answers.stat(flat(at)),
|
|
424
|
+
remove: (at) => {
|
|
425
|
+
answers.remove(flat(at));
|
|
426
|
+
},
|
|
427
|
+
real: (at) => answers.real(flat(at)),
|
|
428
|
+
fetch: () => {
|
|
429
|
+
throw new Error(MADE_UP + 'install anything into.');
|
|
430
|
+
},
|
|
431
|
+
run: () => {
|
|
432
|
+
throw new Error(MADE_UP + 'run anything in.');
|
|
433
|
+
},
|
|
434
|
+
};
|
|
435
|
+
}
|