@suss/recognize 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,205 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable by
79
+ such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or Derivative
95
+ Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and do not
117
+ modify the License. You may add Your own attribution notices
118
+ within Derivative Works that You distribute, alongside or as an
119
+ addendum to the NOTICE text from the Work, provided that such
120
+ additional attribution notices cannot be construed as modifying
121
+ the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor has
163
+ been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format please. Also add information on
185
+ how to contact you by electronic and paper mail.
186
+
187
+ If the program does not interact with users remotely through a computer
188
+ network, then your name and employer's name (e.g., your institution)
189
+ is sufficient to fill in the "name of copyright owner" field. Feel
190
+ free to omit the "name of employer" line if you are in no way affiliated
191
+ with any institution.
192
+
193
+ Copyright 2026 Nimbus Cloud AI LLC
194
+
195
+ Licensed under the Apache License, Version 2.0 (the "License");
196
+ you may not use this file except in compliance with the License.
197
+ You may obtain a copy of the License at
198
+
199
+ http://www.apache.org/licenses/LICENSE-2.0
200
+
201
+ Unless required by applicable law or agreed to in writing, software
202
+ distributed under the License is distributed on an "AS IS" BASIS,
203
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
204
+ See the License for the specific language governing permissions and
205
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # @suss/recognize
2
+
3
+ Write a pack as data. A pack states where a match starts, which methods
4
+ count, and what each one reads or writes; this package compiles that
5
+ into the recognizer hooks the adapters already call, and any adapter
6
+ that implements the executor ops can run it.
7
+
8
+ ```ts
9
+ import { declaredBy, pack, storageCalls } from "@suss/recognize";
10
+
11
+ const COMMANDS = {
12
+ get: { kind: "read", selector: { at: 0 } },
13
+ hset: { kind: "write", selector: { at: 0 }, fields: { at: 1 } },
14
+ } as const;
15
+
16
+ const calls = storageCalls({
17
+ system: "redis",
18
+ client: declaredBy("ioredis", "redis", "iovalkey"),
19
+ })
20
+ .methods(COMMANDS, { ignoringCase: true })
21
+ .container(namespaceOf)
22
+ .example('redis.get("user_online:42")');
23
+
24
+ export default pack("redis", [calls], {
25
+ languages: ["typescript", "javascript"],
26
+ recognizedAs: "@suss/framework-redis",
27
+ });
28
+ ```
29
+
30
+ Nothing here imports a syntax tree, so the same declaration drives the
31
+ TypeScript adapter today and the Python and Ruby adapters once they
32
+ implement the ops.
33
+
34
+ ## The spine
35
+
36
+ A pack does four jobs: it discovers units, it recognizes calls inside
37
+ them, it declares terminals, and it claims sub-units. They share one
38
+ spine and differ in what the ending yields.
39
+
40
+ ```
41
+ where the match starts -> which method -> read the arguments -> yield
42
+ effects
43
+ a unit
44
+ a terminal
45
+ a sub-unit
46
+ ```
47
+
48
+ Only the effects ending is built. The other three are further members of
49
+ `Ending` with an entry in the compile table.
50
+
51
+ ### Where a match starts
52
+
53
+ The start is its own axis, and a receiver is one value on it. Across the
54
+ 29 shipped packs a match starts from at least thirteen places, and most
55
+ of them are not receivers at all: an exported name, a file path, a
56
+ decorator, a parameter's type, a template file beside the module, a
57
+ function's return type. `MatchStart` is where those arrive.
58
+
59
+ The receiver-shaped starts are their own union, `ReceiverOrigin`:
60
+
61
+ | origin | what it matches | built |
62
+ |---|---|---|
63
+ | `declaredBy` | a receiver whose method one of these modules declared | yes |
64
+ | `constructed` | a client made from one of these modules' exports | yes |
65
+ | `factoryMade` | `app = express()` | no |
66
+ | `imported` | a function the file imports | no |
67
+ | `anchored` | a chain read from its anchor call | no |
68
+ | `inherits` | a Ruby or Python receiver matched by ancestry | no |
69
+ | `global` | `process.env`, bare `fetch` | no |
70
+
71
+ `declaredBy` is what a pack wants when the source never spells the
72
+ client out: `const redis = await this.getClient()` says nothing about
73
+ ioredis, and the declaration behind `redis.get` says everything.
74
+ `constructed` asks the receiver itself, so it still works where the
75
+ method is untyped.
76
+
77
+ ## The gradient
78
+
79
+ Expressiveness is bought link by link, and the price is printed.
80
+
81
+ 1. A chain of data links. Serializable, inspectable, and it runs
82
+ wherever the ops do.
83
+ 2. A link written as a function. That link is code, the rest stay data,
84
+ and pack health says which ones are opaque.
85
+ 3. `astLink` from `@suss/recognize/ast`, which hands the function the
86
+ adapter's own node. Behind its own import, so reaching for it shows
87
+ up in the diff, and pack health reports it the way it reports a pack
88
+ that declares no version.
89
+
90
+ `packGradients` in `@suss/adapter-typescript` reads the counts off a
91
+ run, and three health checks fire on them: a link written as a function,
92
+ a link that reads the syntax tree, and a declaration with no example.
93
+
94
+ ## The executor ops
95
+
96
+ `CallOps` is the whole of what a chain asks about one call site. An
97
+ adapter implements it once. Today `callOpsFor` in
98
+ `@suss/adapter-typescript` is the only implementation, and it puts the
99
+ result on the recognizer context under `ops`.
100
+
101
+ | op | what it gives back |
102
+ |---|---|
103
+ | `method()` | which method the call reaches for, as the source spells it |
104
+ | `receiverIsFrom(origin)` | whether the receiver came from where the origin says |
105
+ | `argumentCount()` | how many arguments the call passes |
106
+ | `nameAt(index, unsettled)` | the name that argument gives, with the hole policy applied |
107
+ | `calleeText()` | the callee, as the source writes it |
108
+
109
+ A chain running on an adapter with no ops matches nothing rather than
110
+ throwing, since a pack loaded into the wrong adapter is a configuration
111
+ mistake and not a crash.
112
+
113
+ ## The example every declaration states
114
+
115
+ ```ts
116
+ .example('redis.get("user_online:42")')
117
+ ```
118
+
119
+ `runExamples(pack, run)` takes each declaration's example, hands it to
120
+ the compiler the caller supplied, and gives back what came out. A pack's
121
+ test asserts the stated effect, so the day the example stops matching
122
+ the pack fails rather than the documentation quietly lying.
123
+ `examplesMissing(pack)` lists the declarations that state none.
124
+
125
+ ## Ordering
126
+
127
+ The links are guards, so the compiled hook checks the cheap one first:
128
+ looking a method up in a table costs nothing, while following a receiver
129
+ to the library that made it walks declarations. A link that changes what
130
+ the receiver is, the way Prisma's model property will, needs the
131
+ declared order back, and `compile.ts` is where that goes.
package/dist/ast.cjs ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/ast.ts
21
+ var ast_exports = {};
22
+ __export(ast_exports, {
23
+ astLink: () => astLink
24
+ });
25
+ module.exports = __toCommonJS(ast_exports);
26
+ function astLink(read) {
27
+ const link = (...args) => {
28
+ const ops = args[args.length - 1];
29
+ const given = args.slice(0, -1);
30
+ return read(ops.ast(), ...given);
31
+ };
32
+ return Object.assign(link, { reachesAst: true });
33
+ }
34
+ // Annotate the CommonJS export names for ESM import in node:
35
+ 0 && (module.exports = {
36
+ astLink
37
+ });
package/dist/ast.d.cts ADDED
@@ -0,0 +1,32 @@
1
+ import { C as CallOps, L as LinkFunction } from './chain-DTSij2Mn.cjs';
2
+
3
+ /**
4
+ * The floor: a link that reads the adapter's own syntax tree.
5
+ *
6
+ * A pack that outgrows the ops still gets the tree, and this is the
7
+ * only door to it. Going through a separate import puts the decision in
8
+ * the diff, and `astLink` marks the link so the pack health report says
9
+ * which packs went through, the way it says which declare no version.
10
+ * Allowed, observable, and slightly inconvenient.
11
+ *
12
+ * The node comes back as `unknown` because this package does not read
13
+ * any one language. A pack casts it to the adapter it was written
14
+ * against, and that cast is how the pack says which adapter it needs.
15
+ */
16
+
17
+ /**
18
+ * The ops an adapter implements when it can hand out its own nodes. The
19
+ * extra member is here rather than on `CallOps` so that a pack reaching
20
+ * for a node has to import this module first.
21
+ */
22
+ interface AstCapableOps extends CallOps {
23
+ /** The adapter's own node for the call in hand. */
24
+ ast(): unknown;
25
+ }
26
+ /**
27
+ * A link answered by reading the call's own node. `read` is handed the
28
+ * node and whatever the link would have been handed anyway.
29
+ */
30
+ declare function astLink<A extends unknown[], R>(read: (node: unknown, ...given: A) => R): LinkFunction<[...A, CallOps], R>;
31
+
32
+ export { type AstCapableOps, astLink };
package/dist/ast.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { C as CallOps, L as LinkFunction } from './chain-DTSij2Mn.js';
2
+
3
+ /**
4
+ * The floor: a link that reads the adapter's own syntax tree.
5
+ *
6
+ * A pack that outgrows the ops still gets the tree, and this is the
7
+ * only door to it. Going through a separate import puts the decision in
8
+ * the diff, and `astLink` marks the link so the pack health report says
9
+ * which packs went through, the way it says which declare no version.
10
+ * Allowed, observable, and slightly inconvenient.
11
+ *
12
+ * The node comes back as `unknown` because this package does not read
13
+ * any one language. A pack casts it to the adapter it was written
14
+ * against, and that cast is how the pack says which adapter it needs.
15
+ */
16
+
17
+ /**
18
+ * The ops an adapter implements when it can hand out its own nodes. The
19
+ * extra member is here rather than on `CallOps` so that a pack reaching
20
+ * for a node has to import this module first.
21
+ */
22
+ interface AstCapableOps extends CallOps {
23
+ /** The adapter's own node for the call in hand. */
24
+ ast(): unknown;
25
+ }
26
+ /**
27
+ * A link answered by reading the call's own node. `read` is handed the
28
+ * node and whatever the link would have been handed anyway.
29
+ */
30
+ declare function astLink<A extends unknown[], R>(read: (node: unknown, ...given: A) => R): LinkFunction<[...A, CallOps], R>;
31
+
32
+ export { type AstCapableOps, astLink };
package/dist/ast.js ADDED
@@ -0,0 +1,12 @@
1
+ // src/ast.ts
2
+ function astLink(read) {
3
+ const link = (...args) => {
4
+ const ops = args[args.length - 1];
5
+ const given = args.slice(0, -1);
6
+ return read(ops.ast(), ...given);
7
+ };
8
+ return Object.assign(link, { reachesAst: true });
9
+ }
10
+ export {
11
+ astLink
12
+ };
@@ -0,0 +1,197 @@
1
+ /**
2
+ * The operations a chain performs at one call site, and what a language
3
+ * adapter has to be able to work out for it.
4
+ *
5
+ * A chain is data, so something has to turn "did this module declare
6
+ * the method" into a yes or no about a particular program. That is the
7
+ * adapter's job, and this interface is the whole of what a chain asks
8
+ * for. An adapter implements it once and every declared pack runs
9
+ * there, which is what lets one pack drive several languages.
10
+ *
11
+ * Nothing here mentions a syntax tree. A link that needs the tree goes
12
+ * through `@suss/recognize/ast`, a separate import so that reaching for
13
+ * it shows up in a diff and in the pack health report.
14
+ */
15
+ /**
16
+ * How a pack pins down the receiver a call is on.
17
+ *
18
+ * The migration plan for #542 lists four more: `factoryMade` (`app =
19
+ * express()`), `imported`, `anchored` (a chain read from its anchor
20
+ * call), `inherits` (a Ruby or Python receiver matched by ancestry) and
21
+ * `global` (`process.env`, bare `fetch`). Each arrives as a member here
22
+ * with an entry in every adapter's dispatch table. The README beside
23
+ * this file says which starts are not receiver-shaped at all.
24
+ */
25
+ type ReceiverOrigin = DeclaredBy | ConstructedFrom;
26
+ /**
27
+ * A receiver whose method one of these modules declared.
28
+ *
29
+ * This is the origin for a client the source never spells out. `const
30
+ * redis = await this.getClient()` says nothing about ioredis, and the
31
+ * declaration behind `redis.get` says everything.
32
+ */
33
+ interface DeclaredBy {
34
+ readonly origin: "declaredBy";
35
+ /** The modules whose declarations settle the call. */
36
+ readonly importedFrom: readonly string[];
37
+ }
38
+ /**
39
+ * A client made from a module's export, however the program caches it.
40
+ * Asked of the receiver itself, so it still works where the method is untyped
41
+ * and `declaredBy` finds nothing to read.
42
+ */
43
+ interface ConstructedFrom {
44
+ readonly origin: "constructed";
45
+ /** The modules whose export the client was made from. */
46
+ readonly importedFrom: readonly string[];
47
+ }
48
+ /**
49
+ * A receiver whose method one of these modules declared. Pass every
50
+ * module that ships the same client, the way three packages all speak
51
+ * one wire protocol.
52
+ */
53
+ declare function declaredBy(...importedFrom: readonly string[]): DeclaredBy;
54
+ /** A client made from one of these modules' exports. */
55
+ declare function constructedFrom(...importedFrom: readonly string[]): ConstructedFrom;
56
+ /**
57
+ * What a reader gives back for a name nothing in the source settles.
58
+ * `"nothing"` gives null, `"reference"` gives the value to go and ask
59
+ * about instead.
60
+ */
61
+ type UnsettledName = "nothing" | "reference";
62
+ /**
63
+ * One call site, as the questions a chain asks about it.
64
+ *
65
+ * An adapter builds one of these per call and hands it to the
66
+ * recognizer through its context. Every member is about the call in
67
+ * hand, so there is no node to pass around and no place for a pack to
68
+ * reach past what it declared.
69
+ */
70
+ interface CallOps {
71
+ /** Which method the call reaches for, spelled as the source spells it. */
72
+ method(): string | null;
73
+ /** Whether the receiver came from where the origin says. */
74
+ receiverIsFrom(origin: ReceiverOrigin): boolean;
75
+ /** How many arguments the call passes. */
76
+ argumentCount(): number;
77
+ /** The name the argument in this position gives. */
78
+ nameAt(index: number, unsettled: UnsettledName): string | null;
79
+ /** The callee, as the source writes it. */
80
+ calleeText(): string;
81
+ }
82
+ /**
83
+ * The property an adapter puts its ops on, in the context it hands a
84
+ * recognizer. A context without it belongs to an adapter that has not
85
+ * implemented the ops, and a declared pack matches nothing there.
86
+ */
87
+ interface OpsCarrier {
88
+ ops?: CallOps;
89
+ }
90
+ /** The ops in a recognizer context, or null when the adapter has none. */
91
+ declare function opsIn(ctx: unknown): CallOps | null;
92
+
93
+ /**
94
+ * The spine every pack shares, as a chain of links.
95
+ *
96
+ * A pack does four jobs, and all four start the same way: match the
97
+ * receiver, match the method, read the arguments, then yield. What
98
+ * differs is the ending. Recognition yields effects, discovery yields a
99
+ * unit, a terminal yields a response write, and a claimed callback
100
+ * yields a sub-unit. Only the effects ending is built; the others are
101
+ * further members of `Ending` with an entry in the compile table.
102
+ *
103
+ * A link's answer is data wherever it can be. A link given a function
104
+ * instead is code, that link alone, and pack health says which ones.
105
+ */
106
+
107
+ /** A link whose answer a pack wrote as code rather than as data. */
108
+ interface LinkFunction<A extends unknown[], R> {
109
+ (...args: A): R;
110
+ /** Set when the function was built through `@suss/recognize/ast`. */
111
+ readonly reachesAst?: boolean;
112
+ }
113
+ /**
114
+ * What a match starts from.
115
+ *
116
+ * Most of what the shipped packs match starts from a receiver, and none
117
+ * of what discovery matches does: an exported name, a file path, a
118
+ * decorator, a parameter's type, a template file beside the module and
119
+ * a function's return type each start somewhere else. So the start is
120
+ * its own axis, and a receiver origin is one value on it.
121
+ */
122
+ type MatchStart = FromReceiver;
123
+ /** A match that starts from the receiver a call is on. */
124
+ interface FromReceiver {
125
+ readonly starts: "receiver";
126
+ readonly origin: ReceiverOrigin;
127
+ }
128
+ /** Where the match begins. */
129
+ interface StartLink {
130
+ readonly asks: "start";
131
+ readonly at: MatchStart;
132
+ }
133
+ /** Which methods count, and what each one does. */
134
+ interface MethodsLink<TMeaning> {
135
+ readonly asks: "methods";
136
+ readonly table: Readonly<Record<string, TMeaning>>;
137
+ /**
138
+ * Whether two spellings of one method name are the same method. One
139
+ * client library lower-cases where another camel-cases, and both are
140
+ * sending the same command.
141
+ */
142
+ readonly ignoringCase: boolean;
143
+ }
144
+ /**
145
+ * Which container a call's selector belongs to.
146
+ *
147
+ * The call in hand comes second so that a rule written over the
148
+ * selector alone, which is most of them, ignores it. A rule that has to
149
+ * read the syntax tree goes through `astLink`, which is what puts the
150
+ * call to use.
151
+ */
152
+ interface ContainerLink {
153
+ readonly asks: "container";
154
+ readonly from: LinkFunction<[readonly string[], CallOps], string | null>;
155
+ }
156
+ /** One question in a chain, and the answer the pack gave for it. */
157
+ type Link<TMeaning> = StartLink | MethodsLink<TMeaning> | ContainerLink;
158
+ /** Which argument or arguments say what a call reached. */
159
+ type ArgumentPick = {
160
+ readonly at: number;
161
+ } | {
162
+ readonly from: number;
163
+ };
164
+ /** What one method of a storage client does. */
165
+ interface StorageMethod {
166
+ readonly kind: "read" | "write";
167
+ /** Which argument or arguments say what the call reached. */
168
+ readonly selector?: ArgumentPick;
169
+ /** Which argument says which field inside it, when the method takes one. */
170
+ readonly fields?: ArgumentPick;
171
+ }
172
+ /** What a chain produces when every link matches. */
173
+ type Ending = StorageEnding;
174
+ /** A storage access: one call, one thing it read or wrote. */
175
+ interface StorageEnding {
176
+ readonly yields: "storageAccess";
177
+ /** The store, in the words OpenTelemetry's semantic conventions use. */
178
+ readonly system: string;
179
+ /** The wire, when it differs from the store's own name. */
180
+ readonly transport?: string;
181
+ /** Which of the store's namespaces the call reached. */
182
+ readonly scope: string;
183
+ /** What a reader gives back for a name nothing in the source settles. */
184
+ readonly unsettledName: "nothing" | "reference";
185
+ }
186
+ /**
187
+ * A pack's declaration for one kind of call: the links, the ending, and
188
+ * a line of code it matches.
189
+ */
190
+ interface Chain<TMeaning = StorageMethod> {
191
+ readonly links: readonly Link<TMeaning>[];
192
+ readonly ending: Ending;
193
+ /** A line of code this matches, which the pack's tests run. */
194
+ readonly example: string | null;
195
+ }
196
+
197
+ export { type ArgumentPick as A, type CallOps as C, type DeclaredBy as D, type Ending as E, type FromReceiver as F, type LinkFunction as L, type MatchStart as M, type OpsCarrier as O, type ReceiverOrigin as R, type StorageMethod as S, type UnsettledName as U, type Chain as a, type ConstructedFrom as b, type ContainerLink as c, type Link as d, type MethodsLink as e, type StartLink as f, type StorageEnding as g, constructedFrom as h, declaredBy as i, opsIn as o };