@suss/packs 0.18.0 → 0.19.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.
@@ -31,3 +31,4 @@ import '@suss/framework-react';
31
31
  import '@suss/framework-redis';
32
32
  import '@suss/framework-sqlalchemy';
33
33
  import '@suss/framework-ts-rest';
34
+ import '@suss/framework-zustand';
package/dist/react.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import "./chunk-3RG5ZIWI.js";
2
2
 
3
3
  // ../framework/react/dist/index.js
4
+ import { Node } from "ts-morph";
4
5
  var STORY_FILE_PATTERN = /\.stories\.tsx?$/;
5
6
  var TEST_FILE_PATTERN = /\.(test|spec)\.tsx?$/;
6
7
  function startsWithUppercase(name) {
@@ -36,6 +37,117 @@ var reactComponentExports = (sourceFile, ctx) => {
36
37
  }
37
38
  return out;
38
39
  };
40
+ var BOOT_CALLEES = ["createRoot", "hydrateRoot"];
41
+ var BOOT_MODULES = ["react-dom/client", "react-dom"];
42
+ function importedBootNames(sourceFile) {
43
+ const names = /* @__PURE__ */ new Set();
44
+ for (const decl of sourceFile.getImportDeclarations()) {
45
+ if (!BOOT_MODULES.includes(decl.getModuleSpecifierValue())) {
46
+ continue;
47
+ }
48
+ for (const named of decl.getNamedImports()) {
49
+ if (BOOT_CALLEES.includes(named.getName())) {
50
+ names.add(named.getAliasNode()?.getText() ?? named.getName());
51
+ }
52
+ }
53
+ }
54
+ return names;
55
+ }
56
+ function importedDomNamespaces(sourceFile) {
57
+ const names = /* @__PURE__ */ new Set();
58
+ for (const decl of sourceFile.getImportDeclarations()) {
59
+ if (!BOOT_MODULES.includes(decl.getModuleSpecifierValue())) {
60
+ continue;
61
+ }
62
+ const namespace = decl.getNamespaceImport()?.getText();
63
+ if (namespace !== void 0) {
64
+ names.add(namespace);
65
+ }
66
+ const defaultImport = decl.getDefaultImport()?.getText();
67
+ if (defaultImport !== void 0) {
68
+ names.add(defaultImport);
69
+ }
70
+ }
71
+ return names;
72
+ }
73
+ function isBootRender(call, bootNames, domNamespaces) {
74
+ const callee = call.getExpression();
75
+ if (!Node.isPropertyAccessExpression(callee)) {
76
+ return false;
77
+ }
78
+ if (callee.getName() !== "render") {
79
+ return false;
80
+ }
81
+ const base = callee.getExpression();
82
+ if (Node.isCallExpression(base)) {
83
+ const inner = base.getExpression();
84
+ return Node.isIdentifier(inner) && bootNames.has(inner.getText());
85
+ }
86
+ return Node.isIdentifier(base) && domNamespaces.has(base.getText());
87
+ }
88
+ function renderedComponentOf(call) {
89
+ const argument = call.getArguments()[0];
90
+ if (argument === void 0) {
91
+ return null;
92
+ }
93
+ let tag = null;
94
+ if (Node.isJsxSelfClosingElement(argument)) {
95
+ const node = argument.getTagNameNode();
96
+ tag = Node.isIdentifier(node) ? node : null;
97
+ } else if (Node.isJsxElement(argument)) {
98
+ const node = argument.getOpeningElement().getTagNameNode();
99
+ tag = Node.isIdentifier(node) ? node : null;
100
+ }
101
+ if (tag === null || !/^[A-Z]/.test(tag.getText())) {
102
+ return null;
103
+ }
104
+ const symbol = tag.getSymbol();
105
+ const aliased = symbol?.getAliasedSymbol();
106
+ for (const decl of (aliased ?? symbol)?.getDeclarations() ?? []) {
107
+ if (Node.isFunctionDeclaration(decl) && decl.getBody() !== void 0) {
108
+ return { func: decl, name: decl.getName() ?? tag.getText() };
109
+ }
110
+ if (Node.isVariableDeclaration(decl)) {
111
+ const init = decl.getInitializer();
112
+ if (init !== void 0 && (Node.isArrowFunction(init) || Node.isFunctionExpression(init))) {
113
+ return { func: init, name: decl.getName() };
114
+ }
115
+ }
116
+ }
117
+ return null;
118
+ }
119
+ var reactRootComponents = (sourceFile, _ctx) => {
120
+ const sf = sourceFile;
121
+ const text = sf.getFullText();
122
+ if (!text.includes("render")) {
123
+ return [];
124
+ }
125
+ const bootNames = importedBootNames(sf);
126
+ const domNamespaces = importedDomNamespaces(sf);
127
+ if (bootNames.size === 0 && domNamespaces.size === 0) {
128
+ return [];
129
+ }
130
+ const out = [];
131
+ const claimed = /* @__PURE__ */ new Set();
132
+ sf.forEachDescendant((node) => {
133
+ if (!Node.isCallExpression(node)) {
134
+ return;
135
+ }
136
+ if (!isBootRender(node, bootNames, domNamespaces)) {
137
+ return;
138
+ }
139
+ const component = renderedComponentOf(node);
140
+ if (component !== null && !claimed.has(component.func)) {
141
+ claimed.add(component.func);
142
+ out.push({
143
+ func: component.func,
144
+ kind: "component",
145
+ name: component.name
146
+ });
147
+ }
148
+ });
149
+ return out;
150
+ };
39
151
  var EVENT_HANDLER_INPUT = {
40
152
  type: "positionalParams",
41
153
  params: [{ position: 0, role: "event" }]
@@ -214,7 +326,10 @@ function reactFramework() {
214
326
  paramPosition: 0
215
327
  },
216
328
  subUnits: reactSubUnits,
217
- discoverUnits: reactComponentExports
329
+ discoverUnits: (sourceFile, ctx) => [
330
+ ...reactComponentExports(sourceFile, ctx),
331
+ ...reactRootComponents(sourceFile, ctx)
332
+ ]
218
333
  };
