@suss/recognize 0.18.0 → 0.20.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/README.md CHANGED
@@ -76,6 +76,15 @@ ioredis, and the declaration behind `redis.get` says everything.
76
76
  `constructed` asks the receiver itself, so it still works where the
77
77
  method is untyped.
78
78
 
79
+ A chain can also match a bare call of the tracked value itself, with
80
+ `.calls(meaning)` beside its methods table. A store hook is the case:
81
+ `useAppStore((s) => s.bears)` reaches for no method, so there is no
82
+ name for the table to list; the call matches when its callee is a
83
+ bound name whose written value came from the chain's origin. The
84
+ fields such a call reads are usually stated in a selector lambda, and
85
+ `fields: { selectorParam: 0 }` picks them off the lambda's parameter,
86
+ one per distinct first segment.
87
+
79
88
  ## The gradient
80
89
 
81
90
  Expressiveness is bought link by link, and the price is printed.
@@ -111,6 +120,8 @@ result on the recognizer context under `ops`.
111
120
  | `receiver()` | the call the receiver is, as ops of its own |
112
121
  | `argument(index)` | the call that argument is, as ops of its own |
113
122
  | `callee()` | the call the callee itself was written as |
123
+ | `namedCallee()` | whether the call goes to a name the program bound (optional) |
124
+ | `parameterReadsAt(index)` | the fields a selector lambda in that position reads off its parameter (optional) |
114
125
  | `propertyAt(index, property, unsettled)` | what a named property of that argument says |
115
126
  | `valueAt(index)` | the value that argument states, as `ValueOps` |
116
127
 
package/dist/ast.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CallOps } from '@suss/extractor';
2
- import { L as LinkFunction } from './chain-C7w99UMv.cjs';
2
+ import { L as LinkFunction } from './chain-_S93eC3O.cjs';
3
3
  import '@suss/behavioral-ir';
4
4
 
5
5
  /**
package/dist/ast.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CallOps } from '@suss/extractor';
2
- import { L as LinkFunction } from './chain-C7w99UMv.js';
2
+ import { L as LinkFunction } from './chain-_S93eC3O.js';
3
3
  import '@suss/behavioral-ir';
4
4
 
5
5
  /**
@@ -165,12 +165,30 @@ interface InterpolatesLink {
165
165
  readonly from?: ReceiverOrigin;
166
166
  }
167
167
  /** One question in a chain, and the answer the pack gave for it. */
168
- type Link<TMeaning> = StartLink | SubjectLink | MethodsLink<TMeaning> | ContainerLink | AccessPathLink | ContainersLink | InputLink | InterpolatesLink;
168
+ type Link<TMeaning> = StartLink | SubjectLink | MethodsLink<TMeaning> | CallsLink<TMeaning> | ContainerLink | AccessPathLink | ContainersLink | InputLink | InterpolatesLink;
169
+ /**
170
+ * The meaning of a bare call of the tracked client itself. A store
171
+ * hook is the case: `useAppStore((s) => s.bears)` reaches for no
172
+ * method, so there is no name for a methods table to list; the call
173
+ * matches by what its callee was written as.
174
+ */
175
+ interface CallsLink<TMeaning> {
176
+ readonly asks: "calls";
177
+ readonly meaning: TMeaning;
178
+ }
169
179
  /**
170
180
  * Which argument or arguments say what a call reached, and where to go
171
181
  * looking. Without `of` the argument belongs to the chain's subject.
172
182
  */
173
183
  type ArgumentPick = OneArgument | ArgumentsFrom;
184
+ /**
185
+ * The fields a selector lambda reads off its parameter, one per
186
+ * distinct first segment: `(s) => s.bears.count` reads `bears`. The
187
+ * value says which argument the lambda is passed as.
188
+ */
189
+ interface SelectorParamPick {
190
+ readonly selectorParam: number;
191
+ }
174
192
  /** The argument in one position. */
