@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.
Files changed (270) hide show
  1. package/CHANGELOG.md +563 -0
  2. package/dist/core/actor.d.ts +1 -1
  3. package/dist/core/actor.js +5 -4
  4. package/dist/core/actor.ts +5 -4
  5. package/dist/core/attach.d.ts +0 -7
  6. package/dist/core/attach.js +38 -67
  7. package/dist/core/attach.ts +34 -80
  8. package/dist/core/chain.js +13 -17
  9. package/dist/core/chain.ts +11 -15
  10. package/dist/core/condition.d.ts +4 -4
  11. package/dist/core/condition.js +2 -2
  12. package/dist/core/descend.d.ts +4 -2
  13. package/dist/core/descend.js +91 -23
  14. package/dist/core/descend.ts +90 -21
  15. package/dist/core/errors/catalogue.d.ts +52 -0
  16. package/dist/{operations/errors/errors.js → core/errors/catalogue.js} +1 -1
  17. package/dist/{operations/errors/errors.ts → core/errors/catalogue.ts} +1 -1
  18. package/dist/{operations/errors/catalog.d.ts → core/errors/error.d.ts} +2 -3
  19. package/dist/{operations/errors/catalog.js → core/errors/error.js} +1 -16
  20. package/dist/{operations/errors/catalog.ts → core/errors/error.ts} +3 -19
  21. package/dist/core/errors/namespaces.d.ts +3 -0
  22. package/dist/core/errors/namespaces.js +15 -0
  23. package/dist/core/errors/namespaces.ts +19 -0
  24. package/dist/core/finding.js +2 -2
  25. package/dist/core/finding.ts +1 -2
  26. package/dist/core/init.d.ts +1 -1
  27. package/dist/core/init.js +51 -5
  28. package/dist/core/init.ts +58 -5
  29. package/dist/core/invoked.d.ts +1 -1
  30. package/dist/core/invoked.js +3 -1
  31. package/dist/core/invoked.ts +5 -2
  32. package/dist/core/round.js +36 -22
  33. package/dist/core/round.ts +26 -9
  34. package/dist/core/rows.d.ts +4 -0
  35. package/dist/core/rows.js +31 -2
  36. package/dist/core/rows.ts +33 -1
  37. package/dist/core/scope.d.ts +1 -0
  38. package/dist/core/scope.js +1 -0
  39. package/dist/core/scope.ts +2 -0
  40. package/dist/core/thread.d.ts +3 -3
  41. package/dist/core/tree.d.ts +4 -1
  42. package/dist/core/tree.js +26 -6
  43. package/dist/core/tree.ts +29 -6
  44. package/dist/core/types.d.ts +3 -3
  45. package/dist/core/types.js +3 -1
  46. package/dist/core/types.ts +2 -1
  47. package/dist/derivation/attach.js +3 -2
  48. package/dist/derivation/attach.ts +2 -1
  49. package/dist/derivation/generators/build.js +6 -6
  50. package/dist/derivation/generators/build.ts +1 -1
  51. package/dist/derivation/generators/check.js +1 -1
  52. package/dist/derivation/generators/determinism.js +1 -1
  53. package/dist/derivation/generators/release.js +60 -47
  54. package/dist/derivation/generators/release.ts +66 -43
  55. package/dist/derivation/release.d.ts +7 -3
  56. package/dist/derivation/release.js +14 -1
  57. package/dist/derivation/release.ts +22 -2
  58. package/dist/integrations/attach.d.ts +4 -0
  59. package/dist/integrations/attach.js +37 -56
  60. package/dist/integrations/attach.ts +54 -60
  61. package/dist/integrations/cli.d.ts +37 -0
  62. package/dist/integrations/cli.js +440 -0
  63. package/dist/integrations/cli.ts +543 -0
  64. package/dist/{core/files.d.ts → integrations/disk.d.ts} +16 -24
  65. package/dist/integrations/disk.js +435 -0
  66. package/dist/integrations/disk.ts +465 -0
  67. package/dist/integrations/generators/read.js +6 -6
  68. package/dist/integrations/generators/read.ts +4 -4
  69. package/dist/integrations/generators/vault.js +10 -11
  70. package/dist/integrations/generators/vault.ts +4 -5
  71. package/dist/{operations/http.d.ts → integrations/https.d.ts} +10 -6
  72. package/dist/integrations/https.js +170 -0
  73. package/dist/integrations/https.ts +216 -0
  74. package/dist/integrations/pglite.d.ts +26 -0
  75. package/dist/integrations/pglite.js +143 -0
  76. package/dist/integrations/pglite.ts +206 -0
  77. package/dist/integrations/secret.d.ts +8 -2
  78. package/dist/integrations/secret.js +3 -5
  79. package/dist/integrations/secret.ts +10 -6
  80. package/dist/integrations/target.d.ts +155 -14
  81. package/dist/integrations/target.js +171 -50
  82. package/dist/integrations/target.ts +377 -61
  83. package/dist/integrations/vault.d.ts +1 -0
  84. package/dist/integrations/vault.js +20 -5
  85. package/dist/integrations/vault.ts +17 -5
  86. package/dist/integrity/attach.js +8 -77
  87. package/dist/integrity/attach.ts +7 -76
  88. package/dist/integrity/check-threads.js +5 -5
  89. package/dist/integrity/check-threads.ts +2 -2
  90. package/dist/integrity/constraint.d.ts +0 -1
  91. package/dist/integrity/constraint.js +267 -366
  92. package/dist/integrity/constraint.ts +267 -375
  93. package/dist/integrity/generators/compiler.js +14 -17
  94. package/dist/integrity/generators/compiler.ts +10 -15
  95. package/dist/integrity/generators/gate.js +15 -15
  96. package/dist/integrity/generators/gate.ts +10 -10
  97. package/dist/integrity/generators/issues.js +7 -7
  98. package/dist/integrity/generators/publish.js +39 -57
  99. package/dist/integrity/generators/publish.ts +44 -55
  100. package/dist/integrity/generators/trial.d.ts +3 -3
  101. package/dist/integrity/generators/trial.js +133 -165
  102. package/dist/integrity/generators/trial.ts +145 -169
  103. package/dist/integrity/lint.js +9 -13
  104. package/dist/integrity/lint.ts +7 -10
  105. package/dist/integrity/lsp/bin.js +5 -4
  106. package/dist/integrity/lsp/bin.ts +3 -1
  107. package/dist/integrity/lsp/diagnostics.js +3 -3
  108. package/dist/integrity/lsp/diagnostics.ts +1 -1
  109. package/dist/integrity/lsp/lint.js +19 -30
  110. package/dist/integrity/lsp/lint.ts +16 -32
  111. package/dist/integrity/lsp/server.js +3 -3
  112. package/dist/integrity/slopnator.d.ts +3 -13
  113. package/dist/integrity/slopnator.js +59 -38
  114. package/dist/integrity/slopnator.ts +54 -38
  115. package/dist/integrity/slopnators/sl_broken_lineage.js +2 -2
  116. package/dist/integrity/slopnators/sl_declared_elsewhere.js +1 -1
  117. package/dist/integrity/slopnators/sl_derived_drift.js +4 -4
  118. package/dist/integrity/slopnators/sl_derived_drift.ts +1 -1
  119. package/dist/integrity/slopnators/sl_door_in_a_node.js +220 -0
  120. package/dist/integrity/slopnators/sl_door_in_a_node.ts +250 -0
  121. package/dist/integrity/slopnators/sl_inert_island.js +10 -8
  122. package/dist/integrity/slopnators/sl_inert_island.ts +8 -6
  123. package/dist/integrity/slopnators/sl_missing_row.js +6 -51
  124. package/dist/integrity/slopnators/sl_missing_row.ts +4 -50
  125. package/dist/integrity/slopnators/sl_no_barrel.js +1 -1
  126. package/dist/integrity/slopnators/sl_no_child_process.js +36 -18
  127. package/dist/integrity/slopnators/sl_no_child_process.ts +44 -18
  128. package/dist/integrity/slopnators/sl_no_dispatch_bypass.js +80 -149
  129. package/dist/integrity/slopnators/sl_no_dispatch_bypass.ts +95 -147
  130. package/dist/integrity/slopnators/sl_no_import_cycle.js +15 -4
  131. package/dist/integrity/slopnators/sl_no_import_cycle.ts +20 -4
  132. package/dist/integrity/slopnators/sl_no_such_command.js +2 -2
  133. package/dist/integrity/slopnators/sl_no_such_command.ts +1 -1
  134. package/dist/integrity/slopnators/sl_outside_an_operation.js +20 -0
  135. package/dist/integrity/slopnators/sl_outside_an_operation.ts +25 -0
  136. package/dist/integrity/slopnators/sl_screen_holds_only_declared.d.ts +2 -0
  137. package/dist/integrity/slopnators/sl_screen_holds_only_declared.js +61 -0
  138. package/dist/integrity/slopnators/sl_screen_holds_only_declared.ts +70 -0
  139. package/dist/integrity/slopnators/sl_secret_literal.js +1 -33
  140. package/dist/integrity/slopnators/sl_secret_literal.ts +1 -33
  141. package/dist/integrity/slopnators/sl_stale_path.js +5 -22
  142. package/dist/integrity/slopnators/sl_stale_path.ts +4 -20
  143. package/dist/integrity/slopnators/sl_twice_meant.js +1 -1
  144. package/dist/integrity/slopnators/sl_twice_parented.js +29 -5
  145. package/dist/integrity/slopnators/sl_twice_parented.ts +28 -4
  146. package/dist/integrity/slopnators/sl_undeclared_crossing.d.ts +4 -1
  147. package/dist/integrity/slopnators/sl_undeclared_crossing.js +426 -62
  148. package/dist/integrity/slopnators/sl_undeclared_crossing.ts +454 -70
  149. package/dist/integrity/slopnators/sl_undeclared_destination.js +59 -25
  150. package/dist/integrity/slopnators/sl_undeclared_destination.ts +69 -21
  151. package/dist/integrity/slopnators/sl_undeclared_list.d.ts +2 -0
  152. package/dist/integrity/slopnators/sl_undeclared_list.js +363 -0
  153. package/dist/integrity/slopnators/sl_undeclared_list.ts +358 -0
  154. package/dist/integrity/slopnators/sl_undeclared_node.js +1 -11
  155. package/dist/integrity/slopnators/sl_undeclared_node.ts +0 -10
  156. package/dist/integrity/slopnators/sl_undeclared_operation.js +111 -29
  157. package/dist/integrity/slopnators/sl_undeclared_operation.ts +134 -26
  158. package/dist/integrity/slopnators/sl_undeclared_variant.js +2 -2
  159. package/dist/integrity/slopnators/sl_undeclared_webhook.d.ts +2 -0
  160. package/dist/integrity/slopnators/sl_undeclared_webhook.js +90 -0
  161. package/dist/integrity/slopnators/sl_undeclared_webhook.ts +108 -0
  162. package/dist/integrity/slopnators/sl_underived_route.d.ts +2 -0
  163. package/dist/integrity/slopnators/sl_underived_route.js +61 -0
  164. package/dist/integrity/slopnators/sl_underived_route.ts +72 -0
  165. package/dist/integrity/slopnators/sl_ungoverned_island.js +3 -3
  166. package/dist/integrity/slopnators/sl_ungoverned_island.ts +1 -1
  167. package/dist/integrity/slopnators/sl_unlisted_program.d.ts +2 -0
  168. package/dist/integrity/slopnators/sl_unlisted_program.js +39 -0
  169. package/dist/integrity/slopnators/sl_unlisted_program.ts +40 -0
  170. package/dist/integrity/slopnators/sl_unnamed_island.js +1 -1
  171. package/dist/integrity/slopnators/sl_unpaired_member.js +3 -3
  172. package/dist/integrity/slopnators/sl_unpaired_member.ts +1 -1
  173. package/dist/integrity/slopnators/sl_unpaired_slopnator.js +4 -4
  174. package/dist/integrity/slopnators/sl_unpaired_slopnator.ts +1 -1
  175. package/dist/integrity/slopnators/sl_unprefixed_member.js +5 -31
  176. package/dist/integrity/slopnators/sl_unprefixed_member.ts +2 -28
  177. package/dist/integrity/slopnators/sl_unthreaded.js +11 -7
  178. package/dist/integrity/slopnators/sl_unthreaded.ts +6 -7
  179. package/dist/integrity/slopnators/sl_untranslated_key.js +2 -25
  180. package/dist/integrity/slopnators/sl_untranslated_key.ts +1 -25
  181. package/dist/integrity/slopnators/sl_unvaulted_secret.d.ts +2 -0
  182. package/dist/integrity/slopnators/sl_unvaulted_secret.js +107 -0
  183. package/dist/integrity/slopnators/sl_unvaulted_secret.ts +132 -0
  184. package/dist/integrity/slopnators/sl_unversioned.js +6 -4
  185. package/dist/integrity/slopnators/sl_unversioned.ts +5 -3
  186. package/dist/integrity/sweep.d.ts +1 -0
  187. package/dist/integrity/sweep.js +105 -42
  188. package/dist/integrity/sweep.ts +115 -42
  189. package/dist/knowledge/attach.js +4 -3
  190. package/dist/knowledge/attach.ts +3 -2
  191. package/dist/knowledge/generators/docsgen.js +8 -6
  192. package/dist/knowledge/generators/docsgen.ts +4 -2
  193. package/dist/knowledge/generators/glossary.js +4 -4
  194. package/dist/knowledge/generators/glossary.ts +1 -1
  195. package/dist/operations/access.d.ts +23 -0
  196. package/dist/operations/access.js +28 -1
  197. package/dist/operations/access.ts +43 -0
  198. package/dist/operations/attach.js +33 -113
  199. package/dist/operations/attach.ts +51 -117
  200. package/dist/operations/capabilities.d.ts +14 -5
  201. package/dist/operations/capabilities.js +13 -4
  202. package/dist/operations/capabilities.ts +27 -8
  203. package/dist/operations/dispatch.d.ts +8 -2
  204. package/dist/operations/dispatch.js +128 -185
  205. package/dist/operations/dispatch.ts +138 -191
  206. package/dist/operations/error-results.d.ts +1 -1
  207. package/dist/operations/error-results.js +2 -2
  208. package/dist/operations/error-results.ts +2 -2
  209. package/dist/operations/generators/capability.d.ts +11 -1
  210. package/dist/operations/generators/capability.js +481 -224
  211. package/dist/operations/generators/capability.ts +562 -233
  212. package/dist/operations/generators/compile.js +66 -39
  213. package/dist/operations/generators/compile.ts +78 -39
  214. package/dist/operations/generators/permits.js +11 -12
  215. package/dist/operations/generators/permits.ts +3 -4
  216. package/dist/operations/generators/seed.d.ts +1 -0
  217. package/dist/operations/generators/seed.js +19 -17
  218. package/dist/operations/generators/seed.ts +22 -14
  219. package/dist/operations/generators/trial.d.ts +6 -8
  220. package/dist/operations/generators/trial.js +200 -70
  221. package/dist/operations/generators/trial.ts +230 -93
  222. package/dist/operations/nodes.d.ts +15 -16
  223. package/dist/operations/nodes.ts +16 -17
  224. package/dist/operations/operations.d.ts +40 -4
  225. package/dist/operations/operations.js +1 -0
  226. package/dist/operations/operations.ts +61 -4
  227. package/dist/operations/result.d.ts +2 -2
  228. package/dist/operations/result.ts +2 -2
  229. package/package.json +1 -4
  230. package/dist/core/answers.d.ts +0 -171
  231. package/dist/core/answers.js +0 -789
  232. package/dist/core/answers.ts +0 -999
  233. package/dist/core/client.d.ts +0 -63
  234. package/dist/core/client.js +0 -249
  235. package/dist/core/client.ts +0 -289
  236. package/dist/core/files.js +0 -171
  237. package/dist/core/files.ts +0 -222
  238. package/dist/integrations/module.d.ts +0 -6
  239. package/dist/integrations/module.js +0 -153
  240. package/dist/integrations/module.ts +0 -191
  241. package/dist/integrity/slopnators/sl_unkept_rows.js +0 -104
  242. package/dist/integrity/slopnators/sl_unkept_rows.ts +0 -111
  243. package/dist/integrity/slopnators/sl_unseamed_reach.js +0 -73
  244. package/dist/integrity/slopnators/sl_unseamed_reach.ts +0 -79
  245. package/dist/operations/cost.d.ts +0 -14
  246. package/dist/operations/cost.js +0 -37
  247. package/dist/operations/cost.ts +0 -58
  248. package/dist/operations/errors/errors.d.ts +0 -52
  249. package/dist/operations/http.js +0 -124
  250. package/dist/operations/http.ts +0 -169
  251. package/dist/operations/memory.d.ts +0 -104
  252. package/dist/operations/memory.js +0 -365
  253. package/dist/operations/memory.ts +0 -470
  254. package/dist/operations/metering.d.ts +0 -55
  255. package/dist/operations/metering.js +0 -247
  256. package/dist/operations/metering.ts +0 -328
  257. package/dist/operations/queue-policy.d.ts +0 -3
  258. package/dist/operations/queue-policy.js +0 -8
  259. package/dist/operations/queue-policy.ts +0 -10
  260. package/dist/operations/seams.d.ts +0 -239
  261. package/dist/operations/seams.js +0 -45
  262. package/dist/operations/seams.ts +0 -364
  263. package/dist/operations/store.d.ts +0 -14
  264. package/dist/operations/store.js +0 -1
  265. package/dist/operations/store.ts +0 -29
  266. /package/dist/{operations → core}/errors/classes.d.ts +0 -0
  267. /package/dist/{operations → core}/errors/classes.js +0 -0
  268. /package/dist/{operations → core}/errors/classes.ts +0 -0
  269. /package/dist/integrity/slopnators/{sl_unkept_rows.d.ts → sl_door_in_a_node.d.ts} +0 -0
  270. /package/dist/integrity/slopnators/{sl_unseamed_reach.d.ts → sl_outside_an_operation.d.ts} +0 -0
