@prestack/thread 0.0.1

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 (248) hide show
  1. package/CHANGELOG.md +192 -0
  2. package/dist/attach.d.ts +1 -0
  3. package/dist/attach.js +1 -0
  4. package/dist/core/actor.d.ts +12 -0
  5. package/dist/core/actor.js +8 -0
  6. package/dist/core/asking.d.ts +180 -0
  7. package/dist/core/asking.js +1109 -0
  8. package/dist/core/attach.d.ts +54 -0
  9. package/dist/core/attach.js +510 -0
  10. package/dist/core/chain.d.ts +16 -0
  11. package/dist/core/chain.js +114 -0
  12. package/dist/core/cli.d.ts +2 -0
  13. package/dist/core/cli.js +1682 -0
  14. package/dist/core/condition.d.ts +52 -0
  15. package/dist/core/condition.js +198 -0
  16. package/dist/core/descend.d.ts +81 -0
  17. package/dist/core/descend.js +879 -0
  18. package/dist/core/finding.d.ts +12 -0
  19. package/dist/core/finding.js +23 -0
  20. package/dist/core/generators/meta.d.ts +2 -0
  21. package/dist/core/generators/meta.js +823 -0
  22. package/dist/core/init.d.ts +15 -0
  23. package/dist/core/init.js +134 -0
  24. package/dist/core/invoked.d.ts +9 -0
  25. package/dist/core/invoked.js +41 -0
  26. package/dist/core/round.d.ts +1 -0
  27. package/dist/core/round.js +57 -0
  28. package/dist/core/rows.d.ts +26 -0
  29. package/dist/core/rows.js +354 -0
  30. package/dist/core/scope.d.ts +6 -0
  31. package/dist/core/scope.js +12 -0
  32. package/dist/core/thread.d.ts +26 -0
  33. package/dist/core/thread.js +5 -0
  34. package/dist/core/tree.d.ts +12 -0
  35. package/dist/core/tree.js +56 -0
  36. package/dist/core/types.d.ts +49 -0
  37. package/dist/core/types.js +311 -0
  38. package/dist/derivation/attach.d.ts +2 -0
  39. package/dist/derivation/attach.js +61 -0
  40. package/dist/derivation/generators/build.d.ts +16 -0
  41. package/dist/derivation/generators/build.js +217 -0
  42. package/dist/derivation/generators/check.d.ts +18 -0
  43. package/dist/derivation/generators/check.js +78 -0
  44. package/dist/derivation/generators/derivation.d.ts +3 -0
  45. package/dist/derivation/generators/derivation.js +273 -0
  46. package/dist/derivation/generators/determinism.d.ts +20 -0
  47. package/dist/derivation/generators/determinism.js +110 -0
  48. package/dist/derivation/generators/release.d.ts +3 -0
  49. package/dist/derivation/generators/release.js +183 -0
  50. package/dist/derivation/makers/release.d.ts +1 -0
  51. package/dist/derivation/makers/release.js +107 -0
  52. package/dist/derivation/release.d.ts +10 -0
  53. package/dist/derivation/release.js +12 -0
  54. package/dist/integrations/attach.d.ts +6 -0
  55. package/dist/integrations/attach.js +177 -0
  56. package/dist/integrations/generators/read.d.ts +1 -0
  57. package/dist/integrations/generators/read.js +92 -0
  58. package/dist/integrations/generators/sdk.d.ts +1 -0
  59. package/dist/integrations/generators/sdk.js +148 -0
  60. package/dist/integrations/generators/secret.d.ts +1 -0
  61. package/dist/integrations/generators/secret.js +233 -0
  62. package/dist/integrations/generators/target.d.ts +1 -0
  63. package/dist/integrations/generators/target.js +765 -0
  64. package/dist/integrations/generators/vault.d.ts +1 -0
  65. package/dist/integrations/generators/vault.js +164 -0
  66. package/dist/integrations/sdk.d.ts +6 -0
  67. package/dist/integrations/sdk.js +151 -0
  68. package/dist/integrations/secret.d.ts +16 -0
  69. package/dist/integrations/secret.js +30 -0
  70. package/dist/integrations/target.d.ts +49 -0
  71. package/dist/integrations/target.js +225 -0
  72. package/dist/integrations/vault.d.ts +12 -0
  73. package/dist/integrations/vault.js +104 -0
  74. package/dist/integrity/attach.d.ts +2 -0
  75. package/dist/integrity/attach.js +213 -0
  76. package/dist/integrity/check-threads.d.ts +10 -0
  77. package/dist/integrity/check-threads.js +153 -0
  78. package/dist/integrity/constraint.d.ts +16 -0
  79. package/dist/integrity/constraint.js +1105 -0
  80. package/dist/integrity/generators/compiler.d.ts +1 -0
  81. package/dist/integrity/generators/compiler.js +130 -0
  82. package/dist/integrity/generators/gate.d.ts +1 -0
  83. package/dist/integrity/generators/gate.js +172 -0
  84. package/dist/integrity/generators/issues.d.ts +1 -0
  85. package/dist/integrity/generators/issues.js +100 -0
  86. package/dist/integrity/generators/publish.d.ts +1 -0
  87. package/dist/integrity/generators/publish.js +186 -0
  88. package/dist/integrity/generators/rule.d.ts +2 -0
  89. package/dist/integrity/generators/rule.js +213 -0
  90. package/dist/integrity/generators/seal.d.ts +4 -0
  91. package/dist/integrity/generators/seal.js +101 -0
  92. package/dist/integrity/generators/trial.d.ts +39 -0
  93. package/dist/integrity/generators/trial.js +254 -0
  94. package/dist/integrity/lint.d.ts +50 -0
  95. package/dist/integrity/lint.js +161 -0
  96. package/dist/integrity/lsp/bin.d.ts +2 -0
  97. package/dist/integrity/lsp/bin.js +35 -0
  98. package/dist/integrity/lsp/diagnostics.d.ts +25 -0
  99. package/dist/integrity/lsp/diagnostics.js +57 -0
  100. package/dist/integrity/lsp/findings.d.ts +20 -0
  101. package/dist/integrity/lsp/findings.js +39 -0
  102. package/dist/integrity/lsp/lint.d.ts +7 -0
  103. package/dist/integrity/lsp/lint.js +95 -0
  104. package/dist/integrity/lsp/protocol.d.ts +20 -0
  105. package/dist/integrity/lsp/protocol.js +57 -0
  106. package/dist/integrity/lsp/server.d.ts +15 -0
  107. package/dist/integrity/lsp/server.js +171 -0
  108. package/dist/integrity/sealed.d.ts +1 -0
  109. package/dist/integrity/sealed.js +56 -0
  110. package/dist/integrity/slopnator.d.ts +90 -0
  111. package/dist/integrity/slopnator.js +267 -0
  112. package/dist/integrity/slopnators/sl_broken_lineage.d.ts +2 -0
  113. package/dist/integrity/slopnators/sl_broken_lineage.js +35 -0
  114. package/dist/integrity/slopnators/sl_declared_elsewhere.d.ts +2 -0
  115. package/dist/integrity/slopnators/sl_declared_elsewhere.js +33 -0
  116. package/dist/integrity/slopnators/sl_derived_drift.d.ts +8 -0
  117. package/dist/integrity/slopnators/sl_derived_drift.js +91 -0
  118. package/dist/integrity/slopnators/sl_hardcoded_style.d.ts +2 -0
  119. package/dist/integrity/slopnators/sl_hardcoded_style.js +46 -0
  120. package/dist/integrity/slopnators/sl_inert_island.d.ts +2 -0
  121. package/dist/integrity/slopnators/sl_inert_island.js +85 -0
  122. package/dist/integrity/slopnators/sl_inert_slopnator.d.ts +2 -0
  123. package/dist/integrity/slopnators/sl_inert_slopnator.js +76 -0
  124. package/dist/integrity/slopnators/sl_missing_row.d.ts +2 -0
  125. package/dist/integrity/slopnators/sl_missing_row.js +180 -0
  126. package/dist/integrity/slopnators/sl_no_barrel.d.ts +2 -0
  127. package/dist/integrity/slopnators/sl_no_barrel.js +41 -0
  128. package/dist/integrity/slopnators/sl_no_child_process.d.ts +2 -0
  129. package/dist/integrity/slopnators/sl_no_child_process.js +61 -0
  130. package/dist/integrity/slopnators/sl_no_comment.d.ts +2 -0
  131. package/dist/integrity/slopnators/sl_no_comment.js +41 -0
  132. package/dist/integrity/slopnators/sl_no_dispatch_bypass.d.ts +2 -0
  133. package/dist/integrity/slopnators/sl_no_dispatch_bypass.js +301 -0
  134. package/dist/integrity/slopnators/sl_no_import_cycle.d.ts +2 -0
  135. package/dist/integrity/slopnators/sl_no_import_cycle.js +42 -0
  136. package/dist/integrity/slopnators/sl_no_such_command.d.ts +2 -0
  137. package/dist/integrity/slopnators/sl_no_such_command.js +55 -0
  138. package/dist/integrity/slopnators/sl_only_takes_a_literal.d.ts +2 -0
  139. package/dist/integrity/slopnators/sl_only_takes_a_literal.js +59 -0
  140. package/dist/integrity/slopnators/sl_secret_literal.d.ts +2 -0
  141. package/dist/integrity/slopnators/sl_secret_literal.js +89 -0
  142. package/dist/integrity/slopnators/sl_stale_path.d.ts +2 -0
  143. package/dist/integrity/slopnators/sl_stale_path.js +92 -0
  144. package/dist/integrity/slopnators/sl_twice_meant.d.ts +2 -0
  145. package/dist/integrity/slopnators/sl_twice_meant.js +30 -0
  146. package/dist/integrity/slopnators/sl_twice_parented.d.ts +2 -0
  147. package/dist/integrity/slopnators/sl_twice_parented.js +34 -0
  148. package/dist/integrity/slopnators/sl_undeclared_crossing.d.ts +2 -0
  149. package/dist/integrity/slopnators/sl_undeclared_crossing.js +78 -0
  150. package/dist/integrity/slopnators/sl_undeclared_destination.d.ts +2 -0
  151. package/dist/integrity/slopnators/sl_undeclared_destination.js +56 -0
  152. package/dist/integrity/slopnators/sl_undeclared_element.d.ts +2 -0
  153. package/dist/integrity/slopnators/sl_undeclared_element.js +34 -0
  154. package/dist/integrity/slopnators/sl_undeclared_node.d.ts +2 -0
  155. package/dist/integrity/slopnators/sl_undeclared_node.js +59 -0
  156. package/dist/integrity/slopnators/sl_undeclared_operation.d.ts +2 -0
  157. package/dist/integrity/slopnators/sl_undeclared_operation.js +120 -0
  158. package/dist/integrity/slopnators/sl_undeclared_variant.d.ts +2 -0
  159. package/dist/integrity/slopnators/sl_undeclared_variant.js +117 -0
  160. package/dist/integrity/slopnators/sl_undescribed.d.ts +2 -0
  161. package/dist/integrity/slopnators/sl_undescribed.js +54 -0
  162. package/dist/integrity/slopnators/sl_ungoverned_island.d.ts +2 -0
  163. package/dist/integrity/slopnators/sl_ungoverned_island.js +58 -0
  164. package/dist/integrity/slopnators/sl_unkept_rows.d.ts +2 -0
  165. package/dist/integrity/slopnators/sl_unkept_rows.js +104 -0
  166. package/dist/integrity/slopnators/sl_unnamed_island.d.ts +2 -0
  167. package/dist/integrity/slopnators/sl_unnamed_island.js +37 -0
  168. package/dist/integrity/slopnators/sl_unpaired_member.d.ts +2 -0
  169. package/dist/integrity/slopnators/sl_unpaired_member.js +114 -0
  170. package/dist/integrity/slopnators/sl_unpaired_slopnator.d.ts +2 -0
  171. package/dist/integrity/slopnators/sl_unpaired_slopnator.js +60 -0
  172. package/dist/integrity/slopnators/sl_unprefixed_member.d.ts +2 -0
  173. package/dist/integrity/slopnators/sl_unprefixed_member.js +126 -0
  174. package/dist/integrity/slopnators/sl_unseamed_reach.d.ts +2 -0
  175. package/dist/integrity/slopnators/sl_unseamed_reach.js +73 -0
  176. package/dist/integrity/slopnators/sl_unthreaded.d.ts +56 -0
  177. package/dist/integrity/slopnators/sl_unthreaded.js +352 -0
  178. package/dist/integrity/slopnators/sl_untranslated_key.d.ts +2 -0
  179. package/dist/integrity/slopnators/sl_untranslated_key.js +157 -0
  180. package/dist/integrity/slopnators/sl_unversioned.d.ts +2 -0
  181. package/dist/integrity/slopnators/sl_unversioned.js +31 -0
  182. package/dist/integrity/sweep.d.ts +24 -0
  183. package/dist/integrity/sweep.js +264 -0
  184. package/dist/knowledge/attach.d.ts +2 -0
  185. package/dist/knowledge/attach.js +339 -0
  186. package/dist/knowledge/generators/docsgen.d.ts +1 -0
  187. package/dist/knowledge/generators/docsgen.js +145 -0
  188. package/dist/knowledge/generators/glossary.d.ts +1 -0
  189. package/dist/knowledge/generators/glossary.js +56 -0
  190. package/dist/knowledge/generators/skills.d.ts +1 -0
  191. package/dist/knowledge/generators/skills.js +222 -0
  192. package/dist/knowledge/glossary.d.ts +6 -0
  193. package/dist/knowledge/glossary.js +1 -0
  194. package/dist/operations/access.d.ts +27 -0
  195. package/dist/operations/access.js +61 -0
  196. package/dist/operations/attach.d.ts +6 -0
  197. package/dist/operations/attach.js +414 -0
  198. package/dist/operations/capabilities.d.ts +37 -0
  199. package/dist/operations/capabilities.js +35 -0
  200. package/dist/operations/cost.d.ts +14 -0
  201. package/dist/operations/cost.js +37 -0
  202. package/dist/operations/dispatch.d.ts +14 -0
  203. package/dist/operations/dispatch.js +327 -0
  204. package/dist/operations/error-results.d.ts +4 -0
  205. package/dist/operations/error-results.js +25 -0
  206. package/dist/operations/errors/catalog.d.ts +58 -0
  207. package/dist/operations/errors/catalog.js +91 -0
  208. package/dist/operations/errors/classes.d.ts +73 -0
  209. package/dist/operations/errors/classes.js +22 -0
  210. package/dist/operations/errors/errors.d.ts +52 -0
  211. package/dist/operations/errors/errors.js +257 -0
  212. package/dist/operations/generators/capability.d.ts +5 -0
  213. package/dist/operations/generators/capability.js +603 -0
  214. package/dist/operations/generators/compile.d.ts +2 -0
  215. package/dist/operations/generators/compile.js +541 -0
  216. package/dist/operations/generators/grant.d.ts +1 -0
  217. package/dist/operations/generators/grant.js +267 -0
  218. package/dist/operations/generators/operation.d.ts +1 -0
  219. package/dist/operations/generators/operation.js +811 -0
  220. package/dist/operations/generators/permits.d.ts +1 -0
  221. package/dist/operations/generators/permits.js +196 -0
  222. package/dist/operations/generators/seed.d.ts +20 -0
  223. package/dist/operations/generators/seed.js +285 -0
  224. package/dist/operations/generators/trial.d.ts +53 -0
  225. package/dist/operations/generators/trial.js +376 -0
  226. package/dist/operations/http.d.ts +30 -0
  227. package/dist/operations/http.js +121 -0
  228. package/dist/operations/makers/capability.d.ts +1 -0
  229. package/dist/operations/makers/capability.js +117 -0
  230. package/dist/operations/makers/trial.d.ts +1 -0
  231. package/dist/operations/makers/trial.js +413 -0
  232. package/dist/operations/memory.d.ts +104 -0
  233. package/dist/operations/memory.js +365 -0
  234. package/dist/operations/metering.d.ts +55 -0
  235. package/dist/operations/metering.js +247 -0
  236. package/dist/operations/nodes.d.ts +35 -0
  237. package/dist/operations/nodes.js +15 -0
  238. package/dist/operations/operations.d.ts +18 -0
  239. package/dist/operations/operations.js +5 -0
  240. package/dist/operations/queue-policy.d.ts +3 -0
  241. package/dist/operations/queue-policy.js +8 -0
  242. package/dist/operations/result.d.ts +19 -0
  243. package/dist/operations/result.js +10 -0
  244. package/dist/operations/seams.d.ts +239 -0
  245. package/dist/operations/seams.js +45 -0
  246. package/dist/operations/store.d.ts +14 -0
  247. package/dist/operations/store.js +1 -0
  248. package/package.json +16 -0