175
193
  interface OneArgument {
176
194
  /** The steps to the call the argument belongs to. */
@@ -261,13 +279,13 @@ interface StorageMethod {
261
279
  * wrote, or the plain list a method whose own name settles it states
262
280
  * outright: `findById` picks by `_id` however the id is spelt.
263
281
  */
264
- readonly selector?: readonly string[] | ArgumentPick | InputRule | StatedRule;
282
+ readonly selector?: readonly string[] | ArgumentPick | SelectorParamPick | InputRule | StatedRule;
265
283
  /**
266
284
  * Which fields the call touched, said the same three ways. A delete
267
285
  * touches the whole document and states `["*"]`, since nothing in its
268
286
  * arguments says so.
269
287
  */
270
- readonly fields?: readonly string[] | ArgumentPick | InputRule | StatedRule;
288
+ readonly fields?: readonly string[] | ArgumentPick | SelectorParamPick | InputRule | StatedRule;
271
289
  }
272
290
  /**
273
291
  * What one method of a client that takes a statement written as SQL
@@ -418,4 +436,4 @@ interface Chain<TMeaning = MethodMeaning> {
418
436
  readonly example: string | null;
419
437
  }
420
438
 
421
- 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 };
439
+ export type { ArgumentPick as A, StorageEnding as B, Chain as C, SubjectLink as D, Ending as E, FromReceiver as F, ToReceiver as G, 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, CallsLink as i, ContainerArgument as j, ContainerLink as k, ContainerRule as l, ContainersLink as m, InputLink as n, InputRule as o, Link as p, ManyIn as q, MatchStart as r, MessageSendEnding as s, MethodsLink as t, OneMessage as u, SelectorParamPick as v, SqlEnding as w, StartLink as x, StatedInputs as y, StatedRule as z };
@@ -165,12 +165,30 @@ interface InterpolatesLink {
165
165
  readonly from?: ReceiverOrigin;
166
166
  }
167
167
  /** One question in a chain, and the answer the pack gave for it. */
168
- type Link<TMeaning> = StartLink | SubjectLink | MethodsLink<TMeaning> | ContainerLink | AccessPathLink | ContainersLink | InputLink | InterpolatesLink;
168
+ type Link<TMeaning> = StartLink | SubjectLink | MethodsLink<TMeaning> | CallsLink<TMeaning> | ContainerLink | AccessPathLink | ContainersLink | InputLink | InterpolatesLink;
169
+ /**
170
+ * The meaning of a bare call of the tracked client itself. A store
171
+ * hook is the case: `useAppStore((s) => s.bears)` reaches for no
172
+ * method, so there is no name for a methods table to list; the call
173
+ * matches by what its callee was written as.
174
+ */
175
+ interface CallsLink<TMeaning> {
176
+ readonly asks: "calls";
177
+ readonly meaning: TMeaning;
178
+ }
169
179
  /**
170
180
  * Which argument or arguments say what a call reached, and where to go
171
181
  * looking. Without `of` the argument belongs to the chain's subject.
172
182
  */
173
183
  type ArgumentPick = OneArgument | ArgumentsFrom;
184
+ /**
185
+ * The fields a selector lambda reads off its parameter, one per
186
+ * distinct first segment: `(s) => s.bears.count` reads `bears`. The
187
+ * value says which argument the lambda is passed as.
188
+ */
189
+ interface SelectorParamPick {
190
+ readonly selectorParam: number;
191
+ }
174
192
  /** The argument in one position. */
175
193
  interface OneArgument {
176
194
  /** The steps to the call the argument belongs to. */
@@ -261,13 +279,13 @@ interface StorageMethod {
261
279
  * wrote, or the plain list a method whose own name settles it states
262
280
  * outright: `findById` picks by `_id` however the id is spelt.
263
281
  */
264
- readonly selector?: readonly string[] | ArgumentPick | InputRule | StatedRule;
282
+ readonly selector?: readonly string[] | ArgumentPick | SelectorParamPick | InputRule | StatedRule;
265
283
  /**
266
284
  * Which fields the call touched, said the same three ways. A delete
267
285
  * touches the whole document and states `["*"]`, since nothing in its
268
286
  * arguments says so.
269
287
  */
270
- readonly fields?: readonly string[] | ArgumentPick | InputRule | StatedRule;
288
+ readonly fields?: readonly string[] | ArgumentPick | SelectorParamPick | InputRule | StatedRule;
271
289
  }
272
290
  /**
273
291
  * What one method of a client that takes a statement written as SQL
@@ -418,4 +436,4 @@ interface Chain<TMeaning = MethodMeaning> {
418
436
  readonly example: string | null;
419
437
  }
420
438
 
421
- 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 };
439
+ export type { ArgumentPick as A, StorageEnding as B, Chain as C, SubjectLink as D, Ending as E, FromReceiver as F, ToReceiver as G, 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, CallsLink as i, ContainerArgument as j, ContainerLink as k, ContainerRule as l, ContainersLink as m, InputLink as n, InputRule as o, Link as p, ManyIn as q, MatchStart as r, MessageSendEnding as s, MethodsLink as t, OneMessage as u, SelectorParamPick as v, SqlEnding as w, StartLink as x, StatedInputs as y, StatedRule as z };
package/dist/index.cjs CHANGED
@@ -64,8 +64,22 @@ var MAX_RECEIVER_HOPS = 8;
64
64
  function compile(chain, recognition) {
65
65
  return (_call, ctx) => {
66
66
  const ops = opsIn(ctx);
67
+ if (ops === null) {
68
+ return null;
69
+ }
70
+ const bare = bareCall(chain, ops);
71
+ if (bare !== null) {
72
+ return YIELD[chain.ending.yields]({
73
+ ops,
74
+ subject: ops,
75
+ method: bare.method,
76
+ meaning: bare.meaning,
77
+ chain,
78
+ recognition
79
+ });
80
+ }
67
81
  const methods = methodsIn(chain);
68
- if (ops === null || methods === null) {
82
+ if (methods === null) {
69
83
  return null;
70
84
  }
71
85
  for (const subject of subjectsOf(chain, ops)) {
@@ -90,6 +104,21 @@ function linkIn(chain, asks) {
90
104
  const link = chain.links.find((candidate) => candidate.asks === asks);
91
105
  return link ?? null;
92
106
  }
107
+ function bareCall(chain, ops) {
108
+ const link = linkIn(chain, "calls");
109
+ const start = linkIn(chain, "start");
110
+ if (link === null || start === null || start.at.starts !== "receiver") {
111
+ return null;
112
+ }
113
+ if (ops.method() !== null || ops.namedCallee?.() !== true) {
114
+ return null;
115
+ }
116
+ const written = ops.callee();
117
+ if (written === null || !written.isFrom(start.at.origin)) {
118
+ return null;
119
+ }
120
+ return { method: ops.calleeText(), meaning: link.meaning };
121
+ }
93
122
  function methodsIn(chain) {
94
123
  return linkIn(chain, "methods");
95
124
  }
@@ -278,6 +307,9 @@ function namesFor(says, subject, stated, unsettled) {
278
307
  const input2 = stated.input;
279
308
  return input2 === null ? [] : [...says({ ...stated, input: input2 })];
280
309
  }
310
+ if ("selectorParam" in says) {
311
+ return [...subject.parameterReadsAt?.(says.selectorParam) ?? []];
312
+ }
281
313
  const pointed = says;
282
314
  if (!("by" in pointed)) {
283
315
  return namesAt(subject, pointed, unsettled);
@@ -591,8 +623,15 @@ function rulesIn(chain) {
591
623
  const link = chain.links.find(
592
624
  (candidate) => candidate.asks === "methods"
593
625
  );
626
+ const calls = chain.links.find(
627
+ (candidate) => candidate.asks === "calls"
628
+ );
629
+ const meanings = [
630
+ ...Object.values(link?.table ?? {}),
631
+ ...calls === void 0 ? [] : [calls.meaning]
632
+ ];
594
633
  const written = /* @__PURE__ */ new Map();
595
- for (const method of Object.values(link?.table ?? {})) {
634
+ for (const method of meanings) {
596
635
  for (const asks of ["selector", "fields"]) {
597
636
  const rule = ruleFor(method[asks]);
598
637
  if (rule !== null) {
@@ -672,6 +711,7 @@ function chainFrom3(declared) {
672
711
  table,
673
712
  ignoringCase: options?.ignoringCase ?? false
674
713
  }),
714
+ calls: (meaning) => adding({ asks: "calls", meaning }),
675
715
  container: (says) => adding(
676
716
  typeof says === "function" ? { asks: "container", from: says } : { asks: "container", argument: says }
677
717
  ),
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ConstructedFrom, DeclaredBy, CallOps, InvocationRecognizer, PatternPack, UnsettledName, ReceiverOrigin, PackDeclarations } from '@suss/extractor';
2
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-C7w99UMv.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-C7w99UMv.cjs';
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-_S93eC3O.cjs';
4
+ export { f as AccessKind, g as AccessPathLink, h as ArgumentsFrom, i as CallsLink, j as ContainerArgument, k as ContainerLink, l as ContainerRule, m as ContainersLink, E as Ending, F as FromReceiver, n as InputLink, o as InputRule, K as KindAsAsked, p as Link, q as ManyIn, r as MatchStart, s as MessageSendEnding, t as MethodsLink, u as OneMessage, v as SelectorParamPick, w as SqlEnding, x as StartLink, y as StatedInputs, z as StatedRule, B as StorageEnding, D as SubjectLink, T as ToArgument, G as ToReceiver } from './chain-_S93eC3O.cjs';
5
5
  import { Effect, MessageBusSemantics } from '@suss/behavioral-ir';
6
6
 
7
7
  /**
@@ -287,6 +287,12 @@ interface StorageCalls {
287
287
  methods(table: Readonly<Record<string, StorageMethod>>, options?: {
288
288
  ignoringCase?: boolean;
289
289
  }): StorageCalls;
290
+ /**
291
+ * What a bare call of the client itself does. A store hook is the
292
+ * case: `useAppStore((s) => s.bears)` reaches for no method, so the
293
+ * one meaning here is the whole answer.
294
+ */
295
+ calls(meaning: StorageMethod): StorageCalls;
290
296
  /**
291
297
  * Which container a call's selector belongs to, as an argument or as
292
298
  * the pack's own rule. Without this the first name a call reached is
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ConstructedFrom, DeclaredBy, CallOps, InvocationRecognizer, PatternPack, UnsettledName, ReceiverOrigin, PackDeclarations } from '@suss/extractor';
2
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-C7w99UMv.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-C7w99UMv.js';
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-_S93eC3O.js';
4
+ export { f as AccessKind, g as AccessPathLink, h as ArgumentsFrom, i as CallsLink, j as ContainerArgument, k as ContainerLink, l as ContainerRule, m as ContainersLink, E as Ending, F as FromReceiver, n as InputLink, o as InputRule, K as KindAsAsked, p as Link, q as ManyIn, r as MatchStart, s as MessageSendEnding, t as MethodsLink, u as OneMessage, v as SelectorParamPick, w as SqlEnding, x as StartLink, y as StatedInputs, z as StatedRule, B as StorageEnding, D as SubjectLink, T as ToArgument, G as ToReceiver } from './chain-_S93eC3O.js';
5
5
  import { Effect, MessageBusSemantics } from '@suss/behavioral-ir';
6
6
 
7
7
  /**
@@ -287,6 +287,12 @@ interface StorageCalls {
287
287
  methods(table: Readonly<Record<string, StorageMethod>>, options?: {
288
288
  ignoringCase?: boolean;
289
289
  }): StorageCalls;
290
+ /**
291
+ * What a bare call of the client itself does. A store hook is the
292
+ * case: `useAppStore((s) => s.bears)` reaches for no method, so the
293
+ * one meaning here is the whole answer.
294
+ */
295
+ calls(meaning: StorageMethod): StorageCalls;
290
296
  /**
291
297
  * Which container a call's selector belongs to, as an argument or as
292
298
  * the pack's own rule. Without this the first name a call reached is
package/dist/index.js CHANGED
@@ -28,8 +28,22 @@ var MAX_RECEIVER_HOPS = 8;
28
28
  function compile(chain, recognition) {
29
29
  return (_call, ctx) => {
30
30
  const ops = opsIn(ctx);
31
+ if (ops === null) {
32
+ return null;
33
+ }
34
+ const bare = bareCall(chain, ops);
35
+ if (bare !== null) {
36
+ return YIELD[chain.ending.yields]({
37
+ ops,
38
+ subject: ops,
39
+ method: bare.method,
40
+ meaning: bare.meaning,
41
+ chain,
42
+ recognition
43
+ });
44
+ }
31
45
  const methods = methodsIn(chain);
32
- if (ops === null || methods === null) {
46
+ if (methods === null) {
33
47
  return null;
34
48
  }
35
49
  for (const subject of subjectsOf(chain, ops)) {
@@ -54,6 +68,21 @@ function linkIn(chain, asks) {
54
68
  const link = chain.links.find((candidate) => candidate.asks === asks);
55
69
  return link ?? null;
56
70
  }
71
+ function bareCall(chain, ops) {
72
+ const link = linkIn(chain, "calls");
73
+ const start = linkIn(chain, "start");
74
+ if (link === null || start === null || start.at.starts !== "receiver") {
75
+ return null;
76
+ }
77
+ if (ops.method() !== null || ops.namedCallee?.() !== true) {
78
+ return null;
79
+ }
80
+ const written = ops.callee();
81
+ if (written === null || !written.isFrom(start.at.origin)) {
82
+ return null;
83
+ }
84
+ return { method: ops.calleeText(), meaning: link.meaning };
85
+ }
57
86
  function methodsIn(chain) {
58
87
  return linkIn(chain, "methods");
59
88
  }
@@ -242,6 +271,9 @@ function namesFor(says, subject, stated, unsettled) {
242
271
  const input2 = stated.input;
243
272
  return input2 === null ? [] : [...says({ ...stated, input: input2 })];
244
273
  }
274
+ if ("selectorParam" in says) {
275
+ return [...subject.parameterReadsAt?.(says.selectorParam) ?? []];
276
+ }
245
277
  const pointed = says;
246
278
  if (!("by" in pointed)) {
247
279
  return namesAt(subject, pointed, unsettled);
@@ -555,8 +587,15 @@ function rulesIn(chain) {
555
587
  const link = chain.links.find(
556
588
  (candidate) => candidate.asks === "methods"
557
589
  );
590
+ const calls = chain.links.find(
591
+ (candidate) => candidate.asks === "calls"
592
+ );
593
+ const meanings = [
594
+ ...Object.values(link?.table ?? {}),
595
+ ...calls === void 0 ? [] : [calls.meaning]
596
+ ];
558
597
  const written = /* @__PURE__ */ new Map();
559
- for (const method of Object.values(link?.table ?? {})) {
598
+ for (const method of meanings) {
560
599
  for (const asks of ["selector", "fields"]) {
561
600
  const rule = ruleFor(method[asks]);
562
601
  if (rule !== null) {
@@ -636,6 +675,7 @@ function chainFrom3(declared) {
636
675
  table,
637
676
  ignoringCase: options?.ignoringCase ?? false
638
677
  }),
678
+ calls: (meaning) => adding({ asks: "calls", meaning }),
639
679
  container: (says) => adding(
640
680
  typeof says === "function" ? { asks: "container", from: says } : { asks: "container", argument: says }
641
681
  ),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suss/recognize",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
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.18.0",
53
- "@suss/extractor": "0.18.0",
54
- "@suss/sql": "0.18.0"
52
+ "@suss/behavioral-ir": "0.20.0",
53
+ "@suss/extractor": "0.20.0",
54
+ "@suss/sql": "0.20.0"
55
55
  },
56
56
  "devDependencies": {
57
57
  "tsup": "*",