@@ -1,171 +0,0 @@
1
- import { spawnSync } from 'node:child_process';
2
- import * as disk from 'node:fs';
3
- import { dirname, join } from 'node:path';
4
- const CHANNEL = 'THREAD_CHANNEL';
5
- const WAITING = 180000;
6
- function overFiles(dir) {
7
- const idle = new Int32Array(new SharedArrayBuffer(4));
8
- let spun = 0;
9
- const ask = (body) => {
10
- spun += 1;
11
- const name = `${dir}/${String(process.pid)}-${String(spun)}`;
12
- disk.writeFileSync(`${name}.asking`, JSON.stringify(body));
13
- disk.renameSync(`${name}.asking`, `${name}.order`);
14
- const until = Date.now() + WAITING;
15
- for (;;) {
16
- let held;
17
- try {
18
- held = disk.readFileSync(`${name}.answer`, 'utf8');
19
- }
20
- catch {
21
- held = undefined;
22
- }
23
- if (held !== undefined) {
24
- disk.rmSync(`${name}.answer`, { force: true });
25
- const said = JSON.parse(held);
26
- if (said.answered === 'refused')
27
- throw new Error(String(said.because));
28
- return said;
29
- }
30
- if (Date.now() > until)
31
- throw new Error('nothing answered ' +
32
- String(body.order) +
33
- ' ' +
34
- String(body.at) +
35
- ' for three minutes, so this stopped waiting rather than spinning forever. Whoever was answering is gone. It waits longer than a server waits before giving up on a run, on purpose: if an answer were still coming it would have arrived. Nothing here is half-written — one order is one file, and it was either answered or it was not.');
36
- Atomics.wait(idle, 0, 0, 2);
37
- }
38
- };
39
- return {
40
- kind: (at) => ask({ order: 'kind', at }).held,
41
- read: (at) => ask({ order: 'read', at }).said,
42
- write: (at, said) => {
43
- ask({ order: 'write', at, said });
44
- },
45
- list: (at) => ask({ order: 'list', at }).held,
46
- stat: (at) => ask({ order: 'stat', at }).held,
47
- remove: (at) => {
48
- ask({ order: 'remove', at });
49
- },
50
- real: (at) => ask({ order: 'real', at }).at,
51
- fetch: (at) => ask({ order: 'fetch', at }).said,
52
- };
53
- }
54
- const WHERE = process.env[CHANNEL];
55
- let answering = WHERE !== undefined && WHERE !== '' ? overFiles(WHERE) : undefined;
56
- export function answeredBy(one) {
57
- answering = one;
58
- }
59
- const asked = (at) => (typeof at === 'string' ? answering : undefined);
60
- export function attached() {
61
- return answering !== undefined;
62
- }
63
- export function kind(at) {
64
- const one = answering;
65
- if (one !== undefined)
66
- return one.kind(at);
67
- const held = disk.statSync(at, { throwIfNoEntry: false });
68
- if (held === undefined)
69
- return 'none';
70
- return held.isFile() ? 'file' : held.isDirectory() ? 'folder' : 'other';
71
- }
72
- export function existsSync(at) {
73
- return typeof at === 'string' ? kind(at) !== 'none' : disk.existsSync(at);
74
- }
75
- export function readFileSync(at, how) {
76
- const one = asked(at);
77
- return one === undefined ? disk.readFileSync(at, how ?? 'utf8') : one.read(at);
78
- }
79
- export function writeFileSync(at, said, how) {
80
- const one = asked(at);
81
- if (one !== undefined) {
82
- one.write(at, said);
83
- return;
84
- }
85
- if (typeof at === 'string')
86
- disk.mkdirSync(dirname(at), { recursive: true });
87
- disk.writeFileSync(at, said, how ?? 'utf8');
88
- }
89
- export function readdirSync(at, how) {
90
- const one = asked(at);
91
- if (one === undefined)
92
- return how === undefined ? disk.readdirSync(at) : disk.readdirSync(at, how);
93
- const held = one.list(at);
94
- return how === undefined
95
- ? held.map((each) => each.name)
96
- : held.map((each) => ({ name: each.name, isFile: () => each.kind === 'file', isDirectory: () => each.kind === 'folder' }));
97
- }
98
- export function statSync(at, how) {
99
- const one = asked(at);
100
- if (one === undefined)
101
- return (how === undefined ? disk.statSync(at) : disk.statSync(at, how));
102
- const path = at;
103
- const held = one.kind(path);
104
- if (held === 'none') {
105
- if (how !== undefined)
106
- return undefined;
107
- throw new Error(`${path} is not there, so nothing can be said about it.`);
108
- }
109
- const measured = one.stat(path);
110
- return {
111
- name: path,
112
- size: measured.size,
113
- modified: measured.modified,
114
- mtimeMs: measured.modified,
115
- isFile: () => held === 'file',
116
- isDirectory: () => held === 'folder',
117
- };
118
- }
119
- export function rmSync(at, how) {
120
- const one = asked(at);
121
- if (one === undefined)
122
- disk.rmSync(at, how);
123
- else
124
- one.remove(at);
125
- }
126
- export function renameSync(from, to) {
127
- const one = asked(from);
128
- if (one === undefined) {
129
- disk.renameSync(from, to);
130
- return;
131
- }
132
- one.write(to, one.read(from));
133
- one.remove(from);
134
- }
135
- export function appendFileSync(at, said) {
136
- const one = asked(at);
137
- if (one === undefined) {
138
- disk.appendFileSync(at, said);
139
- return;
140
- }
141
- const path = at;
142
- one.write(path, `${one.kind(path) === 'none' ? '' : one.read(path)}${said}`);
143
- }
144
- export function realpathSync(at) {
145
- const one = asked(at);
146
- return one === undefined ? disk.realpathSync(at) : one.real(at);
147
- }
148
- export function manager(into) {
149
- if (disk.existsSync(join(into, 'pnpm-lock.yaml')))
150
- return ['pnpm', 'add'];
151
- if (disk.existsSync(join(into, 'yarn.lock')))
152
- return ['yarn', 'add'];
153
- if (disk.existsSync(join(into, 'bun.lockb')))
154
- return ['bun', 'add'];
155
- return ['npm', 'install'];
156
- }
157
- export function installing(at) {
158
- const tool = manager(at)[0] ?? 'npm';
159
- const ran = spawnSync(tool, ['install'], { cwd: at, encoding: 'utf8', shell: false });
160
- const said = `${ran.stdout ?? ''}${ran.stderr ?? ''}`.trim();
161
- if (ran.error !== undefined)
162
- throw new Error(`${tool} is not on this machine, so what ${at} depends on cannot be fetched. Put ${tool} on this machine, ` +
163
- 'or take away the lockfile that picked it and another one is used.');
164
- if (ran.status !== 0)
165
- throw new Error(`${tool} could not install what ${at} depends on. It said: ${said === '' ? `nothing, and exited ${String(ran.status)}` : said}`);
166
- return said;
167
- }
168
- export function fetching(at) {
169
- const one = answering;
170
- return one === undefined ? installing(at) : one.fetch(at);
171
- }
@@ -1,222 +0,0 @@
1
- import { spawnSync } from 'node:child_process'
2
- import * as disk from 'node:fs'
3
- import { dirname, join } from 'node:path'
4
-
5
- export type Kind = 'file' | 'folder' | 'other' | 'none'
6
-
7
- export interface Listed {
8
- readonly name: string
9
- readonly kind: Exclude<Kind, 'none'>
10
- }
11
-
12
- export interface Measured {
13
- readonly size: number
14
- readonly modified: number
15
- }
16
-
17
- export interface Answering {
18
- readonly kind: (at: string) => Kind
19
- readonly read: (at: string) => string
20
- readonly write: (at: string, said: string) => void
21
- readonly list: (at: string) => readonly Listed[]
22
- readonly stat: (at: string) => Measured
23
- readonly remove: (at: string) => void
24
- readonly real: (at: string) => string
25
- readonly fetch: (at: string) => string
26
- }
27
-
28
- const CHANNEL = 'THREAD_CHANNEL'
29
-
30
- const WAITING = 180000
31
-
32
- function overFiles(dir: string): Answering {
33
- const idle = new Int32Array(new SharedArrayBuffer(4))
34
- let spun = 0
35
-
36
- const ask = (body: Readonly<Record<string, unknown>>): Readonly<Record<string, unknown>> => {
37
- spun += 1
38
- const name = `${dir}/${String(process.pid)}-${String(spun)}`
39
- disk.writeFileSync(`${name}.asking`, JSON.stringify(body))
40
- disk.renameSync(`${name}.asking`, `${name}.order`)
41
- const until = Date.now() + WAITING
42
- for (;;) {
43
- let held: string | undefined
44
- try {
45
- held = disk.readFileSync(`${name}.answer`, 'utf8')
46
- } catch {
47
- held = undefined
48
- }
49
- if (held !== undefined) {
50
- disk.rmSync(`${name}.answer`, { force: true })
51
- const said = JSON.parse(held) as Readonly<Record<string, unknown>>
52
- if (said.answered === 'refused') throw new Error(String(said.because))
53
- return said
54
- }
55
- if (Date.now() > until)
56
- throw new Error(
57
- 'nothing answered ' +
58
- String(body.order) +
59
- ' ' +
60
- String(body.at) +
61
- ' for three minutes, so this stopped waiting rather than spinning forever. Whoever was answering is gone. It waits longer than a server waits before giving up on a run, on purpose: if an answer were still coming it would have arrived. Nothing here is half-written — one order is one file, and it was either answered or it was not.',
62
- )
63
- Atomics.wait(idle, 0, 0, 2)
64
- }
65
- }
66
-
67
- return {
68
- kind: (at) => ask({ order: 'kind', at }).held as Kind,
69
- read: (at) => ask({ order: 'read', at }).said as string,
70
- write: (at, said) => {
71
- ask({ order: 'write', at, said })
72
- },
73
- list: (at) => ask({ order: 'list', at }).held as readonly Listed[],
74
- stat: (at) => ask({ order: 'stat', at }).held as Measured,
75
- remove: (at) => {
76
- ask({ order: 'remove', at })
77
- },
78
- real: (at) => ask({ order: 'real', at }).at as string,
79
- fetch: (at) => ask({ order: 'fetch', at }).said as string,
80
- }
81
- }
82
-
83
- const WHERE = process.env[CHANNEL]
84
-
85
- let answering: Answering | undefined = WHERE !== undefined && WHERE !== '' ? overFiles(WHERE) : undefined
86
-
87
- export function answeredBy(one: Answering | undefined): void {
88
- answering = one
89
- }
90
-
91
- const asked = (at: unknown): Answering | undefined => (typeof at === 'string' ? answering : undefined)
92
-
93
- export function attached(): boolean {
94
- return answering !== undefined
95
- }
96
-
97
- export function kind(at: string): Kind {
98
- const one = answering
99
- if (one !== undefined) return one.kind(at)
100
- const held = disk.statSync(at, { throwIfNoEntry: false })
101
- if (held === undefined) return 'none'
102
- return held.isFile() ? 'file' : held.isDirectory() ? 'folder' : 'other'
103
- }
104
-
105
- export function existsSync(at: disk.PathLike): boolean {
106
- return typeof at === 'string' ? kind(at) !== 'none' : disk.existsSync(at)
107
- }
108
-
109
- export function readFileSync(at: disk.PathOrFileDescriptor, how?: BufferEncoding): string {
110
- const one = asked(at)
111
- return one === undefined ? disk.readFileSync(at, how ?? 'utf8') : one.read(at as string)
112
- }
113
-
114
- export function writeFileSync(at: disk.PathOrFileDescriptor, said: string, how?: BufferEncoding): void {
115
- const one = asked(at)
116
- if (one !== undefined) {
117
- one.write(at as string, said)
118
- return
119
- }
120
- if (typeof at === 'string') disk.mkdirSync(dirname(at), { recursive: true })
121
- disk.writeFileSync(at, said, how ?? 'utf8')
122
- }
123
-
124
- export interface Named {
125
- readonly name: string
126
- readonly isFile: () => boolean
127
- readonly isDirectory: () => boolean
128
- }
129
-
130
- export function readdirSync(at: disk.PathLike): string[]
131
- export function readdirSync(at: disk.PathLike, how: { readonly withFileTypes: true }): readonly Named[]
132
- export function readdirSync(at: disk.PathLike, how?: { readonly withFileTypes: true }): string[] | readonly Named[] {
133
- const one = asked(at)
134
- if (one === undefined) return how === undefined ? disk.readdirSync(at) : disk.readdirSync(at, how)
135
- const held = one.list(at as string)
136
- return how === undefined
137
- ? held.map((each) => each.name)
138
- : held.map((each) => ({ name: each.name, isFile: () => each.kind === 'file', isDirectory: () => each.kind === 'folder' }))
139
- }
140
-
141
- export interface Held extends Named, Measured {
142
- readonly mtimeMs: number
143
- }
144
-
145
- export function statSync(at: disk.PathLike): Held
146
- export function statSync(at: disk.PathLike, how: { readonly throwIfNoEntry: false }): Held | undefined
147
- export function statSync(at: disk.PathLike, how?: { readonly throwIfNoEntry: false }): Held | undefined {
148
- const one = asked(at)
149
- if (one === undefined) return (how === undefined ? disk.statSync(at) : disk.statSync(at, how)) as Held | undefined
150
- const path = at as string
151
- const held = one.kind(path)
152
- if (held === 'none') {
153
- if (how !== undefined) return undefined
154
- throw new Error(`${path} is not there, so nothing can be said about it.`)
155
- }
156
- const measured = one.stat(path)
157
- return {
158
- name: path,
159
- size: measured.size,
160
- modified: measured.modified,
161
- mtimeMs: measured.modified,
162
- isFile: () => held === 'file',
163
- isDirectory: () => held === 'folder',
164
- }
165
- }
166
-
167
- export function rmSync(at: disk.PathLike, how?: disk.RmOptions): void {
168
- const one = asked(at)
169
- if (one === undefined) disk.rmSync(at, how)
170
- else one.remove(at as string)
171
- }
172
-
173
- export function renameSync(from: disk.PathLike, to: disk.PathLike): void {
174
- const one = asked(from)
175
- if (one === undefined) {
176
- disk.renameSync(from, to)
177
- return
178
- }
179
- one.write(to as string, one.read(from as string))
180
- one.remove(from as string)
181
- }
182
-
183
- export function appendFileSync(at: disk.PathOrFileDescriptor, said: string): void {
184
- const one = asked(at)
185
- if (one === undefined) {
186
- disk.appendFileSync(at, said)
187
- return
188
- }
189
- const path = at as string
190
- one.write(path, `${one.kind(path) === 'none' ? '' : one.read(path)}${said}`)
191
- }
192
-
193
- export function realpathSync(at: disk.PathLike): string {
194
- const one = asked(at)
195
- return one === undefined ? disk.realpathSync(at as string) : one.real(at as string)
196
- }
197
-
198
- export function manager(into: string): readonly string[] {
199
- if (disk.existsSync(join(into, 'pnpm-lock.yaml'))) return ['pnpm', 'add']
200
- if (disk.existsSync(join(into, 'yarn.lock'))) return ['yarn', 'add']
201
- if (disk.existsSync(join(into, 'bun.lockb'))) return ['bun', 'add']
202
- return ['npm', 'install']
203
- }
204
-
205
- export function installing(at: string): string {
206
- const tool = manager(at)[0] ?? 'npm'
207
- const ran = spawnSync(tool, ['install'], { cwd: at, encoding: 'utf8', shell: false })
208
- const said = `${ran.stdout ?? ''}${ran.stderr ?? ''}`.trim()
209
- if (ran.error !== undefined)
210
- throw new Error(
211
- `${tool} is not on this machine, so what ${at} depends on cannot be fetched. Put ${tool} on this machine, ` +
212
- 'or take away the lockfile that picked it and another one is used.',
213
- )
214
- if (ran.status !== 0)
215
- throw new Error(`${tool} could not install what ${at} depends on. It said: ${said === '' ? `nothing, and exited ${String(ran.status)}` : said}`)
216
- return said
217
- }
218
-
219
- export function fetching(at: string): string {
220
- const one = answering
221
- return one === undefined ? installing(at) : one.fetch(at)
222
- }
@@ -1,6 +0,0 @@
1
- export declare function ran(name: string): Promise<void>;
2
- export declare function run(declared: {
3
- readonly name: string;
4
- readonly module: string;
5
- readonly requires: readonly string[];
6
- }): Promise<void>;
@@ -1,153 +0,0 @@
1
- var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
- if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
- return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
- return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
- });
6
- }
7
- return path;
8
- };
9
- import { spawnSync } from 'node:child_process';
10
- import { argv, stderr, stdout } from 'node:process';
11
- import { answer, asking, given, unasked, wordsIn } from "../core/answers.js";
12
- import { readFileSync } from "../core/files.js";
13
- import { exit } from "../core/invoked.js";
14
- import { valuesIn } from "../core/rows.js";
15
- import { findTree, inTree } from "../core/tree.js";
16
- import { REACH, reachOf } from "./target.js";
17
- import { opened } from "./vault.js";
18
- const PRODUCTION = '--production';
19
- const METHOD = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/;
20
- function isClass(fn) {
21
- return /^class[\s{]/.test(Function.prototype.toString.call(fn));
22
- }
23
- const ASKS = [
24
- {
25
- key: 'args',
26
- says: 'a JSON value — an array for positional arguments, anything else for one, blank for none',
27
- },
28
- ];
29
- const TAKES = ASKS.map((one) => one.key);
30
- const ASKED = ASKS.map((one) => `\`${one.key}\`: ${one.says}`);
31
- export async function ran(name) {
32
- const say = (because) => {
33
- stderr.write(`${name}: ${because}\n`);
34
- exit(1);
35
- };
36
- const tree = findTree();
37
- let targets = [];
38
- try {
39
- const taken = valuesIn(readFileSync(inTree(tree, 'targets.ts')));
40
- targets = taken.TARGETS ?? [];
41
- }
42
- catch {
43
- return say('`_threads/targets.ts` could not be read, so nothing says what this integration is.');
44
- }
45
- const mine = targets.find((one) => one.id === `${REACH.cli}${name}` || one.id === `${REACH.module}${name}`);
46
- if (mine === undefined) {
47
- return say(`no target called \`${REACH.cli}${name}\` or \`${REACH.module}${name}\` is declared here, so this command should ` +
48
- 'not exist. Declare it with `thread create target`, or take its row out of `_threads/derivation.ts`.');
49
- }
50
- const does = mine.offers ?? [];
51
- const passed = argv.slice(2);
52
- const sub = passed[0];
53
- if (sub === undefined) {
54
- stdout.write(`${name}: ${mine.describes}\n\n${String(does.length)} command(s), read off \`${mine.uses ?? ''}\` when \`${mine.id}\` was declared:\n` +
55
- `${does.join(', ') || '(none were readable — name them with `thread create target edit`)'}\n\n` +
56
- `thread run ${name} <command> [anything else] — arguments and flags reach \`${mine.uses ?? ''}\` untouched.\n` +
57
- `It takes ${String(ASKED.length)} answer(s): ${ASKED.join('; ')}.\n`);
58
- exit(0);
59
- }
60
- if (!does.includes(sub)) {
61
- return say(`\`${sub}\` is not one of the ${String(does.length)} command(s) \`${mine.uses ?? ''}\` stated when \`${mine.id}\` ` +
62
- `was declared. It declared: ${does.join(', ') || '(nothing)'}. If the tool has changed, read it again with ` +
63
- `\`thread create target edit ${mine.id}\`.`);
64
- }
65
- if (reachOf(mine.id) === 'module') {
66
- return run({ name, module: mine.uses ?? '', requires: mine.requires });
67
- }
68
- const went = spawnSync(mine.uses ?? '', passed, { cwd: tree.at, stdio: 'inherit' });
69
- exit(went.status ?? 1);
70
- }
71
- export async function run(declared) {
72
- const refuse = (because) => {
73
- stderr.write(`${declared.name}: ${because}\n`);
74
- exit(1);
75
- };
76
- const method = wordsIn([])[0];
77
- if (method === undefined) {
78
- return refuse(`takes the method to call, dot-separated for a namespaced one — e.g. \`thread run ${declared.name} customers.list\`.`);
79
- }
80
- if (!METHOD.test(method)) {
81
- return refuse(`\`${method}\` is not a method path — one name, or names joined by dots, e.g. \`customers.list\``);
82
- }
83
- const piped = given();
84
- unasked(piped, TAKES, `\`thread run ${declared.name} ${method}\``);
85
- const { ask, shut } = asking(piped);
86
- const typed = (piped.length > 0
87
- ? (answer(piped, TAKES[0] ?? 'args') ?? '')
88
- : await ask('args', 'args, as JSON — an array for positional arguments, anything else for one (blank for none): ')).trim();
89
- shut();
90
- let args = [];
91
- if (typed !== '') {
92
- let parsed;
93
- try {
94
- parsed = JSON.parse(typed);
95
- }
96
- catch (thrown) {
97
- return refuse(`that is not JSON: ${thrown instanceof Error ? thrown.message : String(thrown)}. Nothing was called.`);
98
- }
99
- args = Array.isArray(parsed) ? parsed : [parsed];
100
- }
101
- const env = argv.includes(PRODUCTION) ? 'production' : 'sandbox';
102
- const opening = opened(findTree().at, declared.requires, env);
103
- let resolved;
104
- try {
105
- resolved = await opening(declared.requires);
106
- }
107
- catch (thrown) {
108
- return refuse(thrown instanceof Error ? thrown.message : String(thrown));
109
- }
110
- const credentials = declared.requires.map((one) => resolved[one] ?? '');
111
- let mod;
112
- try {
113
- mod = (await import(__rewriteRelativeImportExtension(declared.module)));
114
- }
115
- catch (thrown) {
116
- return refuse(`\`${declared.module}\` could not be imported: ${thrown instanceof Error ? thrown.message : String(thrown)}. It was ` +
117
- `installed when this was declared — if it is gone, \`npm install ${declared.module}\` puts it back.`);
118
- }
119
- const entry = mod.default ?? mod;
120
- const asFunction = entry;
121
- const asConstructor = entry;
122
- const REACHES = new Set(['constructor', '__proto__', 'prototype']);
123
- const client = typeof entry !== 'function' ? entry : isClass(asFunction) ? Reflect.construct(asConstructor, credentials) : asFunction(...credentials);
124
- let owner = client;
125
- let target = client;
126
- for (const segment of method.split('.')) {
127
- if (REACHES.has(segment)) {
128
- return refuse(`\`${segment}\` is not an operation of \`${declared.module}\` — it is a step every JavaScript value has, and ` +
129
- 'walking to it leaves what was installed. What may run here is what the module exports, and a person fixed that ' +
130
- 'set when they declared it.');
131
- }
132
- owner = target;
133
- target = target?.[segment];
134
- }
135
- if (typeof target !== 'function') {
136
- return refuse(`\`${method}\` on \`${declared.module}\` is ${target === undefined ? 'nothing' : `a ${typeof target}`}, not a method that can be called`);
137
- }
138
- let result;
139
- try {
140
- result = await target.apply(owner, args);
141
- }
142
- catch (thrown) {
143
- return refuse(`\`${method}\` on \`${declared.module}\` threw: ${thrown instanceof Error ? thrown.message : String(thrown)}`);
144
- }
145
- stdout.write(`${declared.name}: ${method} (${env})\n`);
146
- try {
147
- stdout.write(`${JSON.stringify(result, null, 2)}\n`);
148
- }
149
- catch {
150
- stdout.write(`${String(result)}\n`);
151
- }
152
- exit(0);
153
- }