@@ -0,0 +1,15 @@
1
+ export declare const TREE = "_threads";
2
+ export declare const ROOT = "thread.ts";
3
+ export declare class AlreadyThreadedError extends Error {
4
+ readonly at: string;
5
+ constructor(at: string);
6
+ }
7
+ export declare const COMPILER = "tsconfig.json";
8
+ export declare const LOCKFILES: readonly ["package-lock.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb"];
9
+ export declare const MANIFEST = "package.json";
10
+ export declare const REGISTRY: string;
11
+ export declare const IGNORED: string;
12
+ export declare function ignored(): string;
13
+ export declare function compiler(): string;
14
+ export declare function root(into: string): string;
15
+ export declare function init(into: string): readonly string[];
@@ -0,0 +1,134 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join, relative, resolve } from 'node:path';
3
+ import { quoted } from "./rows.js";
4
+ export const TREE = '_threads';
5
+ export const ROOT = 'thread.ts';
6
+ export class AlreadyThreadedError extends Error {
7
+ at;
8
+ constructor(at) {
9
+ super(`${at} already exists, so this repository already has a root. A tree has one root and it is written once. ` +
10
+ 'Declare something under it with `thread create` — run it bare to see what this tree makes — or take on ' +
11
+ 'a package with `thread attach`, which brings its rows with it. Neither is written by hand.');
12
+ this.name = 'AlreadyThreadedError';
13
+ this.at = at;
14
+ }
15
+ }
16
+ export const COMPILER = 'tsconfig.json';
17
+ export const LOCKFILES = ['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock', 'bun.lockb'];
18
+ export const MANIFEST = 'package.json';
19
+ const MODULE = 'module';
20
+ export const REGISTRY = '.npm' + 'rc';
21
+ export const IGNORED = '.git' + 'ignore';
22
+ export function ignored() {
23
+ return [
24
+ 'node_' + 'modules/',
25
+ '.next/',
26
+ 'dist/',
27
+ '*.tsbuildinfo',
28
+ 'next-env.d.ts',
29
+ '.DS_Store',
30
+ '',
31
+ ].join('\n');
32
+ }
33
+ export function compiler() {
34
+ return `${JSON.stringify({
35
+ compilerOptions: {
36
+ target: 'ES2022',
37
+ module: 'ESNext',
38
+ moduleResolution: 'bundler',
39
+ strict: true,
40
+ allowImportingTsExtensions: true,
41
+ skipLibCheck: true,
42
+ types: ['node'],
43
+ jsx: 'react-jsx',
44
+ noEmit: true,
45
+ },
46
+ }, null, 2)}\n`;
47
+ }
48
+ function owned(into) {
49
+ const held = LOCKFILES.filter((one) => existsSync(join(into, one)));
50
+ return [
51
+ {
52
+ id: 'manifest',
53
+ at: 'package.json',
54
+ describes: 'What this app is made of and what may be run against it — the packages it installs and the commands that build it, serve it and refuse it.',
55
+ },
56
+ ...(existsSync(join(into, REGISTRY))
57
+ ? [
58
+ {
59
+ id: 'registry',
60
+ at: REGISTRY,
61
+ describes: 'Which registry this app’s packages come from, and any credential scoped to it. Declared beside the lockfile because an install is not reproducible without it: the lockfile says which versions answered, and this says who answered.',
62
+ },
63
+ ]
64
+ : []),
65
+ {
66
+ id: 'ignored',
67
+ at: IGNORED,
68
+ describes: 'What is built rather than written, so the checks that read this repository can tell the two apart. Every surface here asks which files are tracked, and without it an app that has been served once answers with its whole build cache.',
69
+ },
70
+ ...held.map((one) => ({
71
+ id: 'lockfile',
72
+ at: one,
73
+ describes: 'The exact version of every package this app resolved to, so an install here and an install anywhere else are the same install.',
74
+ })),
75
+ ];
76
+ }
77
+ export function root(into) {
78
+ const rows = owned(into).flatMap((one) => [
79
+ ' {',
80
+ ` id: ${quoted(one.id)},`,
81
+ ` at: ${quoted(one.at)},`,
82
+ ` describes: ${quoted(one.describes)},`,
83
+ ' version: 1,',
84
+ ...(one.runs === undefined ? [] : [` runs: ${quoted(one.runs)},`]),
85
+ ' },',
86
+ ]);
87
+ return [
88
+ "import type { Threaded } from './thread.ts'",
89
+ '',
90
+ 'export const THREAD: Threaded = {',
91
+ " id: 'thread',",
92
+ ` at: '${TREE}/${ROOT}',`,
93
+ " describes: 'The framework that declares what must exist, forbids what is not declared, and derives what can be derived.',",
94
+ ' version: 1,',
95
+ ' declares: [',
96
+ ...rows,
97
+ ' ],',
98
+ '}',
99
+ '',
100
+ ].join('\n');
101
+ }
102
+ export function init(into) {
103
+ const dir = resolve(into, TREE);
104
+ const at = join(dir, ROOT);
105
+ if (existsSync(at))
106
+ throw new AlreadyThreadedError(relative(into, at));
107
+ mkdirSync(dir, { recursive: true });
108
+ const written = [];
109
+ const held = join(into, COMPILER);
110
+ if (!existsSync(held)) {
111
+ writeFileSync(held, compiler(), 'utf8');
112
+ written.push(COMPILER);
113
+ }
114
+ const manifest = join(into, MANIFEST);
115
+ if (!existsSync(manifest)) {
116
+ throw new Error(`there is no ${MANIFEST} here, and a thread tree is source this package has to be able to load. ` +
117
+ 'Run `npm init` first, then `thread init` — the tree is written beside a manifest, not instead of one.');
118
+ }
119
+ const stated = JSON.parse(readFileSync(manifest, 'utf8'));
120
+ if (stated.type !== MODULE) {
121
+ writeFileSync(manifest, `${JSON.stringify({ ...stated, type: MODULE }, null, 2)}\n`, 'utf8');
122
+ written.push(MANIFEST);
123
+ }
124
+ const ignore = join(into, IGNORED);
125
+ if (!existsSync(ignore)) {
126
+ writeFileSync(ignore, ignored(), 'utf8');
127
+ written.push(IGNORED);
128
+ }
129
+ for (const [name, text] of [[ROOT, root(into)]]) {
130
+ writeFileSync(join(dir, name), text, 'utf8');
131
+ written.push(relative(into, join(dir, name)));
132
+ }
133
+ return written;
134
+ }
@@ -0,0 +1,9 @@
1
+ export declare function invoked(url: string): boolean;
2
+ export declare const SOURCE: boolean;
3
+ export declare const BESIDE: (name: string) => string;
4
+ export declare const LOADER: readonly string[];
5
+ export declare const CLI: readonly string[];
6
+ export declare const REFUSED: unique symbol;
7
+ export declare const shared: (on: boolean) => void;
8
+ export declare function exit(code?: number): never;
9
+ export declare const refusal: (thrown: unknown) => number | undefined;
@@ -0,0 +1,41 @@
1
+ import { realpathSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { argv, exit as ending } from 'node:process';
4
+ import { fileURLToPath } from 'node:url';
5
+ export function invoked(url) {
6
+ const named = argv[1];
7
+ if (named === undefined)
8
+ return false;
9
+ try {
10
+ const held = new URL(url);
11
+ held.search = '';
12
+ held.hash = '';
13
+ return realpathSync(named) === realpathSync(fileURLToPath(held));
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ export const SOURCE = import.meta.url.endsWith('.ts');
20
+ export const BESIDE = (name) => `${name}${SOURCE ? '.ts' : '.js'}`;
21
+ export const LOADER = SOURCE ? ['--import', 'tsx'] : [];
22
+ export const CLI = [
23
+ ...LOADER,
24
+ join(dirname(fileURLToPath(import.meta.url)), BESIDE('cli')),
25
+ ];
26
+ export const REFUSED = Symbol.for('thread.refused');
27
+ let sharing = false;
28
+ export const shared = (on) => {
29
+ sharing = on;
30
+ };
31
+ export function exit(code) {
32
+ if (!sharing)
33
+ ending(code);
34
+ throw Object.assign(new Error(`refused with ${String(code ?? 0)}`), { [REFUSED]: code ?? 0 });
35
+ }
36
+ export const refusal = (thrown) => {
37
+ if (typeof thrown !== 'object' || thrown === null)
38
+ return undefined;
39
+ const held = thrown[REFUSED];
40
+ return typeof held === 'number' ? held : undefined;
41
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,57 @@
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 { resolve } from 'node:path';
10
+ import { argv, exitCode, stdout } from 'node:process';
11
+ import { pathToFileURL } from 'node:url';
12
+ import { generators, RAN, REFUSED_BY } from "./chain.js";
13
+ import { forget } from "./descend.js";
14
+ import { refusal, shared } from "./invoked.js";
15
+ import { findTree } from "./tree.js";
16
+ let spun = 0;
17
+ const words = (command) => command.trim().split(/\s+/).slice(1);
18
+ shared(true);
19
+ const tree = findTree();
20
+ const rows = await generators(tree);
21
+ for (const command of argv.slice(2).filter((one) => one !== '')) {
22
+ const said = words(command);
23
+ const name = said[0];
24
+ if (name === undefined)
25
+ continue;
26
+ const held = rows.find((one) => one.by === `thread ${name}`);
27
+ if (held?.at === undefined) {
28
+ stdout.write(`${REFUSED_BY} ${command}\n`);
29
+ stdout.write(`round: no command named "${name}", so \`${command}\` was not run\n`);
30
+ continue;
31
+ }
32
+ const found = resolve(tree.at, held.at);
33
+ forget();
34
+ argv.length = 1;
35
+ argv.push(found, ...said.slice(1));
36
+ spun += 1;
37
+ process.exitCode = 0;
38
+ try {
39
+ await import(__rewriteRelativeImportExtension(`${pathToFileURL(found).href}?round=${String(spun)}`));
40
+ if (exitCode !== undefined && exitCode !== 0)
41
+ stdout.write(`${REFUSED_BY} ${command}\n`);
42
+ else
43
+ stdout.write(`${RAN} ${command}\n`);
44
+ }
45
+ catch (thrown) {
46
+ const code = refusal(thrown);
47
+ if (code === undefined) {
48
+ stdout.write(`${REFUSED_BY} ${command}\n`);
49
+ stdout.write(`round: \`${command}\` threw: ${thrown instanceof Error ? thrown.message : String(thrown)}\n`);
50
+ }
51
+ else if (code === 0)
52
+ stdout.write(`${RAN} ${command}\n`);
53
+ else
54
+ stdout.write(`${REFUSED_BY} ${command}\n`);
55
+ }
56
+ }
57
+ process.exitCode = 0;
@@ -0,0 +1,26 @@
1
+ export interface Bounds {
2
+ readonly open: number;
3
+ readonly close: number;
4
+ }
5
+ export declare function inCode(text: string): readonly boolean[];
6
+ export declare function matched(text: string, code: readonly boolean[], from: number, open: string, close: string): number;
7
+ export declare function listBounds(text: string, list: string): Bounds | undefined;
8
+ export declare function holdsRow(text: string, where: Bounds, id: string): boolean;
9
+ export declare function seededAt(text: string, where: Bounds, id: string): string | undefined;
10
+ export declare function rowsIn(text: string, where: Bounds): readonly {
11
+ readonly id: string;
12
+ readonly at: string | undefined;
13
+ readonly source: string;
14
+ }[];
15
+ export declare function withRow(text: string, where: Bounds, row: string): string;
16
+ export declare function withSeed(text: string, where: Bounds, id: string, seed: string): string;
17
+ export declare function withRequires(text: string, where: Bounds, id: string, requires: readonly string[]): string | undefined;
18
+ export declare function seedsIn(text: string, where: Bounds, id: string): Bounds | undefined;
19
+ export declare function afterRow(text: string, where: Bounds, follows: string, row: string): string | undefined;
20
+ export declare const quoted: (one: string) => string;
21
+ export declare const STATED: string[];
22
+ export declare function reconciled(held: string, source: string, fields: readonly string[]): string;
23
+ export declare function fieldIn(text: string, where: Bounds, id: string, field: string): string | undefined;
24
+ export declare function withField(text: string, where: Bounds, id: string, field: string, value: string): string | undefined;
25
+ export declare function withoutRow(text: string, where: Bounds, id: string): string;
26
+ export declare function showing(row: object, only?: readonly string[]): string;
@@ -0,0 +1,354 @@
1
+ import ts from 'typescript';
2
+ const PARSED = new Map();
3
+ function tree(text) {
4
+ const held = PARSED.get(text);
5
+ if (held !== undefined)
6
+ return held;
7
+ const made = ts.createSourceFile('rows.ts', text, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
8
+ if (PARSED.size > 8)
9
+ PARSED.clear();
10
+ PARSED.set(text, made);
11
+ return made;
12
+ }
13
+ function walk(node, seen) {
14
+ seen(node);
15
+ ts.forEachChild(node, (one) => {
16
+ walk(one, seen);
17
+ });
18
+ }
19
+ const keyed = (one) => ts.isIdentifier(one.name) || ts.isStringLiteral(one.name) ? one.name.text : undefined;
20
+ function stringy(node, name) {
21
+ for (const one of node.properties) {
22
+ if (!ts.isPropertyAssignment(one) || keyed(one) !== name)
23
+ continue;
24
+ return ts.isStringLiteral(one.initializer) ? one.initializer.text : undefined;
25
+ }
26
+ return undefined;
27
+ }
28
+ function listy(node, name) {
29
+ for (const one of node.properties) {
30
+ if (!ts.isPropertyAssignment(one) || keyed(one) !== name)
31
+ continue;
32
+ return ts.isArrayLiteralExpression(one.initializer) ? one.initializer : undefined;
33
+ }
34
+ return undefined;
35
+ }
36
+ const spanned = (node) => ({
37
+ open: node.getStart(),
38
+ close: node.getEnd() - 1,
39
+ });
40
+ export function inCode(text) {
41
+ const held = new Array(text.length).fill(true);
42
+ let cursor = 0;
43
+ while (cursor < text.length) {
44
+ const one = text[cursor];
45
+ const next = text[cursor + 1];
46
+ if (one === '/' && next === '/') {
47
+ while (cursor < text.length && text[cursor] !== '\n')
48
+ held[cursor++] = false;
49
+ continue;
50
+ }
51
+ if (one === '/' && next === '*') {
52
+ held[cursor++] = false;
53
+ held[cursor++] = false;
54
+ while (cursor < text.length && !(text[cursor] === '*' && text[cursor + 1] === '/'))
55
+ held[cursor++] = false;
56
+ held[cursor++] = false;
57
+ held[cursor++] = false;
58
+ continue;
59
+ }
60
+ if (one === "'" || one === '"' || one === '`') {
61
+ held[cursor++] = false;
62
+ while (cursor < text.length && text[cursor] !== one) {
63
+ if (text[cursor] === '\\')
64
+ held[cursor++] = false;
65
+ held[cursor++] = false;
66
+ }
67
+ held[cursor++] = false;
68
+ continue;
69
+ }
70
+ cursor += 1;
71
+ }
72
+ return held;
73
+ }
74
+ export function matched(text, code, from, open, close) {
75
+ let depth = 0;
76
+ for (let cursor = from; cursor < text.length; cursor += 1) {
77
+ if (code[cursor] !== true)
78
+ continue;
79
+ if (text[cursor] === open)
80
+ depth += 1;
81
+ if (text[cursor] === close) {
82
+ depth -= 1;
83
+ if (depth === 0)
84
+ return cursor;
85
+ }
86
+ }
87
+ return -1;
88
+ }
89
+ export function listBounds(text, list) {
90
+ const file = tree(text);
91
+ let found;
92
+ let held;
93
+ walk(file, (node) => {
94
+ if (found !== undefined || !ts.isVariableDeclaration(node) || node.initializer === undefined)
95
+ return;
96
+ const unwrapped = (node2) => ts.isAsExpression(node2) || ts.isSatisfiesExpression(node2) ? unwrapped(node2.expression) : node2;
97
+ const one = unwrapped(node.initializer);
98
+ if (ts.isIdentifier(node.name) && node.name.text === list && ts.isArrayLiteralExpression(one)) {
99
+ found = one;
100
+ return;
101
+ }
102
+ if (held === undefined && ts.isObjectLiteralExpression(one))
103
+ held = one;
104
+ });
105
+ if (found !== undefined)
106
+ return spanned(found);
107
+ if (held === undefined)
108
+ return undefined;
109
+ const inside = listy(held, list);
110
+ return inside === undefined ? undefined : spanned(inside);
111
+ }
112
+ function elements(text, where) {
113
+ let found;
114
+ walk(tree(text), (node) => {
115
+ if (found !== undefined)
116
+ return;
117
+ if (ts.isArrayLiteralExpression(node) && node.getStart() === where.open && node.getEnd() - 1 === where.close) {
118
+ found = node;
119
+ }
120
+ });
121
+ if (found === undefined)
122
+ return [];
123
+ return found.elements.filter((one) => ts.isObjectLiteralExpression(one));
124
+ }
125
+ function rowAt(text, where, id) {
126
+ return elements(text, where).find((one) => stringy(one, 'id') === id);
127
+ }
128
+ export function holdsRow(text, where, id) {
129
+ return rowAt(text, where, id) !== undefined;
130
+ }
131
+ export function seededAt(text, where, id) {
132
+ const held = rowAt(text, where, id);
133
+ if (held === undefined)
134
+ return undefined;
135
+ const seeds = listy(held, 'seeds');
136
+ const derives = listy(held, 'derives');
137
+ if (seeds !== undefined && derives !== undefined)
138
+ return undefined;
139
+ const first = (seeds ?? derives)?.elements[0];
140
+ if (first === undefined || !ts.isObjectLiteralExpression(first))
141
+ return undefined;
142
+ return stringy(first, 'at');
143
+ }
144
+ export function rowsIn(text, where) {
145
+ const found = [];
146
+ for (const one of elements(text, where)) {
147
+ const id = stringy(one, 'id');
148
+ if (id === undefined)
149
+ continue;
150
+ const at = stringy(one, 'at');
151
+ const from = one.getStart();
152
+ const line = text.lastIndexOf('\n', from) + 1;
153
+ const pad = text.slice(line, from);
154
+ found.push({ id, at, source: `${/^[ \t]*$/.test(pad) ? pad : ''}${text.slice(from, one.getEnd())},` });
155
+ }
156
+ return found;
157
+ }
158
+ export function withRow(text, where, row) {
159
+ const held = /[ \t]*$/.exec(text.slice(0, where.close))?.[0] ?? '';
160
+ const before = text.slice(0, where.close - held.length);
161
+ const empty = before.trimEnd().endsWith('[');
162
+ const line = text.lastIndexOf('\n', where.open);
163
+ const pad = empty ? (/^[ \t]*/.exec(text.slice(line + 1))?.[0] ?? '') : held;
164
+ return `${before}${empty ? '\n' : ''}${row}\n${pad}${text.slice(where.close)}`;
165
+ }
166
+ export function withSeed(text, where, id, seed) {
167
+ const held = rowAt(text, where, id);
168
+ if (held === undefined)
169
+ return text;
170
+ if (listy(held, 'seeds') !== undefined)
171
+ return text;
172
+ const to = held.getEnd() - 1;
173
+ const line = text.lastIndexOf('\n', held.getStart());
174
+ const pad = /^[ \t]*/.exec(text.slice(line + 1))?.[0] ?? ' ';
175
+ const before = text.slice(0, to).trimEnd();
176
+ const comma = before.endsWith(',') ? '' : ',';
177
+ return `${before}${comma}\n${pad} seeds: [\n${seed}\n${pad} ],\n${pad}${text.slice(to)}`;
178
+ }
179
+ export function withRequires(text, where, id, requires) {
180
+ const held = rowAt(text, where, id);
181
+ if (held === undefined)
182
+ return undefined;
183
+ const line = text.lastIndexOf('\n', held.getStart()) + 1;
184
+ const pad = `${/^[ \t]*/.exec(text.slice(line))?.[0] ?? ' '} `;
185
+ const written = requires.length === 0 ? '' : `${pad}requires: [${requires.map((one) => `'${one}'`).join(', ')}],\n`;
186
+ const propertyNamed = (name) => {
187
+ for (const one of held.properties) {
188
+ if (ts.isPropertyAssignment(one) && keyed(one) === name)
189
+ return one;
190
+ }
191
+ return undefined;
192
+ };
193
+ const already = propertyNamed('requires');
194
+ if (already !== undefined) {
195
+ const opens = text.lastIndexOf('\n', already.getStart()) + 1;
196
+ const shut = text.indexOf('\n', already.getEnd());
197
+ return `${text.slice(0, opens)}${written}${text.slice(shut === -1 ? text.length : shut + 1)}`;
198
+ }
199
+ const version = propertyNamed('version');
200
+ if (version === undefined)
201
+ return undefined;
202
+ const after = text.indexOf('\n', version.getEnd());
203
+ const at = after === -1 ? text.length : after + 1;
204
+ return `${text.slice(0, at)}${written}${text.slice(at)}`;
205
+ }
206
+ export function seedsIn(text, where, id) {
207
+ const held = rowAt(text, where, id);
208
+ if (held === undefined)
209
+ return undefined;
210
+ const list = listy(held, 'seeds');
211
+ return list === undefined ? undefined : spanned(list);
212
+ }
213
+ export function afterRow(text, where, follows, row) {
214
+ const held = rowAt(text, where, follows);
215
+ if (held === undefined)
216
+ return undefined;
217
+ let to = held.getEnd();
218
+ if (text[to] === ',')
219
+ to += 1;
220
+ return `${text.slice(0, to)}\n${row}${text.slice(to)}`;
221
+ }
222
+ function headed(text) {
223
+ let found;
224
+ walk(tree(text), (node) => {
225
+ if (found !== undefined || !ts.isVariableDeclaration(node) || node.initializer === undefined)
226
+ return;
227
+ const one = ts.isAsExpression(node.initializer) ? node.initializer.expression : node.initializer;
228
+ if (ts.isObjectLiteralExpression(one))
229
+ found = one;
230
+ });
231
+ return found;
232
+ }
233
+ function stated(node, field) {
234
+ for (const one of node.properties) {
235
+ if (!ts.isPropertyAssignment(one) || keyed(one) !== field)
236
+ continue;
237
+ return { open: one.initializer.getStart(), close: one.initializer.getEnd() };
238
+ }
239
+ return undefined;
240
+ }
241
+ export const quoted = (one) => `'${one.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, '\\n')}'`;
242
+ export const STATED = ['at', 'describes', 'version'];
243
+ export function reconciled(held, source, fields) {
244
+ const ships = headed(source);
245
+ if (ships === undefined)
246
+ return held;
247
+ const named = stringy(ships, 'id');
248
+ let next = held;
249
+ for (const field of fields) {
250
+ const want = stated(ships, field);
251
+ if (want === undefined)
252
+ continue;
253
+ const mine = headed(next);
254
+ if (mine === undefined || stringy(mine, 'id') !== named)
255
+ return held;
256
+ const have = stated(mine, field);
257
+ if (have === undefined)
258
+ continue;
259
+ const said = source.slice(want.open, want.close);
260
+ if (next.slice(have.open, have.close) === said)
261
+ continue;
262
+ next = next.slice(0, have.open) + said + next.slice(have.close);
263
+ }
264
+ return next;
265
+ }
266
+ export function fieldIn(text, where, id, field) {
267
+ const held = rowAt(text, where, id);
268
+ if (held === undefined)
269
+ return undefined;
270
+ for (const one of held.properties) {
271
+ if (!ts.isPropertyAssignment(one) || keyed(one) !== field)
272
+ continue;
273
+ return text.slice(one.initializer.getStart(), one.initializer.getEnd());
274
+ }
275
+ return undefined;
276
+ }
277
+ export function withField(text, where, id, field, value) {
278
+ const held = rowAt(text, where, id);
279
+ if (held === undefined)
280
+ return undefined;
281
+ for (const one of held.properties) {
282
+ if (!ts.isPropertyAssignment(one) || keyed(one) !== field)
283
+ continue;
284
+ return `${text.slice(0, one.initializer.getStart())}${value}${text.slice(one.initializer.getEnd())}`;
285
+ }
286
+ const last = held.properties.at(-1);
287
+ if (last === undefined)
288
+ return undefined;
289
+ let ends = last.getEnd();
290
+ if (text[ends] === ',')
291
+ ends += 1;
292
+ const already = text[ends - 1] === ',' ? '' : ',';
293
+ if (!text.slice(held.getStart(), held.getEnd()).includes('\n')) {
294
+ return `${text.slice(0, ends)}${already} ${field}: ${value}${text.slice(ends)}`;
295
+ }
296
+ const line = text.lastIndexOf('\n', last.getStart()) + 1;
297
+ const pad = /^[ \t]*/.exec(text.slice(line))?.[0] ?? ' ';
298
+ return `${text.slice(0, ends)}${already}\n${pad}${field}: ${value},${text.slice(ends)}`;
299
+ }
300
+ export function withoutRow(text, where, id) {
301
+ const held = rowAt(text, where, id);
302
+ if (held === undefined)
303
+ return text;
304
+ let ends = held.getEnd();
305
+ if (text[ends] === ',')
306
+ ends += 1;
307
+ const pad = /[ \t]*$/.exec(text.slice(0, held.getStart()))?.[0] ?? '';
308
+ const from = held.getStart() - pad.length;
309
+ if (text[ends] === '\n')
310
+ ends += 1;
311
+ const left = text.slice(0, from);
312
+ const right = text.slice(ends);
313
+ return left.trimEnd().endsWith('[') && right.trimStart().startsWith(']')
314
+ ? `${left.replace(/\s*$/, '')}${right.replace(/^\s*/, '')}`
315
+ : left + right;
316
+ }
317
+ const lines = (held, pad) => {
318
+ if (held === null || held === undefined)
319
+ return [String(held)];
320
+ if (Array.isArray(held)) {
321
+ if (held.length === 0)
322
+ return ['[]'];
323
+ if (held.every((one) => typeof one !== 'object' || one === null))
324
+ return [held.map((one) => String(one)).join(', ')];
325
+ return held.flatMap((one) => {
326
+ const [first = '', ...rest] = lines(one, `${pad} `);
327
+ return [`${pad}- ${first.trimStart()}`, ...rest];
328
+ });
329
+ }
330
+ if (typeof held === 'object') {
331
+ const parts = Object.entries(held);
332
+ if (parts.length === 0)
333
+ return ['{}'];
334
+ return parts.flatMap(([key, one]) => {
335
+ const [first = '', ...rest] = lines(one, `${pad} `);
336
+ return rest.length === 0 && !first.includes('\n') ? [`${pad}${key}: ${first}`] : [`${pad}${key}:`, first, ...rest];
337
+ });
338
+ }
339
+ return [String(held)];
340
+ };
341
+ export function showing(row, only = []) {
342
+ const held = row;
343
+ const keys = Object.keys(held);
344
+ const wanted = only.filter((one) => one !== '');
345
+ const stray = wanted.filter((one) => !keys.includes(one));
346
+ if (stray.length > 0) {
347
+ return `${stray.map((one) => `\`${one}\``).join(', ')} ${stray.length === 1 ? 'is not a field' : 'are not fields'} of this row. It states ${keys.join(', ')}\n`;
348
+ }
349
+ const showing = wanted.length === 0 ? keys : wanted;
350
+ return `${showing.flatMap((key) => {
351
+ const [first = '', ...rest] = lines(held[key], ' ');
352
+ return rest.length === 0 ? [`${key}: ${first.trimStart()}`] : [`${key}:`, first, ...rest];
353
+ }).join('\n')}\n`;
354
+ }
@@ -0,0 +1,6 @@
1
+ export declare const ORGANISATION = "@prestack";
2
+ export declare const THING = "thread";
3
+ export declare const NAMED = "@prestack/thread";
4
+ export declare const named: (id: string) => string;
5
+ export declare const idOf: (name: string) => string | undefined;
6
+ export declare const ours: (name: string) => boolean;
@@ -0,0 +1,12 @@
1
+ export const ORGANISATION = '@prestack';
2
+ export const THING = 'thread';
3
+ export const NAMED = `${ORGANISATION}/${THING}`;
4
+ const CORE = 'core';
5
+ const HEAD = `${NAMED}-`;
6
+ export const named = (id) => (id === CORE ? NAMED : `${HEAD}${id}`);
7
+ export const idOf = (name) => {
8
+ if (name === NAMED)
9
+ return CORE;
10
+ return name.startsWith(HEAD) ? name.slice(HEAD.length) : undefined;
11
+ };
12
+ export const ours = (name) => idOf(name) !== undefined;