219
334
  }
220
335
  var index_default = reactFramework;
@@ -0,0 +1 @@
1
+ export { default } from '@suss/framework-zustand';
@@ -0,0 +1,38 @@
1
+ import "./chunk-3RG5ZIWI.js";
2
+
3
+ // ../framework/zustand/dist/index.js
4
+ import { constructedFrom, pack, storageCalls } from "@suss/recognize";
5
+ var WRITTEN = ({ input }) => {
6
+ const found = [];
7
+ for (const entry of input.entries("nothing")) {
8
+ if (entry.key !== null) {
9
+ found.push(entry.key);
10
+ }
11
+ }
12
+ return found;
13
+ };
14
+ var payload = (at) => ({ of: { at }, by: WRITTEN });
15
+ var METHODS = {
16
+ setState: { kind: "write", fields: payload(0) },
17
+ getState: { kind: "read" },
18
+ subscribe: { kind: "read" }
19
+ };
20
+ function storeNameOf(_names, call) {
21
+ const callee = call.calleeText();
22
+ const dot = callee.lastIndexOf(".");
23
+ return dot > 0 ? callee.slice(0, dot) : null;
24
+ }
25
+ var STORE_CALLS = storageCalls({
26
+ system: "client-store",
27
+ client: constructedFrom("zustand", "zustand/vanilla")
28
+ }).methods(METHODS).container(storeNameOf).example("useAppStore.setState({ bears: 5 })");
29
+ function zustandFramework() {
30
+ return pack("zustand", [STORE_CALLS], {
31
+ languages: ["typescript", "javascript"],
32
+ recognizedAs: "@suss/framework-zustand"
33
+ });
34
+ }
35
+ var index_default = zustandFramework;
36
+ export {
37
+ index_default as default
38
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suss/packs",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "type": "module",
5
5
  "description": "Every pack suss ships, as one package with a subpath per pack.",
6
6
  "keywords": [
@@ -144,6 +144,10 @@
144
144
  "types": "./dist/redis.d.ts",
145
145
  "import": "./dist/redis.js"
146
146
  },
147
+ "./zustand": {
148
+ "types": "./dist/zustand.d.ts",
149
+ "import": "./dist/zustand.js"
150
+ },
147
151
  "./sqlalchemy": {
148
152
  "types": "./dist/sqlalchemy.d.ts",
149
153
  "import": "./dist/sqlalchemy.js"
@@ -169,15 +173,15 @@
169
173
  "ts-morph": "^23.0.0"
170
174
  },
171
175
  "dependencies": {
172
- "@suss/adapter-python": "0.18.0",
173
- "@suss/adapter-ruby": "0.18.0",
174
- "@suss/adapter-typescript": "0.18.0",
175
- "@suss/behavioral-ir": "0.18.0",
176
- "@suss/contract-graphql": "0.18.0",
177
- "@suss/extractor": "0.18.0",
178
- "@suss/manifest-aws": "0.18.0",
179
- "@suss/recognize": "0.18.0",
180
- "@suss/sql": "0.18.0"
176
+ "@suss/adapter-python": "0.19.0",
177
+ "@suss/adapter-ruby": "0.19.0",
178
+ "@suss/adapter-typescript": "0.19.0",
179
+ "@suss/behavioral-ir": "0.19.0",
180
+ "@suss/contract-graphql": "0.19.0",
181
+ "@suss/extractor": "0.19.0",
182
+ "@suss/manifest-aws": "0.19.0",
183
+ "@suss/recognize": "0.19.0",
184
+ "@suss/sql": "0.19.0"
181
185
  },
182
186
  "devDependencies": {
183
187
  "@suss/client-apollo": "*",
@@ -208,6 +212,7 @@
208
212
  "@suss/framework-prisma": "*",
209
213
  "@suss/framework-react": "*",
210
214
  "@suss/framework-react-query": "*",
215
+ "@suss/framework-zustand": "*",
211
216
  "@suss/framework-react-router": "*",
212
217
  "@suss/framework-redis": "*",
213
218
  "@suss/framework-sqlalchemy": "*",