@suss/recognize 0.13.1 → 0.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast.d.cts +4 -11
- package/dist/ast.d.ts +4 -11
- package/dist/{chain-BaxjT_-k.d.cts → chain-58V6lcel.d.cts} +65 -196
- package/dist/{chain-BaxjT_-k.d.ts → chain-58V6lcel.d.ts} +65 -196
- package/dist/index.cjs +124 -18
- package/dist/index.d.cts +82 -6
- package/dist/index.d.ts +82 -6
- package/dist/index.js +124 -19
- package/package.json +4 -4
package/dist/ast.d.cts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CallOps } from '@suss/extractor';
|
|
2
|
+
import { L as LinkFunction } from './chain-58V6lcel.cjs';
|
|
3
|
+
import '@suss/behavioral-ir';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* The floor: a link that reads the adapter's own syntax tree.
|
|
@@ -14,19 +16,10 @@ import { C as CallOps, L as LinkFunction } from './chain-BaxjT_-k.cjs';
|
|
|
14
16
|
* against, and that cast is how the pack says which adapter it needs.
|
|
15
17
|
*/
|
|
16
18
|
|
|
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
19
|
/**
|
|
27
20
|
* A link answered by reading the call's own node. `read` is handed the
|
|
28
21
|
* node and whatever the link would have been handed anyway.
|
|
29
22
|
*/
|
|
30
23
|
declare function astLink<A extends unknown[], R>(read: (node: unknown, ...given: A) => R): LinkFunction<[...A, CallOps], R>;
|
|
31
24
|
|
|
32
|
-
export {
|
|
25
|
+
export { astLink };
|
package/dist/ast.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CallOps } from '@suss/extractor';
|
|
2
|
+
import { L as LinkFunction } from './chain-58V6lcel.js';
|
|
3
|
+
import '@suss/behavioral-ir';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* The floor: a link that reads the adapter's own syntax tree.
|
|
@@ -14,19 +16,10 @@ import { C as CallOps, L as LinkFunction } from './chain-BaxjT_-k.js';
|
|
|
14
16
|
* against, and that cast is how the pack says which adapter it needs.
|
|
15
17
|
*/
|
|
16
18
|
|
|
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
19
|
/**
|
|
27
20
|
* A link answered by reading the call's own node. `read` is handed the
|
|
28
21
|
* node and whatever the link would have been handed anyway.
|
|
29
22
|
*/
|
|
30
23
|
declare function astLink<A extends unknown[], R>(read: (node: unknown, ...given: A) => R): LinkFunction<[...A, CallOps], R>;
|
|
31
24
|
|
|
32
|
-
export {
|
|
25
|
+
export { astLink };
|
|
@@ -1,196 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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. A call that reaches for no
|
|
42
|
-
* receiver, `new GetObjectCommand(...)`, is made by its own callee.
|
|
43
|
-
*/
|
|
44
|
-
interface ConstructedFrom {
|
|
45
|
-
readonly origin: "constructed";
|
|
46
|
-
/** The modules whose export the client was made from. */
|
|
47
|
-
readonly importedFrom: readonly string[];
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* A receiver whose method one of these modules declared. Pass every
|
|
51
|
-
* module that ships the same client, the way three packages all speak
|
|
52
|
-
* one wire protocol.
|
|
53
|
-
*/
|
|
54
|
-
declare function declaredBy(...importedFrom: readonly string[]): DeclaredBy;
|
|
55
|
-
/** A client made from one of these modules' exports. */
|
|
56
|
-
declare function constructedFrom(...importedFrom: readonly string[]): ConstructedFrom;
|
|
57
|
-
/**
|
|
58
|
-
* What a reader gives back for a name nothing in the source settles.
|
|
59
|
-
* `"nothing"` gives null, `"reference"` gives the value to go and ask
|
|
60
|
-
* about instead.
|
|
61
|
-
*/
|
|
62
|
-
type UnsettledName = "nothing" | "reference";
|
|
63
|
-
/**
|
|
64
|
-
* One value a call states, as the questions a pack can ask about it.
|
|
65
|
-
*
|
|
66
|
-
* `CallOps` reaches a call beside the one in hand, and this reaches the
|
|
67
|
-
* values that are not calls. A library that takes one request object
|
|
68
|
-
* puts everything the call is doing inside it, sometimes as a list and
|
|
69
|
-
* sometimes as a string in a little language of the library's own, and
|
|
70
|
-
* a pack that reads those is handed this rather than the adapter's own
|
|
71
|
-
* node. So the rule it writes runs wherever the ops do.
|
|
72
|
-
*/
|
|
73
|
-
interface ValueOps {
|
|
74
|
-
/** The text of the string the source wrote, or null for anything else. */
|
|
75
|
-
text(): string | null;
|
|
76
|
-
/**
|
|
77
|
-
* The yes or no the source wrote here, or null for anything else. A
|
|
78
|
-
* library that asks which fields a call wants states them as a map of
|
|
79
|
-
* flags, `{ name: 1, password: 0 }`, and a number and a boolean mean
|
|
80
|
-
* the same thing in one of those.
|
|
81
|
-
*/
|
|
82
|
-
flag(): boolean | null;
|
|
83
|
-
/** What this object states, entry by entry. Empty for anything else. */
|
|
84
|
-
entries(unsettled: UnsettledName): readonly ValueEntry[];
|
|
85
|
-
/** What this list states, item by item. Empty for anything else. */
|
|
86
|
-
items(): readonly ValueOps[];
|
|
87
|
-
/** What one named property of this object states, or null for none. */
|
|
88
|
-
property(name: string): ValueOps | null;
|
|
89
|
-
/**
|
|
90
|
-
* The pieces of text the source wrote here, in order, with whatever
|
|
91
|
-
* it interpolated between them left out. A string is one piece and a
|
|
92
|
-
* template is one piece per hole plus one, so a reader that means to
|
|
93
|
-
* put its own placeholders in the holes can. Null when the source
|
|
94
|
-
* wrote neither.
|
|
95
|
-
*/
|
|
96
|
-
parts(): readonly string[] | null;
|
|
97
|
-
/**
|
|
98
|
-
* What the source interpolated between those pieces, in order, each
|
|
99
|
-
* as the call it was written as. There is one per gap, one fewer than
|
|
100
|
-
* `parts` gives, and a hole the source wrote as something other than
|
|
101
|
-
* a call is null rather than being dropped, so the two lists stay in
|
|
102
|
-
* step.
|
|
103
|
-
*
|
|
104
|
-
* What a hole comes to is the pack's to say. This says what was
|
|
105
|
-
* there, so a query that hands over a table object can still be read.
|
|
106
|
-
*/
|
|
107
|
-
holes(): readonly (CallOps | null)[];
|
|
108
|
-
}
|
|
109
|
-
/** One entry of an object a call states. */
|
|
110
|
-
interface ValueEntry {
|
|
111
|
-
/**
|
|
112
|
-
* What the entry is called. A key the source computes,
|
|
113
|
-
* `{ [table]: ... }`, is read the way any other name is.
|
|
114
|
-
*/
|
|
115
|
-
readonly key: string | null;
|
|
116
|
-
/** What the entry says. */
|
|
117
|
-
readonly value: ValueOps;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* One call site, as the questions a chain asks about it.
|
|
121
|
-
*
|
|
122
|
-
* An adapter builds one of these per call and hands it to the
|
|
123
|
-
* recognizer through its context. Every member is about the call in
|
|
124
|
-
* hand, so there is no node to pass around and no place for a pack to
|
|
125
|
-
* reach past what it declared.
|
|
126
|
-
*
|
|
127
|
-
* Two members give back another `CallOps`, which is how these questions
|
|
128
|
-
* reach a call next to this one. A chain of calls and a command object
|
|
129
|
-
* are both these same questions asked one step along, so neither needed
|
|
130
|
-
* a question of its own.
|
|
131
|
-
*/
|
|
132
|
-
interface CallOps {
|
|
133
|
-
/** Which method the call reaches for, spelled as the source spells it. */
|
|
134
|
-
method(): string | null;
|
|
135
|
-
/** Whether the receiver came from where the origin says. */
|
|
136
|
-
receiverIsFrom(origin: ReceiverOrigin): boolean;
|
|
137
|
-
/**
|
|
138
|
-
* Whether the call itself came from where the origin says, which is
|
|
139
|
-
* the same question asked of the callee rather than of what it was
|
|
140
|
-
* called on. `new GetCommand(...)` is the case: a pack that steps to
|
|
141
|
-
* an argument asks this of it before reading anything, so it never
|
|
142
|
-
* reads an argument that was never the one.
|
|
143
|
-
*/
|
|
144
|
-
isFrom(origin: ReceiverOrigin): boolean;
|
|
145
|
-
/** How many arguments the call passes. */
|
|
146
|
-
argumentCount(): number;
|
|
147
|
-
/** The name the argument in this position gives. */
|
|
148
|
-
nameAt(index: number, unsettled: UnsettledName): string | null;
|
|
149
|
-
/** The callee, as the source writes it. */
|
|
150
|
-
calleeText(): string;
|
|
151
|
-
/**
|
|
152
|
-
* The call the receiver is, or null when the receiver is not a call.
|
|
153
|
-
* A receiver the source wrote into a variable comes back as the call
|
|
154
|
-
* it was written as.
|
|
155
|
-
*/
|
|
156
|
-
receiver(): CallOps | null;
|
|
157
|
-
/**
|
|
158
|
-
* The call the argument in this position is, or null when that
|
|
159
|
-
* argument is neither a call nor a construction. `new
|
|
160
|
-
* GetObjectCommand(...)` comes back as a call whose callee is the
|
|
161
|
-
* class, the same as any other call.
|
|
162
|
-
*/
|
|
163
|
-
argument(index: number): CallOps | null;
|
|
164
|
-
/**
|
|
165
|
-
* The call the callee itself was written as, or null when nothing
|
|
166
|
-
* wrote it as one. A class a factory made is the case: `new
|
|
167
|
-
* User({...})` says nothing about what `User` is, and the
|
|
168
|
-
* `model("User", schema)` call it was declared as says everything.
|
|
169
|
-
*/
|
|
170
|
-
callee(): CallOps | null;
|
|
171
|
-
/**
|
|
172
|
-
* What a named property of the object an argument states says. A
|
|
173
|
-
* property bag is not a call, so nothing else here reaches into one.
|
|
174
|
-
*/
|
|
175
|
-
propertyAt(index: number, property: string, unsettled: UnsettledName): string | null;
|
|
176
|
-
/**
|
|
177
|
-
* The value the argument in this position states, or null when the
|
|
178
|
-
* call passes none. `propertyAt` reads one name out of a property
|
|
179
|
-
* bag, which covers a pack that wants one; this hands the bag over
|
|
180
|
-
* for a pack whose rule has to walk it.
|
|
181
|
-
*/
|
|
182
|
-
valueAt(index: number): ValueOps | null;
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* The property an adapter puts its ops on, in the context it hands a
|
|
186
|
-
* recognizer. A context without it belongs to an adapter that has not
|
|
187
|
-
* implemented the ops, and a declared pack matches nothing there.
|
|
188
|
-
*/
|
|
189
|
-
interface OpsCarrier {
|
|
190
|
-
ops?: CallOps;
|
|
191
|
-
}
|
|
192
|
-
/** The ops in a recognizer context, or null when the adapter has none. */
|
|
193
|
-
declare function opsIn(ctx: unknown): CallOps | null;
|
|
1
|
+
import { MessageBusSemantics } from '@suss/behavioral-ir';
|
|
2
|
+
import { ReceiverOrigin, ValueOps, CallOps, UnsettledName } from '@suss/extractor';
|
|
194
3
|
|
|
195
4
|
/**
|
|
196
5
|
* The spine every pack shares, as a chain of links.
|
|
@@ -475,9 +284,14 @@ interface SqlMethod {
|
|
|
475
284
|
readonly statement: OneArgument;
|
|
476
285
|
}
|
|
477
286
|
/** What one method table can say a method does. */
|
|
478
|
-
|
|
287
|
+
/** What one send method does, as the message-send ending reads it. */
|
|
288
|
+
interface MessageSendMethod {
|
|
289
|
+
/** Where the call states the message, or the collection of them. */
|
|
290
|
+
readonly input: OneArgument;
|
|
291
|
+
}
|
|
292
|
+
type MethodMeaning = StorageMethod | SqlMethod | MessageSendMethod;
|
|
479
293
|
/** What a chain produces when every link matches. */
|
|
480
|
-
type Ending = StorageEnding | SqlEnding;
|
|
294
|
+
type Ending = StorageEnding | SqlEnding | MessageSendEnding;
|
|
481
295
|
/** A storage access: one call, one thing it read or wrote. */
|
|
482
296
|
interface StorageEnding {
|
|
483
297
|
readonly yields: "storageAccess";
|
|
@@ -516,6 +330,61 @@ interface SqlEnding {
|
|
|
516
330
|
*/
|
|
517
331
|
readonly dialect: string;
|
|
518
332
|
}
|
|
333
|
+
/**
|
|
334
|
+
* Where the messages a call sends are written.
|
|
335
|
+
*
|
|
336
|
+
* A library either takes one message as the call's input or takes a
|
|
337
|
+
* collection of them under a property. Which of the two is a fact about
|
|
338
|
+
* the command, so a library offering both spells them as two
|
|
339
|
+
* declarations rather than one with a setting on it: SQS has
|
|
340
|
+
* `SendMessageCommand` and `SendMessageBatchCommand`, and they are
|
|
341
|
+
* different shapes.
|
|
342
|
+
*/
|
|
343
|
+
type MessageLocation = OneMessage | ManyIn;
|
|
344
|
+
/** The call's input is the message. */
|
|
345
|
+
interface OneMessage {
|
|
346
|
+
readonly each: "theInput";
|
|
347
|
+
}
|
|
348
|
+
/** A property of the call's input contains the messages, one each. */
|
|
349
|
+
interface ManyIn {
|
|
350
|
+
readonly each: "in";
|
|
351
|
+
/** The property the collection is written on. */
|
|
352
|
+
readonly property: string;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* One part of the channel a message goes to, read off the message.
|
|
356
|
+
*
|
|
357
|
+
* A channel is one name on some wires and several on others. SQS has a
|
|
358
|
+
* queue, EventBridge has a bus and a subject on it, and both are read
|
|
359
|
+
* the same way, so a pack states the parts in the order they join.
|
|
360
|
+
*/
|
|
361
|
+
interface ChannelPart {
|
|
362
|
+
/** The property the message states this part on. */
|
|
363
|
+
readonly property: string;
|
|
364
|
+
/** What the library uses when the message leaves this part out. */
|
|
365
|
+
readonly whenAbsent?: string;
|
|
366
|
+
}
|
|
367
|
+
/** A message sent on a wire, which pairs with whatever consumes that channel. */
|
|
368
|
+
interface MessageSendEnding {
|
|
369
|
+
readonly yields: "messageSend";
|
|
370
|
+
/** The wire, in the words the IR's message-bus semantics use. */
|
|
371
|
+
readonly wire: MessageBusSemantics["messageBus"];
|
|
372
|
+
/** Where the messages are. */
|
|
373
|
+
readonly messages: MessageLocation;
|
|
374
|
+
/** The parts of the channel, joined in the order they are written. */
|
|
375
|
+
readonly channel: readonly ChannelPart[];
|
|
376
|
+
/** What joins the parts, when there is more than one. */
|
|
377
|
+
readonly channelSeparator?: string;
|
|
378
|
+
/** The property the message states its body on, when the pack can say. */
|
|
379
|
+
readonly body?: string;
|
|
380
|
+
/**
|
|
381
|
+
* What a reader gives back for a channel nothing in the source
|
|
382
|
+
* settles. A queue URL only exists at deploy time, so the code writes
|
|
383
|
+
* `process.env.ORDERS_QUEUE_URL` and the env var's name is what both
|
|
384
|
+
* sides of the boundary agree on. `"reference"` keeps that name.
|
|
385
|
+
*/
|
|
386
|
+
readonly unsettledName: UnsettledName;
|
|
387
|
+
}
|
|
519
388
|
/**
|
|
520
389
|
* A pack's declaration for one kind of call: the links, the ending, and
|
|
521
390
|
* a line of code it matches.
|
|
@@ -527,4 +396,4 @@ interface Chain<TMeaning = MethodMeaning> {
|
|
|
527
396
|
readonly example: string | null;
|
|
528
397
|
}
|
|
529
398
|
|
|
530
|
-
export {
|
|
399
|
+
export type { ArgumentPick as A, ToReceiver as B, Chain as C, Ending as E, FromReceiver as F, InterpolatesLink as I, KindAsAsked as K, LinkFunction as L, MethodMeaning as M, OneArgument as O, SqlMethod as S, ToArgument as T, MessageSendMethod as a, MessageLocation as b, ChannelPart as c, CallStep as d, StorageMethod as e, AccessKind as f, AccessPathLink as g, ArgumentsFrom as h, ContainerArgument as i, ContainerLink as j, ContainerRule as k, ContainersLink as l, InputLink as m, InputRule as n, Link as o, ManyIn as p, MatchStart as q, MessageSendEnding as r, MethodsLink as s, OneMessage as t, SqlEnding as u, StartLink as v, StatedInputs as w, StatedRule as x, StorageEnding as y, SubjectLink as z };
|
|
@@ -1,196 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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. A call that reaches for no
|
|
42
|
-
* receiver, `new GetObjectCommand(...)`, is made by its own callee.
|
|
43
|
-
*/
|
|
44
|
-
interface ConstructedFrom {
|
|
45
|
-
readonly origin: "constructed";
|
|
46
|
-
/** The modules whose export the client was made from. */
|
|
47
|
-
readonly importedFrom: readonly string[];
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* A receiver whose method one of these modules declared. Pass every
|
|
51
|
-
* module that ships the same client, the way three packages all speak
|
|
52
|
-
* one wire protocol.
|
|
53
|
-
*/
|
|
54
|
-
declare function declaredBy(...importedFrom: readonly string[]): DeclaredBy;
|
|
55
|
-
/** A client made from one of these modules' exports. */
|
|
56
|
-
declare function constructedFrom(...importedFrom: readonly string[]): ConstructedFrom;
|
|
57
|
-
/**
|
|
58
|
-
* What a reader gives back for a name nothing in the source settles.
|
|
59
|
-
* `"nothing"` gives null, `"reference"` gives the value to go and ask
|
|
60
|
-
* about instead.
|
|
61
|
-
*/
|
|
62
|
-
type UnsettledName = "nothing" | "reference";
|
|
63
|
-
/**
|
|
64
|
-
* One value a call states, as the questions a pack can ask about it.
|
|
65
|
-
*
|
|
66
|
-
* `CallOps` reaches a call beside the one in hand, and this reaches the
|
|
67
|
-
* values that are not calls. A library that takes one request object
|
|
68
|
-
* puts everything the call is doing inside it, sometimes as a list and
|
|
69
|
-
* sometimes as a string in a little language of the library's own, and
|
|
70
|
-
* a pack that reads those is handed this rather than the adapter's own
|
|
71
|
-
* node. So the rule it writes runs wherever the ops do.
|
|
72
|
-
*/
|
|
73
|
-
interface ValueOps {
|
|
74
|
-
/** The text of the string the source wrote, or null for anything else. */
|
|
75
|
-
text(): string | null;
|
|
76
|
-
/**
|
|
77
|
-
* The yes or no the source wrote here, or null for anything else. A
|
|
78
|
-
* library that asks which fields a call wants states them as a map of
|
|
79
|
-
* flags, `{ name: 1, password: 0 }`, and a number and a boolean mean
|
|
80
|
-
* the same thing in one of those.
|
|
81
|
-
*/
|
|
82
|
-
flag(): boolean | null;
|
|
83
|
-
/** What this object states, entry by entry. Empty for anything else. */
|
|
84
|
-
entries(unsettled: UnsettledName): readonly ValueEntry[];
|
|
85
|
-
/** What this list states, item by item. Empty for anything else. */
|
|
86
|
-
items(): readonly ValueOps[];
|
|
87
|
-
/** What one named property of this object states, or null for none. */
|
|
88
|
-
property(name: string): ValueOps | null;
|
|
89
|
-
/**
|
|
90
|
-
* The pieces of text the source wrote here, in order, with whatever
|
|
91
|
-
* it interpolated between them left out. A string is one piece and a
|
|
92
|
-
* template is one piece per hole plus one, so a reader that means to
|
|
93
|
-
* put its own placeholders in the holes can. Null when the source
|
|
94
|
-
* wrote neither.
|
|
95
|
-
*/
|
|
96
|
-
parts(): readonly string[] | null;
|
|
97
|
-
/**
|
|
98
|
-
* What the source interpolated between those pieces, in order, each
|
|
99
|
-
* as the call it was written as. There is one per gap, one fewer than
|
|
100
|
-
* `parts` gives, and a hole the source wrote as something other than
|
|
101
|
-
* a call is null rather than being dropped, so the two lists stay in
|
|
102
|
-
* step.
|
|
103
|
-
*
|
|
104
|
-
* What a hole comes to is the pack's to say. This says what was
|
|
105
|
-
* there, so a query that hands over a table object can still be read.
|
|
106
|
-
*/
|
|
107
|
-
holes(): readonly (CallOps | null)[];
|
|
108
|
-
}
|
|
109
|
-
/** One entry of an object a call states. */
|
|
110
|
-
interface ValueEntry {
|
|
111
|
-
/**
|
|
112
|
-
* What the entry is called. A key the source computes,
|
|
113
|
-
* `{ [table]: ... }`, is read the way any other name is.
|
|
114
|
-
*/
|
|
115
|
-
readonly key: string | null;
|
|
116
|
-
/** What the entry says. */
|
|
117
|
-
readonly value: ValueOps;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* One call site, as the questions a chain asks about it.
|
|
121
|
-
*
|
|
122
|
-
* An adapter builds one of these per call and hands it to the
|
|
123
|
-
* recognizer through its context. Every member is about the call in
|
|
124
|
-
* hand, so there is no node to pass around and no place for a pack to
|
|
125
|
-
* reach past what it declared.
|
|
126
|
-
*
|
|
127
|
-
* Two members give back another `CallOps`, which is how these questions
|
|
128
|
-
* reach a call next to this one. A chain of calls and a command object
|
|
129
|
-
* are both these same questions asked one step along, so neither needed
|
|
130
|
-
* a question of its own.
|
|
131
|
-
*/
|
|
132
|
-
interface CallOps {
|
|
133
|
-
/** Which method the call reaches for, spelled as the source spells it. */
|
|
134
|
-
method(): string | null;
|
|
135
|
-
/** Whether the receiver came from where the origin says. */
|
|
136
|
-
receiverIsFrom(origin: ReceiverOrigin): boolean;
|
|
137
|
-
/**
|
|
138
|
-
* Whether the call itself came from where the origin says, which is
|
|
139
|
-
* the same question asked of the callee rather than of what it was
|
|
140
|
-
* called on. `new GetCommand(...)` is the case: a pack that steps to
|
|
141
|
-
* an argument asks this of it before reading anything, so it never
|
|
142
|
-
* reads an argument that was never the one.
|
|
143
|
-
*/
|
|
144
|
-
isFrom(origin: ReceiverOrigin): boolean;
|
|
145
|
-
/** How many arguments the call passes. */
|
|
146
|
-
argumentCount(): number;
|
|
147
|
-
/** The name the argument in this position gives. */
|
|
148
|
-
nameAt(index: number, unsettled: UnsettledName): string | null;
|
|
149
|
-
/** The callee, as the source writes it. */
|
|
150
|
-
calleeText(): string;
|
|
151
|
-
/**
|
|
152
|
-
* The call the receiver is, or null when the receiver is not a call.
|
|
153
|
-
* A receiver the source wrote into a variable comes back as the call
|
|
154
|
-
* it was written as.
|
|
155
|
-
*/
|
|
156
|
-
receiver(): CallOps | null;
|
|
157
|
-
/**
|
|
158
|
-
* The call the argument in this position is, or null when that
|
|
159
|
-
* argument is neither a call nor a construction. `new
|
|
160
|
-
* GetObjectCommand(...)` comes back as a call whose callee is the
|
|
161
|
-
* class, the same as any other call.
|
|
162
|
-
*/
|
|
163
|
-
argument(index: number): CallOps | null;
|
|
164
|
-
/**
|
|
165
|
-
* The call the callee itself was written as, or null when nothing
|
|
166
|
-
* wrote it as one. A class a factory made is the case: `new
|
|
167
|
-
* User({...})` says nothing about what `User` is, and the
|
|
168
|
-
* `model("User", schema)` call it was declared as says everything.
|
|
169
|
-
*/
|
|
170
|
-
callee(): CallOps | null;
|
|
171
|
-
/**
|
|
172
|
-
* What a named property of the object an argument states says. A
|
|
173
|
-
* property bag is not a call, so nothing else here reaches into one.
|
|
174
|
-
*/
|
|
175
|
-
propertyAt(index: number, property: string, unsettled: UnsettledName): string | null;
|
|
176
|
-
/**
|
|
177
|
-
* The value the argument in this position states, or null when the
|
|
178
|
-
* call passes none. `propertyAt` reads one name out of a property
|
|
179
|
-
* bag, which covers a pack that wants one; this hands the bag over
|
|
180
|
-
* for a pack whose rule has to walk it.
|
|
181
|
-
*/
|
|
182
|
-
valueAt(index: number): ValueOps | null;
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* The property an adapter puts its ops on, in the context it hands a
|
|
186
|
-
* recognizer. A context without it belongs to an adapter that has not
|
|
187
|
-
* implemented the ops, and a declared pack matches nothing there.
|
|
188
|
-
*/
|
|
189
|
-
interface OpsCarrier {
|
|
190
|
-
ops?: CallOps;
|
|
191
|
-
}
|
|
192
|
-
/** The ops in a recognizer context, or null when the adapter has none. */
|
|
193
|
-
declare function opsIn(ctx: unknown): CallOps | null;
|
|
1
|
+
import { MessageBusSemantics } from '@suss/behavioral-ir';
|
|
2
|
+
import { ReceiverOrigin, ValueOps, CallOps, UnsettledName } from '@suss/extractor';
|
|
194
3
|
|
|
195
4
|
/**
|
|
196
5
|
* The spine every pack shares, as a chain of links.
|
|
@@ -475,9 +284,14 @@ interface SqlMethod {
|
|
|
475
284
|
readonly statement: OneArgument;
|
|
476
285
|
}
|
|
477
286
|
/** What one method table can say a method does. */
|
|
478
|
-
|
|
287
|
+
/** What one send method does, as the message-send ending reads it. */
|
|
288
|
+
interface MessageSendMethod {
|
|
289
|
+
/** Where the call states the message, or the collection of them. */
|
|
290
|
+
readonly input: OneArgument;
|
|
291
|
+
}
|
|
292
|
+
type MethodMeaning = StorageMethod | SqlMethod | MessageSendMethod;
|
|
479
293
|
/** What a chain produces when every link matches. */
|
|
480
|
-
type Ending = StorageEnding | SqlEnding;
|
|
294
|
+
type Ending = StorageEnding | SqlEnding | MessageSendEnding;
|
|
481
295
|
/** A storage access: one call, one thing it read or wrote. */
|
|
482
296
|
interface StorageEnding {
|
|
483
297
|
readonly yields: "storageAccess";
|
|
@@ -516,6 +330,61 @@ interface SqlEnding {
|
|
|
516
330
|
*/
|
|
517
331
|
readonly dialect: string;
|
|
518
332
|
}
|
|
333
|
+
/**
|
|
334
|
+
* Where the messages a call sends are written.
|
|
335
|
+
*
|
|
336
|
+
* A library either takes one message as the call's input or takes a
|
|
337
|
+
* collection of them under a property. Which of the two is a fact about
|
|
338
|
+
* the command, so a library offering both spells them as two
|
|
339
|
+
* declarations rather than one with a setting on it: SQS has
|
|
340
|
+
* `SendMessageCommand` and `SendMessageBatchCommand`, and they are
|
|
341
|
+
* different shapes.
|
|
342
|
+
*/
|
|
343
|
+
type MessageLocation = OneMessage | ManyIn;
|
|
344
|
+
/** The call's input is the message. */
|
|
345
|
+
interface OneMessage {
|
|
346
|
+
readonly each: "theInput";
|
|
347
|
+
}
|
|
348
|
+
/** A property of the call's input contains the messages, one each. */
|
|
349
|
+
interface ManyIn {
|
|
350
|
+
readonly each: "in";
|
|
351
|
+
/** The property the collection is written on. */
|
|
352
|
+
readonly property: string;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* One part of the channel a message goes to, read off the message.
|
|
356
|
+
*
|
|
357
|
+
* A channel is one name on some wires and several on others. SQS has a
|
|
358
|
+
* queue, EventBridge has a bus and a subject on it, and both are read
|
|
359
|
+
* the same way, so a pack states the parts in the order they join.
|
|
360
|
+
*/
|
|
361
|
+
interface ChannelPart {
|
|
362
|
+
/** The property the message states this part on. */
|
|
363
|
+
readonly property: string;
|
|
364
|
+
/** What the library uses when the message leaves this part out. */
|
|
365
|
+
readonly whenAbsent?: string;
|
|
366
|
+
}
|
|
367
|
+
/** A message sent on a wire, which pairs with whatever consumes that channel. */
|
|
368
|
+
interface MessageSendEnding {
|
|
369
|
+
readonly yields: "messageSend";
|
|
370
|
+
/** The wire, in the words the IR's message-bus semantics use. */
|
|
371
|
+
readonly wire: MessageBusSemantics["messageBus"];
|
|
372
|
+
/** Where the messages are. */
|
|
373
|
+
readonly messages: MessageLocation;
|
|
374
|
+
/** The parts of the channel, joined in the order they are written. */
|
|
375
|
+
readonly channel: readonly ChannelPart[];
|
|
376
|
+
/** What joins the parts, when there is more than one. */
|
|
377
|
+
readonly channelSeparator?: string;
|
|
378
|
+
/** The property the message states its body on, when the pack can say. */
|
|
379
|
+
readonly body?: string;
|
|
380
|
+
/**
|
|
381
|
+
* What a reader gives back for a channel nothing in the source
|
|
382
|
+
* settles. A queue URL only exists at deploy time, so the code writes
|
|
383
|
+
* `process.env.ORDERS_QUEUE_URL` and the env var's name is what both
|
|
384
|
+
* sides of the boundary agree on. `"reference"` keeps that name.
|
|
385
|
+
*/
|
|
386
|
+
readonly unsettledName: UnsettledName;
|
|
387
|
+
}
|
|
519
388
|
/**
|
|
520
389
|
* A pack's declaration for one kind of call: the links, the ending, and
|
|
521
390
|
* a line of code it matches.
|
|
@@ -527,4 +396,4 @@ interface Chain<TMeaning = MethodMeaning> {
|
|
|
527
396
|
readonly example: string | null;
|
|
528
397
|
}
|
|
529
398
|
|
|
530
|
-
export {
|
|
399
|
+
export type { ArgumentPick as A, ToReceiver as B, Chain as C, Ending as E, FromReceiver as F, InterpolatesLink as I, KindAsAsked as K, LinkFunction as L, MethodMeaning as M, OneArgument as O, SqlMethod as S, ToArgument as T, MessageSendMethod as a, MessageLocation as b, ChannelPart as c, CallStep as d, StorageMethod as e, AccessKind as f, AccessPathLink as g, ArgumentsFrom as h, ContainerArgument as i, ContainerLink as j, ContainerRule as k, ContainersLink as l, InputLink as m, InputRule as n, Link as o, ManyIn as p, MatchStart as q, MessageSendEnding as r, MethodsLink as s, OneMessage as t, SqlEnding as u, StartLink as v, StatedInputs as w, StatedRule as x, StorageEnding as y, SubjectLink as z };
|
package/dist/index.cjs
CHANGED
|
@@ -25,6 +25,7 @@ __export(index_exports, {
|
|
|
25
25
|
declarationsIn: () => declarationsIn,
|
|
26
26
|
declaredBy: () => declaredBy,
|
|
27
27
|
examplesMissing: () => examplesMissing,
|
|
28
|
+
messageSends: () => messageSends,
|
|
28
29
|
opsIn: () => opsIn,
|
|
29
30
|
pack: () => pack,
|
|
30
31
|
runExamples: () => runExamples,
|
|
@@ -41,8 +42,16 @@ var import_sql = require("@suss/sql");
|
|
|
41
42
|
function declaredBy(...importedFrom) {
|
|
42
43
|
return { origin: "declaredBy", importedFrom };
|
|
43
44
|
}
|
|
44
|
-
function constructedFrom(...
|
|
45
|
-
|
|
45
|
+
function constructedFrom(...args) {
|
|
46
|
+
const [first] = args;
|
|
47
|
+
if (typeof first === "object") {
|
|
48
|
+
return {
|
|
49
|
+
origin: "constructed",
|
|
50
|
+
importedFrom: first.from,
|
|
51
|
+
named: first.named
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return { origin: "constructed", importedFrom: args };
|
|
46
55
|
}
|
|
47
56
|
function opsIn(ctx) {
|
|
48
57
|
const carrier = ctx;
|
|
@@ -152,7 +161,8 @@ function startsHere(chain, subject) {
|
|
|
152
161
|
}
|
|
153
162
|
var YIELD = {
|
|
154
163
|
storageAccess,
|
|
155
|
-
sqlAccess
|
|
164
|
+
sqlAccess,
|
|
165
|
+
messageSend
|
|
156
166
|
};
|
|
157
167
|
function storageAccess(matched) {
|
|
158
168
|
const { subject, chain } = matched;
|
|
@@ -247,6 +257,7 @@ function statedValue(subject, pick) {
|
|
|
247
257
|
}
|
|
248
258
|
var NOTHING_STATED = {
|
|
249
259
|
text: () => null,
|
|
260
|
+
name: () => null,
|
|
250
261
|
flag: () => null,
|
|
251
262
|
entries: () => [],
|
|
252
263
|
items: () => [],
|
|
@@ -299,6 +310,57 @@ function nameOf(ops, pick, index, unsettled) {
|
|
|
299
310
|
}
|
|
300
311
|
return null;
|
|
301
312
|
}
|
|
313
|
+
function messageSend(matched) {
|
|
314
|
+
const { ops, subject, chain, recognition } = matched;
|
|
315
|
+
const ending = chain.ending;
|
|
316
|
+
const input = statedValue(
|
|
317
|
+
subject,
|
|
318
|
+
matched.meaning.input
|
|
319
|
+
);
|
|
320
|
+
if (input === null) {
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
const messages = messagesIn(input, ending.messages);
|
|
324
|
+
return messages.length === 0 ? null : messages.map((message) => ({
|
|
325
|
+
type: "interaction",
|
|
326
|
+
binding: (0, import_behavioral_ir.messageBusBinding)({
|
|
327
|
+
recognition,
|
|
328
|
+
messageBus: ending.wire,
|
|
329
|
+
channel: channelOf(message, ending)
|
|
330
|
+
}),
|
|
331
|
+
callee: ops.calleeText(),
|
|
332
|
+
interaction: {
|
|
333
|
+
class: "message-send",
|
|
334
|
+
...bodyOf(message, ending)
|
|
335
|
+
}
|
|
336
|
+
}));
|
|
337
|
+
}
|
|
338
|
+
function messagesIn(input, location) {
|
|
339
|
+
if (location.each === "theInput") {
|
|
340
|
+
return [input];
|
|
341
|
+
}
|
|
342
|
+
const collection = input.property(location.property);
|
|
343
|
+
return collection === null ? [] : collection.items();
|
|
344
|
+
}
|
|
345
|
+
function channelOf(message, ending) {
|
|
346
|
+
const parts = [];
|
|
347
|
+
for (const part of ending.channel) {
|
|
348
|
+
const stated = message.property(part.property)?.name(ending.unsettledName) ?? null;
|
|
349
|
+
const value = stated === null || stated === "" ? part.whenAbsent : stated;
|
|
350
|
+
if (value === void 0) {
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
parts.push(value);
|
|
354
|
+
}
|
|
355
|
+
return parts.join(ending.channelSeparator ?? "#");
|
|
356
|
+
}
|
|
357
|
+
function bodyOf(message, ending) {
|
|
358
|
+
if (ending.body === void 0) {
|
|
359
|
+
return {};
|
|
360
|
+
}
|
|
361
|
+
const stated = message.property(ending.body)?.text() ?? null;
|
|
362
|
+
return stated === null ? {} : { body: stated };
|
|
363
|
+
}
|
|
302
364
|
function sqlAccess(matched) {
|
|
303
365
|
const { ops, subject, method, chain, recognition } = matched;
|
|
304
366
|
const ending = chain.ending;
|
|
@@ -362,10 +424,46 @@ function examplesMissing(pack2) {
|
|
|
362
424
|
return (pack2.declarations?.declarations ?? []).filter((declaration) => declaration.example === null).map((declaration) => declaration.name);
|
|
363
425
|
}
|
|
364
426
|
|
|
427
|
+
// src/chain.ts
|
|
428
|
+
function chainStart(client) {
|
|
429
|
+
return client === void 0 ? [] : [{ asks: "start", at: { starts: "receiver", origin: client } }];
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// src/messageSends.ts
|
|
433
|
+
function messageSends(spec) {
|
|
434
|
+
const ending = {
|
|
435
|
+
yields: "messageSend",
|
|
436
|
+
wire: spec.wire,
|
|
437
|
+
messages: spec.messages,
|
|
438
|
+
channel: spec.channel,
|
|
439
|
+
...spec.channelSeparator === void 0 ? {} : { channelSeparator: spec.channelSeparator },
|
|
440
|
+
...spec.body === void 0 ? {} : { body: spec.body },
|
|
441
|
+
unsettledName: spec.unsettledName ?? "reference"
|
|
442
|
+
};
|
|
443
|
+
return chainFrom({
|
|
444
|
+
links: chainStart(spec.client),
|
|
445
|
+
ending,
|
|
446
|
+
example: null
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
function chainFrom(declared) {
|
|
450
|
+
const adding = (link) => chainFrom({ ...declared, links: [...declared.links, link] });
|
|
451
|
+
return {
|
|
452
|
+
declared,
|
|
453
|
+
methods: (table, options) => adding({
|
|
454
|
+
asks: "methods",
|
|
455
|
+
table,
|
|
456
|
+
ignoringCase: options?.ignoringCase ?? false
|
|
457
|
+
}),
|
|
458
|
+
example: (code) => chainFrom({ ...declared, example: code })
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
|
|
365
462
|
// src/pack.ts
|
|
366
463
|
var DISPATCHED_ON = {
|
|
367
464
|
storageAccess: "invocation",
|
|
368
|
-
sqlAccess: "access"
|
|
465
|
+
sqlAccess: "access",
|
|
466
|
+
messageSend: "invocation"
|
|
369
467
|
};
|
|
370
468
|
function walkedBy(chains, walk2, recognizedAs) {
|
|
371
469
|
return chains.filter((chain) => DISPATCHED_ON[chain.ending.yields] === walk2).map((chain) => compile(chain, recognizedAs));
|
|
@@ -392,10 +490,17 @@ function pack(name, matches, spec) {
|
|
|
392
490
|
function declarationsIn(matches) {
|
|
393
491
|
return { declarations: matches.map((match) => describe(match.declared)) };
|
|
394
492
|
}
|
|
493
|
+
function wireOf(ending) {
|
|
494
|
+
if (ending.yields === "messageSend") {
|
|
495
|
+
return ending.wire;
|
|
496
|
+
}
|
|
497
|
+
return ending.transport ?? ending.system;
|
|
498
|
+
}
|
|
499
|
+
function declaredName(ending) {
|
|
500
|
+
return ending.yields === "messageSend" ? ending.wire : ending.system;
|
|
501
|
+
}
|
|
395
502
|
function protocolOf(chains) {
|
|
396
|
-
const wires = new Set(
|
|
397
|
-
chains.map((chain) => chain.ending.transport ?? chain.ending.system)
|
|
398
|
-
);
|
|
503
|
+
const wires = new Set(chains.map((chain) => wireOf(chain.ending)));
|
|
399
504
|
const [only] = [...wires];
|
|
400
505
|
if (wires.size !== 1 || only === void 0) {
|
|
401
506
|
throw new Error(
|
|
@@ -445,7 +550,7 @@ function describe(chain) {
|
|
|
445
550
|
...rulesIn(chain)
|
|
446
551
|
];
|
|
447
552
|
return {
|
|
448
|
-
name: chain.ending
|
|
553
|
+
name: declaredName(chain.ending),
|
|
449
554
|
// A method table with a rule inside it is still a table, so that
|
|
450
555
|
// link stays counted as data and the rule is priced beside it.
|
|
451
556
|
dataLinks: chain.links.length - links.length,
|
|
@@ -496,14 +601,14 @@ function sqlStatements(spec) {
|
|
|
496
601
|
dialect: spec.dialect
|
|
497
602
|
};
|
|
498
603
|
const client = spec.client;
|
|
499
|
-
return
|
|
500
|
-
links: client
|
|
604
|
+
return chainFrom2({
|
|
605
|
+
links: chainStart(client),
|
|
501
606
|
ending,
|
|
502
607
|
example: null
|
|
503
608
|
});
|
|
504
609
|
}
|
|
505
|
-
function
|
|
506
|
-
const adding = (link) =>
|
|
610
|
+
function chainFrom2(declared) {
|
|
611
|
+
const adding = (link) => chainFrom2({ ...declared, links: [...declared.links, link] });
|
|
507
612
|
return {
|
|
508
613
|
declared,
|
|
509
614
|
methods: (table, options) => adding({
|
|
@@ -512,7 +617,7 @@ function chainFrom(declared) {
|
|
|
512
617
|
ignoringCase: options?.ignoringCase ?? false
|
|
513
618
|
}),
|
|
514
619
|
interpolating: (says) => adding({ asks: "interpolates", ...says }),
|
|
515
|
-
example: (code) =>
|
|
620
|
+
example: (code) => chainFrom2({ ...declared, example: code })
|
|
516
621
|
};
|
|
517
622
|
}
|
|
518
623
|
|
|
@@ -526,14 +631,14 @@ function storageCalls(spec) {
|
|
|
526
631
|
unsettledName: spec.unsettledName ?? "reference"
|
|
527
632
|
};
|
|
528
633
|
const client = spec.client;
|
|
529
|
-
return
|
|
530
|
-
links: client
|
|
634
|
+
return chainFrom3({
|
|
635
|
+
links: chainStart(client),
|
|
531
636
|
ending,
|
|
532
637
|
example: null
|
|
533
638
|
});
|
|
534
639
|
}
|
|
535
|
-
function
|
|
536
|
-
const adding = (link) =>
|
|
640
|
+
function chainFrom3(declared) {
|
|
641
|
+
const adding = (link) => chainFrom3({ ...declared, links: [...declared.links, link] });
|
|
537
642
|
return {
|
|
538
643
|
declared,
|
|
539
644
|
about: (...of) => adding({ asks: "subject", of }),
|
|
@@ -548,7 +653,7 @@ function chainFrom2(declared) {
|
|
|
548
653
|
accessPath: (says) => adding({ asks: "accessPath", argument: says }),
|
|
549
654
|
containersIn: (says) => adding({ asks: "containers", in: says }),
|
|
550
655
|
input: (says) => adding({ asks: "input", at: says }),
|
|
551
|
-
example: (code) =>
|
|
656
|
+
example: (code) => chainFrom3({ ...declared, example: code })
|
|
552
657
|
};
|
|
553
658
|
}
|
|
554
659
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -558,6 +663,7 @@ function chainFrom2(declared) {
|
|
|
558
663
|
declarationsIn,
|
|
559
664
|
declaredBy,
|
|
560
665
|
examplesMissing,
|
|
666
|
+
messageSends,
|
|
561
667
|
opsIn,
|
|
562
668
|
pack,
|
|
563
669
|
runExamples,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
|
-
import { InvocationRecognizer, PatternPack, PackDeclarations } from '@suss/extractor';
|
|
2
|
-
export { DeclaredMatch, PackDeclarations, PatternPack } from '@suss/extractor';
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
5
|
-
import { Effect } from '@suss/behavioral-ir';
|
|
1
|
+
import { ConstructedFrom, DeclaredBy, CallOps, InvocationRecognizer, PatternPack, UnsettledName, ReceiverOrigin, PackDeclarations } from '@suss/extractor';
|
|
2
|
+
export { CallOps, ConstructedFrom, DeclaredBy, DeclaredMatch, OpsCarrier, PackDeclarations, PatternPack, ReceiverOrigin, UnsettledName, ValueEntry, ValueOps } from '@suss/extractor';
|
|
3
|
+
import { C as Chain, M as MethodMeaning, a as MessageSendMethod, b as MessageLocation, c as ChannelPart, S as SqlMethod, I as InterpolatesLink, d as CallStep, e as StorageMethod, A as ArgumentPick, L as LinkFunction, O as OneArgument } from './chain-58V6lcel.cjs';
|
|
4
|
+
export { f as AccessKind, g as AccessPathLink, h as ArgumentsFrom, i as ContainerArgument, j as ContainerLink, k as ContainerRule, l as ContainersLink, E as Ending, F as FromReceiver, m as InputLink, n as InputRule, K as KindAsAsked, o as Link, p as ManyIn, q as MatchStart, r as MessageSendEnding, s as MethodsLink, t as OneMessage, u as SqlEnding, v as StartLink, w as StatedInputs, x as StatedRule, y as StorageEnding, z as SubjectLink, T as ToArgument, B as ToReceiver } from './chain-58V6lcel.cjs';
|
|
5
|
+
import { Effect, MessageBusSemantics } from '@suss/behavioral-ir';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The small builders a pack writes its origins with, and the vocabulary
|
|
9
|
+
* they produce.
|
|
10
|
+
*
|
|
11
|
+
* The types live in `@suss/extractor` because an adapter implements them
|
|
12
|
+
* and never calls any of this. They are re-exported here so a pack
|
|
13
|
+
* author has one import.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A receiver whose method one of these modules declared. Pass every
|
|
18
|
+
* module that ships the same client, the way three packages all speak
|
|
19
|
+
* one wire protocol.
|
|
20
|
+
*/
|
|
21
|
+
declare function declaredBy(...importedFrom: readonly string[]): DeclaredBy;
|
|
22
|
+
/** A client made from one of these modules' exports. */
|
|
23
|
+
declare function constructedFrom(...importedFrom: readonly string[]): ConstructedFrom;
|
|
24
|
+
/** A client made from named exports of those modules. */
|
|
25
|
+
declare function constructedFrom(spec: {
|
|
26
|
+
from: readonly string[];
|
|
27
|
+
named: readonly string[];
|
|
28
|
+
}): ConstructedFrom;
|
|
29
|
+
/** The ops in a recognizer context, or null when the adapter has none. */
|
|
30
|
+
declare function opsIn(ctx: unknown): CallOps | null;
|
|
6
31
|
|
|
7
32
|
/**
|
|
8
33
|
* Turning a chain into the recognizer hook the adapters already call.
|
|
@@ -53,6 +78,57 @@ declare function runExamples(pack: PatternPack, run: RunOverCode): RanExample[];
|
|
|
53
78
|
/** The declarations a pack shipped without a line of code to run. */
|
|
54
79
|
declare function examplesMissing(pack: PatternPack): string[];
|
|
55
80
|
|
|
81
|
+
/**
|
|
82
|
+
* messageSends.ts: a pack that recognizes a call putting a message on a
|
|
83
|
+
* wire.
|
|
84
|
+
*
|
|
85
|
+
* The AWS SDK shape is the one this was written against. An operation
|
|
86
|
+
* is a command class and its arguments are one object, so the pack says
|
|
87
|
+
* which command, where the message is inside it, and which of the
|
|
88
|
+
* message's properties name the channel:
|
|
89
|
+
*
|
|
90
|
+
* client.send(new SendMessageCommand({ QueueUrl, MessageBody }))
|
|
91
|
+
* client.send(new PutEventsCommand({ Entries: [{ EventBusName, DetailType }] }))
|
|
92
|
+
*
|
|
93
|
+
* A library taking one message and a batch of them offers two commands,
|
|
94
|
+
* so a pack writes two declarations. Which of the two a command is
|
|
95
|
+
* belongs to the command rather than to a setting on one declaration.
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
interface MessageSendsSpec {
|
|
99
|
+
/** The wire, in the words the IR's message-bus semantics use. */
|
|
100
|
+
wire: MessageBusSemantics["messageBus"];
|
|
101
|
+
/** Where the messages are: the call's input, or a property holding many. */
|
|
102
|
+
messages: MessageLocation;
|
|
103
|
+
/** The parts of the channel, joined in the order they are written. */
|
|
104
|
+
channel: readonly ChannelPart[];
|
|
105
|
+
/** What joins the parts. Defaults to "#", which is what a bus and a subject use. */
|
|
106
|
+
channelSeparator?: string;
|
|
107
|
+
/** The property a message states its body on. */
|
|
108
|
+
body?: string;
|
|
109
|
+
/**
|
|
110
|
+
* What a reader gives back for a channel nothing in the source
|
|
111
|
+
* settles. Defaults to keeping the reference, since a queue named
|
|
112
|
+
* only at deploy time is the common case rather than the exception.
|
|
113
|
+
*/
|
|
114
|
+
unsettledName?: UnsettledName;
|
|
115
|
+
/** How the pack pins down the client its calls are on. */
|
|
116
|
+
client?: ReceiverOrigin;
|
|
117
|
+
}
|
|
118
|
+
/** A chain over sends, and the links that can still be added. */
|
|
119
|
+
interface MessageSends {
|
|
120
|
+
/** Which methods send, and where each one states the message. */
|
|
121
|
+
methods(table: Readonly<Record<string, MessageSendMethod>>, options?: {
|
|
122
|
+
ignoringCase?: boolean;
|
|
123
|
+
}): MessageSends;
|
|
124
|
+
/** A line of code this matches, which the pack's tests run. */
|
|
125
|
+
example(code: string): MessageSends;
|
|
126
|
+
/** The links and the ending, as data. */
|
|
127
|
+
readonly declared: Chain<MessageSendMethod>;
|
|
128
|
+
}
|
|
129
|
+
/** A pack that recognizes a call sending a message. */
|
|
130
|
+
declare function messageSends(spec: MessageSendsSpec): MessageSends;
|
|
131
|
+
|
|
56
132
|
/**
|
|
57
133
|
* Assembling declared chains into the pack the adapters load.
|
|
58
134
|
*
|
|
@@ -225,4 +301,4 @@ interface StorageCalls {
|
|
|
225
301
|
/** A pack that recognizes calls against a store. */
|
|
226
302
|
declare function storageCalls(spec: StorageCallsSpec): StorageCalls;
|
|
227
303
|
|
|
228
|
-
export { ArgumentPick,
|
|
304
|
+
export { ArgumentPick, CallStep, Chain, ChannelPart, InterpolatesLink, LinkFunction, type Match, MessageLocation, MessageSendMethod, type MessageSends, type MessageSendsSpec, MethodMeaning, OneArgument, type PackSpec, type RanExample, type RunOverCode, SqlMethod, type SqlStatements, type SqlStatementsSpec, type StorageCalls, type StorageCallsSpec, StorageMethod, compile, constructedFrom, declarationsIn, declaredBy, examplesMissing, messageSends, opsIn, pack, runExamples, sqlStatements, storageCalls };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
|
-
import { InvocationRecognizer, PatternPack, PackDeclarations } from '@suss/extractor';
|
|
2
|
-
export { DeclaredMatch, PackDeclarations, PatternPack } from '@suss/extractor';
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
5
|
-
import { Effect } from '@suss/behavioral-ir';
|
|
1
|
+
import { ConstructedFrom, DeclaredBy, CallOps, InvocationRecognizer, PatternPack, UnsettledName, ReceiverOrigin, PackDeclarations } from '@suss/extractor';
|
|
2
|
+
export { CallOps, ConstructedFrom, DeclaredBy, DeclaredMatch, OpsCarrier, PackDeclarations, PatternPack, ReceiverOrigin, UnsettledName, ValueEntry, ValueOps } from '@suss/extractor';
|
|
3
|
+
import { C as Chain, M as MethodMeaning, a as MessageSendMethod, b as MessageLocation, c as ChannelPart, S as SqlMethod, I as InterpolatesLink, d as CallStep, e as StorageMethod, A as ArgumentPick, L as LinkFunction, O as OneArgument } from './chain-58V6lcel.js';
|
|
4
|
+
export { f as AccessKind, g as AccessPathLink, h as ArgumentsFrom, i as ContainerArgument, j as ContainerLink, k as ContainerRule, l as ContainersLink, E as Ending, F as FromReceiver, m as InputLink, n as InputRule, K as KindAsAsked, o as Link, p as ManyIn, q as MatchStart, r as MessageSendEnding, s as MethodsLink, t as OneMessage, u as SqlEnding, v as StartLink, w as StatedInputs, x as StatedRule, y as StorageEnding, z as SubjectLink, T as ToArgument, B as ToReceiver } from './chain-58V6lcel.js';
|
|
5
|
+
import { Effect, MessageBusSemantics } from '@suss/behavioral-ir';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The small builders a pack writes its origins with, and the vocabulary
|
|
9
|
+
* they produce.
|
|
10
|
+
*
|
|
11
|
+
* The types live in `@suss/extractor` because an adapter implements them
|
|
12
|
+
* and never calls any of this. They are re-exported here so a pack
|
|
13
|
+
* author has one import.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A receiver whose method one of these modules declared. Pass every
|
|
18
|
+
* module that ships the same client, the way three packages all speak
|
|
19
|
+
* one wire protocol.
|
|
20
|
+
*/
|
|
21
|
+
declare function declaredBy(...importedFrom: readonly string[]): DeclaredBy;
|
|
22
|
+
/** A client made from one of these modules' exports. */
|
|
23
|
+
declare function constructedFrom(...importedFrom: readonly string[]): ConstructedFrom;
|
|
24
|
+
/** A client made from named exports of those modules. */
|
|
25
|
+
declare function constructedFrom(spec: {
|
|
26
|
+
from: readonly string[];
|
|
27
|
+
named: readonly string[];
|
|
28
|
+
}): ConstructedFrom;
|
|
29
|
+
/** The ops in a recognizer context, or null when the adapter has none. */
|
|
30
|
+
declare function opsIn(ctx: unknown): CallOps | null;
|
|
6
31
|
|
|
7
32
|
/**
|
|
8
33
|
* Turning a chain into the recognizer hook the adapters already call.
|
|
@@ -53,6 +78,57 @@ declare function runExamples(pack: PatternPack, run: RunOverCode): RanExample[];
|
|
|
53
78
|
/** The declarations a pack shipped without a line of code to run. */
|
|
54
79
|
declare function examplesMissing(pack: PatternPack): string[];
|
|
55
80
|
|
|
81
|
+
/**
|
|
82
|
+
* messageSends.ts: a pack that recognizes a call putting a message on a
|
|
83
|
+
* wire.
|
|
84
|
+
*
|
|
85
|
+
* The AWS SDK shape is the one this was written against. An operation
|
|
86
|
+
* is a command class and its arguments are one object, so the pack says
|
|
87
|
+
* which command, where the message is inside it, and which of the
|
|
88
|
+
* message's properties name the channel:
|
|
89
|
+
*
|
|
90
|
+
* client.send(new SendMessageCommand({ QueueUrl, MessageBody }))
|
|
91
|
+
* client.send(new PutEventsCommand({ Entries: [{ EventBusName, DetailType }] }))
|
|
92
|
+
*
|
|
93
|
+
* A library taking one message and a batch of them offers two commands,
|
|
94
|
+
* so a pack writes two declarations. Which of the two a command is
|
|
95
|
+
* belongs to the command rather than to a setting on one declaration.
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
interface MessageSendsSpec {
|
|
99
|
+
/** The wire, in the words the IR's message-bus semantics use. */
|
|
100
|
+
wire: MessageBusSemantics["messageBus"];
|
|
101
|
+
/** Where the messages are: the call's input, or a property holding many. */
|
|
102
|
+
messages: MessageLocation;
|
|
103
|
+
/** The parts of the channel, joined in the order they are written. */
|
|
104
|
+
channel: readonly ChannelPart[];
|
|
105
|
+
/** What joins the parts. Defaults to "#", which is what a bus and a subject use. */
|
|
106
|
+
channelSeparator?: string;
|
|
107
|
+
/** The property a message states its body on. */
|
|
108
|
+
body?: string;
|
|
109
|
+
/**
|
|
110
|
+
* What a reader gives back for a channel nothing in the source
|
|
111
|
+
* settles. Defaults to keeping the reference, since a queue named
|
|
112
|
+
* only at deploy time is the common case rather than the exception.
|
|
113
|
+
*/
|
|
114
|
+
unsettledName?: UnsettledName;
|
|
115
|
+
/** How the pack pins down the client its calls are on. */
|
|
116
|
+
client?: ReceiverOrigin;
|
|
117
|
+
}
|
|
118
|
+
/** A chain over sends, and the links that can still be added. */
|
|
119
|
+
interface MessageSends {
|
|
120
|
+
/** Which methods send, and where each one states the message. */
|
|
121
|
+
methods(table: Readonly<Record<string, MessageSendMethod>>, options?: {
|
|
122
|
+
ignoringCase?: boolean;
|
|
123
|
+
}): MessageSends;
|
|
124
|
+
/** A line of code this matches, which the pack's tests run. */
|
|
125
|
+
example(code: string): MessageSends;
|
|
126
|
+
/** The links and the ending, as data. */
|
|
127
|
+
readonly declared: Chain<MessageSendMethod>;
|
|
128
|
+
}
|
|
129
|
+
/** A pack that recognizes a call sending a message. */
|
|
130
|
+
declare function messageSends(spec: MessageSendsSpec): MessageSends;
|
|
131
|
+
|
|
56
132
|
/**
|
|
57
133
|
* Assembling declared chains into the pack the adapters load.
|
|
58
134
|
*
|
|
@@ -225,4 +301,4 @@ interface StorageCalls {
|
|
|
225
301
|
/** A pack that recognizes calls against a store. */
|
|
226
302
|
declare function storageCalls(spec: StorageCallsSpec): StorageCalls;
|
|
227
303
|
|
|
228
|
-
export { ArgumentPick,
|
|
304
|
+
export { ArgumentPick, CallStep, Chain, ChannelPart, InterpolatesLink, LinkFunction, type Match, MessageLocation, MessageSendMethod, type MessageSends, type MessageSendsSpec, MethodMeaning, OneArgument, type PackSpec, type RanExample, type RunOverCode, SqlMethod, type SqlStatements, type SqlStatementsSpec, type StorageCalls, type StorageCallsSpec, StorageMethod, compile, constructedFrom, declarationsIn, declaredBy, examplesMissing, messageSends, opsIn, pack, runExamples, sqlStatements, storageCalls };
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
// src/compile.ts
|
|
2
|
-
import { storageBinding } from "@suss/behavioral-ir";
|
|
2
|
+
import { messageBusBinding, storageBinding } from "@suss/behavioral-ir";
|
|
3
3
|
import { readSqlAccess, sqlFromParts } from "@suss/sql";
|
|
4
4
|
|
|
5
5
|
// src/ops.ts
|
|
6
6
|
function declaredBy(...importedFrom) {
|
|
7
7
|
return { origin: "declaredBy", importedFrom };
|
|
8
8
|
}
|
|
9
|
-
function constructedFrom(...
|
|
10
|
-
|
|
9
|
+
function constructedFrom(...args) {
|
|
10
|
+
const [first] = args;
|
|
11
|
+
if (typeof first === "object") {
|
|
12
|
+
return {
|
|
13
|
+
origin: "constructed",
|
|
14
|
+
importedFrom: first.from,
|
|
15
|
+
named: first.named
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return { origin: "constructed", importedFrom: args };
|
|
11
19
|
}
|
|
12
20
|
function opsIn(ctx) {
|
|
13
21
|
const carrier = ctx;
|
|
@@ -117,7 +125,8 @@ function startsHere(chain, subject) {
|
|
|
117
125
|
}
|
|
118
126
|
var YIELD = {
|
|
119
127
|
storageAccess,
|
|
120
|
-
sqlAccess
|
|
128
|
+
sqlAccess,
|
|
129
|
+
messageSend
|
|
121
130
|
};
|
|
122
131
|
function storageAccess(matched) {
|
|
123
132
|
const { subject, chain } = matched;
|
|
@@ -212,6 +221,7 @@ function statedValue(subject, pick) {
|
|
|
212
221
|
}
|
|
213
222
|
var NOTHING_STATED = {
|
|
214
223
|
text: () => null,
|
|
224
|
+
name: () => null,
|
|
215
225
|
flag: () => null,
|
|
216
226
|
entries: () => [],
|
|
217
227
|
items: () => [],
|
|
@@ -264,6 +274,57 @@ function nameOf(ops, pick, index, unsettled) {
|
|
|
264
274
|
}
|
|
265
275
|
return null;
|
|
266
276
|
}
|
|
277
|
+
function messageSend(matched) {
|
|
278
|
+
const { ops, subject, chain, recognition } = matched;
|
|
279
|
+
const ending = chain.ending;
|
|
280
|
+
const input = statedValue(
|
|
281
|
+
subject,
|
|
282
|
+
matched.meaning.input
|
|
283
|
+
);
|
|
284
|
+
if (input === null) {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
const messages = messagesIn(input, ending.messages);
|
|
288
|
+
return messages.length === 0 ? null : messages.map((message) => ({
|
|
289
|
+
type: "interaction",
|
|
290
|
+
binding: messageBusBinding({
|
|
291
|
+
recognition,
|
|
292
|
+
messageBus: ending.wire,
|
|
293
|
+
channel: channelOf(message, ending)
|
|
294
|
+
}),
|
|
295
|
+
callee: ops.calleeText(),
|
|
296
|
+
interaction: {
|
|
297
|
+
class: "message-send",
|
|
298
|
+
...bodyOf(message, ending)
|
|
299
|
+
}
|
|
300
|
+
}));
|
|
301
|
+
}
|
|
302
|
+
function messagesIn(input, location) {
|
|
303
|
+
if (location.each === "theInput") {
|
|
304
|
+
return [input];
|
|
305
|
+
}
|
|
306
|
+
const collection = input.property(location.property);
|
|
307
|
+
return collection === null ? [] : collection.items();
|
|
308
|
+
}
|
|
309
|
+
function channelOf(message, ending) {
|
|
310
|
+
const parts = [];
|
|
311
|
+
for (const part of ending.channel) {
|
|
312
|
+
const stated = message.property(part.property)?.name(ending.unsettledName) ?? null;
|
|
313
|
+
const value = stated === null || stated === "" ? part.whenAbsent : stated;
|
|
314
|
+
if (value === void 0) {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
parts.push(value);
|
|
318
|
+
}
|
|
319
|
+
return parts.join(ending.channelSeparator ?? "#");
|
|
320
|
+
}
|
|
321
|
+
function bodyOf(message, ending) {
|
|
322
|
+
if (ending.body === void 0) {
|
|
323
|
+
return {};
|
|
324
|
+
}
|
|
325
|
+
const stated = message.property(ending.body)?.text() ?? null;
|
|
326
|
+
return stated === null ? {} : { body: stated };
|
|
327
|
+
}
|
|
267
328
|
function sqlAccess(matched) {
|
|
268
329
|
const { ops, subject, method, chain, recognition } = matched;
|
|
269
330
|
const ending = chain.ending;
|
|
@@ -327,10 +388,46 @@ function examplesMissing(pack2) {
|
|
|
327
388
|
return (pack2.declarations?.declarations ?? []).filter((declaration) => declaration.example === null).map((declaration) => declaration.name);
|
|
328
389
|
}
|
|
329
390
|
|
|
391
|
+
// src/chain.ts
|
|
392
|
+
function chainStart(client) {
|
|
393
|
+
return client === void 0 ? [] : [{ asks: "start", at: { starts: "receiver", origin: client } }];
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// src/messageSends.ts
|
|
397
|
+
function messageSends(spec) {
|
|
398
|
+
const ending = {
|
|
399
|
+
yields: "messageSend",
|
|
400
|
+
wire: spec.wire,
|
|
401
|
+
messages: spec.messages,
|
|
402
|
+
channel: spec.channel,
|
|
403
|
+
...spec.channelSeparator === void 0 ? {} : { channelSeparator: spec.channelSeparator },
|
|
404
|
+
...spec.body === void 0 ? {} : { body: spec.body },
|
|
405
|
+
unsettledName: spec.unsettledName ?? "reference"
|
|
406
|
+
};
|
|
407
|
+
return chainFrom({
|
|
408
|
+
links: chainStart(spec.client),
|
|
409
|
+
ending,
|
|
410
|
+
example: null
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
function chainFrom(declared) {
|
|
414
|
+
const adding = (link) => chainFrom({ ...declared, links: [...declared.links, link] });
|
|
415
|
+
return {
|
|
416
|
+
declared,
|
|
417
|
+
methods: (table, options) => adding({
|
|
418
|
+
asks: "methods",
|
|
419
|
+
table,
|
|
420
|
+
ignoringCase: options?.ignoringCase ?? false
|
|
421
|
+
}),
|
|
422
|
+
example: (code) => chainFrom({ ...declared, example: code })
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
|
|
330
426
|
// src/pack.ts
|
|
331
427
|
var DISPATCHED_ON = {
|
|
332
428
|
storageAccess: "invocation",
|
|
333
|
-
sqlAccess: "access"
|
|
429
|
+
sqlAccess: "access",
|
|
430
|
+
messageSend: "invocation"
|
|
334
431
|
};
|
|
335
432
|
function walkedBy(chains, walk2, recognizedAs) {
|
|
336
433
|
return chains.filter((chain) => DISPATCHED_ON[chain.ending.yields] === walk2).map((chain) => compile(chain, recognizedAs));
|
|
@@ -357,10 +454,17 @@ function pack(name, matches, spec) {
|
|
|
357
454
|
function declarationsIn(matches) {
|
|
358
455
|
return { declarations: matches.map((match) => describe(match.declared)) };
|
|
359
456
|
}
|
|
457
|
+
function wireOf(ending) {
|
|
458
|
+
if (ending.yields === "messageSend") {
|
|
459
|
+
return ending.wire;
|
|
460
|
+
}
|
|
461
|
+
return ending.transport ?? ending.system;
|
|
462
|
+
}
|
|
463
|
+
function declaredName(ending) {
|
|
464
|
+
return ending.yields === "messageSend" ? ending.wire : ending.system;
|
|
465
|
+
}
|
|
360
466
|
function protocolOf(chains) {
|
|
361
|
-
const wires = new Set(
|
|
362
|
-
chains.map((chain) => chain.ending.transport ?? chain.ending.system)
|
|
363
|
-
);
|
|
467
|
+
const wires = new Set(chains.map((chain) => wireOf(chain.ending)));
|
|
364
468
|
const [only] = [...wires];
|
|
365
469
|
if (wires.size !== 1 || only === void 0) {
|
|
366
470
|
throw new Error(
|
|
@@ -410,7 +514,7 @@ function describe(chain) {
|
|
|
410
514
|
...rulesIn(chain)
|
|
411
515
|
];
|
|
412
516
|
return {
|
|
413
|
-
name: chain.ending
|
|
517
|
+
name: declaredName(chain.ending),
|
|
414
518
|
// A method table with a rule inside it is still a table, so that
|
|
415
519
|
// link stays counted as data and the rule is priced beside it.
|
|
416
520
|
dataLinks: chain.links.length - links.length,
|
|
@@ -461,14 +565,14 @@ function sqlStatements(spec) {
|
|
|
461
565
|
dialect: spec.dialect
|
|
462
566
|
};
|
|
463
567
|
const client = spec.client;
|
|
464
|
-
return
|
|
465
|
-
links: client
|
|
568
|
+
return chainFrom2({
|
|
569
|
+
links: chainStart(client),
|
|
466
570
|
ending,
|
|
467
571
|
example: null
|
|
468
572
|
});
|
|
469
573
|
}
|
|
470
|
-
function
|
|
471
|
-
const adding = (link) =>
|
|
574
|
+
function chainFrom2(declared) {
|
|
575
|
+
const adding = (link) => chainFrom2({ ...declared, links: [...declared.links, link] });
|
|
472
576
|
return {
|
|
473
577
|
declared,
|
|
474
578
|
methods: (table, options) => adding({
|
|
@@ -477,7 +581,7 @@ function chainFrom(declared) {
|
|
|
477
581
|
ignoringCase: options?.ignoringCase ?? false
|
|
478
582
|
}),
|
|
479
583
|
interpolating: (says) => adding({ asks: "interpolates", ...says }),
|
|
480
|
-
example: (code) =>
|
|
584
|
+
example: (code) => chainFrom2({ ...declared, example: code })
|
|
481
585
|
};
|
|
482
586
|
}
|
|
483
587
|
|
|
@@ -491,14 +595,14 @@ function storageCalls(spec) {
|
|
|
491
595
|
unsettledName: spec.unsettledName ?? "reference"
|
|
492
596
|
};
|
|
493
597
|
const client = spec.client;
|
|
494
|
-
return
|
|
495
|
-
links: client
|
|
598
|
+
return chainFrom3({
|
|
599
|
+
links: chainStart(client),
|
|
496
600
|
ending,
|
|
497
601
|
example: null
|
|
498
602
|
});
|
|
499
603
|
}
|
|
500
|
-
function
|
|
501
|
-
const adding = (link) =>
|
|
604
|
+
function chainFrom3(declared) {
|
|
605
|
+
const adding = (link) => chainFrom3({ ...declared, links: [...declared.links, link] });
|
|
502
606
|
return {
|
|
503
607
|
declared,
|
|
504
608
|
about: (...of) => adding({ asks: "subject", of }),
|
|
@@ -513,7 +617,7 @@ function chainFrom2(declared) {
|
|
|
513
617
|
accessPath: (says) => adding({ asks: "accessPath", argument: says }),
|
|
514
618
|
containersIn: (says) => adding({ asks: "containers", in: says }),
|
|
515
619
|
input: (says) => adding({ asks: "input", at: says }),
|
|
516
|
-
example: (code) =>
|
|
620
|
+
example: (code) => chainFrom3({ ...declared, example: code })
|
|
517
621
|
};
|
|
518
622
|
}
|
|
519
623
|
export {
|
|
@@ -522,6 +626,7 @@ export {
|
|
|
522
626
|
declarationsIn,
|
|
523
627
|
declaredBy,
|
|
524
628
|
examplesMissing,
|
|
629
|
+
messageSends,
|
|
525
630
|
opsIn,
|
|
526
631
|
pack,
|
|
527
632
|
runExamples,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/recognize",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Write a pack as data: a chain of named links that any language adapter with the executor ops can run.",
|
|
6
6
|
"keywords": [
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
"typecheck": "tsc --noEmit"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@suss/behavioral-ir": "0.13.
|
|
53
|
-
"@suss/extractor": "0.13.
|
|
54
|
-
"@suss/sql": "0.13.
|
|
52
|
+
"@suss/behavioral-ir": "0.13.2",
|
|
53
|
+
"@suss/extractor": "0.13.2",
|
|
54
|
+
"@suss/sql": "0.13.2"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"tsup": "*",
|