@squiggle.sh/babel-plugin 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +53 -4
- package/dist/index.js +2 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -12,9 +12,30 @@ type BabelTypes = {
|
|
|
12
12
|
variableDeclaration(kind: string, declarations: unknown[]): unknown;
|
|
13
13
|
variableDeclarator(id: unknown, init: unknown): unknown;
|
|
14
14
|
callExpression(callee: unknown, args: unknown[]): unknown;
|
|
15
|
+
jsxExpressionContainer(expr: unknown): unknown;
|
|
16
|
+
arrayExpression(elements: unknown[]): unknown;
|
|
17
|
+
};
|
|
18
|
+
type BabelTemplate = {
|
|
19
|
+
statements: {
|
|
20
|
+
ast(code: string): unknown[];
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
type PluginApi = {
|
|
24
|
+
types: BabelTypes;
|
|
25
|
+
template?: BabelTemplate;
|
|
26
|
+
caller?<T>(cb: (caller: {
|
|
27
|
+
isDev?: boolean;
|
|
28
|
+
} | undefined) => T): T;
|
|
15
29
|
};
|
|
16
30
|
type BabelNode = {
|
|
17
31
|
type: string;
|
|
32
|
+
name?: unknown;
|
|
33
|
+
property?: {
|
|
34
|
+
name?: string;
|
|
35
|
+
};
|
|
36
|
+
openingElement?: {
|
|
37
|
+
name: BabelNode;
|
|
38
|
+
};
|
|
18
39
|
id?: {
|
|
19
40
|
name?: string;
|
|
20
41
|
} | null;
|
|
@@ -51,7 +72,18 @@ type Scope = {
|
|
|
51
72
|
generateUidIdentifier(name: string): {
|
|
52
73
|
name: string;
|
|
53
74
|
};
|
|
54
|
-
|
|
75
|
+
getBinding(name: string): {
|
|
76
|
+
path: {
|
|
77
|
+
node: {
|
|
78
|
+
init?: {
|
|
79
|
+
callee?: {
|
|
80
|
+
name?: string;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
} | undefined;
|
|
86
|
+
getProgramParent(): Scope & {
|
|
55
87
|
path: ProgramPath;
|
|
56
88
|
};
|
|
57
89
|
};
|
|
@@ -63,6 +95,10 @@ type NodePath = {
|
|
|
63
95
|
parentPath?: NodePath | null;
|
|
64
96
|
scope: Scope;
|
|
65
97
|
insertAfter(node: unknown): void;
|
|
98
|
+
replaceWith(node: unknown): void;
|
|
99
|
+
get(key: 'body'): NodePath[];
|
|
100
|
+
traverse(visitor: Record<string, unknown>): void;
|
|
101
|
+
skip(): void;
|
|
66
102
|
};
|
|
67
103
|
type ImportNodePath = {
|
|
68
104
|
node: ImportDeclarationNode;
|
|
@@ -73,22 +109,35 @@ type BabelState = {
|
|
|
73
109
|
filename?: string;
|
|
74
110
|
squiggleHelperLocals?: Record<string, string>;
|
|
75
111
|
squiggleFileLocal?: string;
|
|
112
|
+
squiggleSites?: {
|
|
113
|
+
line: number;
|
|
114
|
+
col: number;
|
|
115
|
+
}[];
|
|
116
|
+
squiggleTagLocal?: string;
|
|
117
|
+
squiggleSitesLocal?: string;
|
|
118
|
+
squiggleSitesInit?: string;
|
|
76
119
|
};
|
|
77
120
|
interface SquiggleBabelOptions {
|
|
78
121
|
instrumentZustand?: boolean;
|
|
79
122
|
instrumentMmkv?: boolean;
|
|
80
123
|
instrumentAsyncStorage?: boolean;
|
|
81
124
|
instrumentSqlite?: boolean;
|
|
125
|
+
instrumentLegendState?: boolean;
|
|
82
126
|
helperModule?: string;
|
|
83
127
|
zustandHelperModule?: string;
|
|
84
128
|
rootDir?: string;
|
|
129
|
+
callSites?: boolean;
|
|
85
130
|
stripInProduction?: boolean;
|
|
86
131
|
}
|
|
87
|
-
declare function squiggleBabelPlugin(_api: {
|
|
88
|
-
types: BabelTypes;
|
|
89
|
-
}, options?: SquiggleBabelOptions): {
|
|
132
|
+
declare function squiggleBabelPlugin(_api: PluginApi, options?: SquiggleBabelOptions): {
|
|
90
133
|
name: string;
|
|
91
134
|
visitor: {
|
|
135
|
+
Program: {
|
|
136
|
+
exit(path: NodePath, state: BabelState): void;
|
|
137
|
+
};
|
|
138
|
+
JSXElement: {
|
|
139
|
+
exit(path: NodePath, state: BabelState): void;
|
|
140
|
+
};
|
|
92
141
|
ImportDeclaration(path: ImportNodePath, state: BabelState): void;
|
|
93
142
|
FunctionDeclaration(path: NodePath, state: BabelState): void;
|
|
94
143
|
VariableDeclarator(path: NodePath, state: BabelState): void;
|
package/dist/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
var{defineProperty:
|
|
1
|
+
var{defineProperty:C,getOwnPropertyNames:c,getOwnPropertyDescriptor:o}=Object,p=Object.prototype.hasOwnProperty;function i(z){return this[z]}var n=(z)=>{var q=(T??=new WeakMap).get(z),$;if(q)return q;if(q=C({},"__esModule",{value:!0}),z&&typeof z==="object"||typeof z==="function"){for(var K of c(z))if(!p.call(q,K))C(q,K,{get:i.bind(z,K),enumerable:!($=o(z,K))||$.enumerable})}return T.set(z,q),q},T;var s=(z)=>z;function l(z,q){this[z]=s.bind(null,q)}var a=(z,q)=>{for(var $ in q)C(z,$,{get:q[$],enumerable:!0,configurable:!0,set:l.bind(q,$)})};var wq={};a(wq,{default:()=>f});module.exports=n(wq);var w=require("node:path"),t="@squiggle.sh/react-native",N="node_modules/";function e(z){let q=z.lastIndexOf(N);return q===-1?z:N+z.slice(q+N.length)}var qq={modules:new Set(["zustand","zustand/vanilla","zustand/react"]),names:new Set(["create","createStore"]),helper:"__squiggleInstrumentZustandFactory"},zq={modules:new Set(["react-native-mmkv"]),names:new Set(["createMMKV","useMMKV"]),helper:"__squiggleInstrumentMmkvFactory"},$q={modules:new Set(["@react-native-async-storage/async-storage"]),names:new Set,defaultExport:!0,helper:"__squiggleInstrumentAsyncStorage"},Bq={modules:new Set(["@op-engineering/op-sqlite"]),names:new Set(["open"]),helper:"__squiggleInstrumentOpSqliteFactory"},Xq={modules:new Set(["expo-sqlite"]),names:new Set(["openDatabaseAsync","openDatabaseSync","useSQLiteContext"]),helper:"__squiggleInstrumentExpoSqliteFactory"},Yq={modules:new Set(["@legendapp/state"]),names:new Set(["observable"]),helper:"__squiggleInstrumentLegendStateFactory"},Zq={modules:new Set(["@legendapp/state/react"]),names:new Set(["useObservable"]),helper:"__squiggleInstrumentLegendStateFactory"};function H(z){return/^[A-Z]/.test(z)}function _(z){if(!z)return!1;return z.some((q)=>{let $=q;return $?.type==="ReturnStatement"&&($.argument?.type==="JSXElement"||$.argument?.type==="JSXFragment")})}function E(z){let q=z?.[0];if(q?.type!=="VariableDeclaration")return!1;return q.declarations?.some(($)=>$.init?.callee?.name==="_c")??!1}function R(z){if(z.type==="ArrowFunctionExpression"){let q=z.body;if(!q)return!1;if(q.type==="JSXElement"||q.type==="JSXFragment")return!0;if(q.type==="BlockStatement"){let $=q.body;return _($)||E($)}return!1}if(z.type==="FunctionExpression"||z.type==="FunctionDeclaration"){let q=z.body;return _(q?.body)||E(q?.body)}return!1}var g={memo:"type",forwardRef:"render"};function jq(z){if(z?.type==="SequenceExpression")z=z.expressions?.at(-1);if(!z)return;let q=z.type==="Identifier"?z.name:z.type==="MemberExpression"?z.property?.name:void 0;return typeof q==="string"&&q in g?q:void 0}function Kq(z,q){if(q?.type!=="Identifier"||typeof q.name!=="string")return!1;return z.scope.getBinding(q.name)?.path.node.init?.callee?.name==="$RefreshSig$"}function Qq(z){let q=z,$=[],K=(W)=>q.get(W);for(let W=0;W<8;W++){let V=q.node;if(V.type==="AssignmentExpression"){q=K("right");continue}if(V.type!=="CallExpression"||!V.arguments?.[0])break;let M=jq(V.callee);if(M!==void 0)$.push(g[M]);else if(!Kq(q,V.callee))return;q=K("arguments.0")}if($.length===0)return;let j=q.node;if(j.type!=="ArrowFunctionExpression"&&j.type!=="FunctionExpression")return;return R(j)?{fnPath:q,fields:$}:void 0}function Wq(z){let q=()=>(process.env.BABEL_ENV??"production")==="development";if(typeof z.caller!=="function")return q();return z.caller(($)=>$?.isDev??q())===!0}function Vq(z){if(!z)return!1;if(z.type==="JSXIdentifier"){let q=typeof z.name==="string"?z.name:"";return H(q)&&q!=="Fragment"}if(z.type==="JSXMemberExpression")return z.property?.name!=="Fragment";return!1}function Fq(z,q,$,K){let j=JSON.stringify(q),W=$.map((V)=>`{ file: ${j}, line: ${V.line}, col: ${V.col} }`).join(", ");return[`function ${z.tag}(e, i) {`," if (e != null && typeof e === 'object' && e.props) {"," var m = globalThis.__squiggleSites || (globalThis.__squiggleSites = new WeakMap());",` m.set(e.props, (${z.sites} || ${z.init}())[i]);`," }"," return e;","}",`var ${z.sites};`,`function ${z.init}() {`,` globalThis.__squiggleSourceRoot || (globalThis.__squiggleSourceRoot = ${JSON.stringify(K)});`,` return (${z.sites} = [${W}]);`,"}"].join(`
|
|
2
|
+
`)}function Jq(z){let q=z.callee;if(!q)return;if(q.type==="Identifier"&&typeof q.name==="string")return S(q.name)?{hook:q.name,expr:q.name}:void 0;if(q.type==="MemberExpression"&&!q.computed&&q.object?.type==="Identifier"&&q.property?.type==="Identifier"&&typeof q.property.name==="string"&&S(q.property.name))return{hook:q.property.name,expr:`${q.object.name}.${q.property.name}`};return}function S(z){return z==="use"||/^use[A-Z0-9]/.test(z)}var Uq=new Set(["TSAsExpression","TSNonNullExpression","TSSatisfiesExpression","TypeCastExpression","ParenthesizedExpression"]);function xq(z){let{node:q,parentPath:$}=z;while($&&Uq.has($.node.type))q=$.node,$=$.parentPath;let K=$?.node;if(K?.type!=="VariableDeclarator"||K.init!==q)return;let j=K.id;if(!j)return;if(j.type==="Identifier")return j.name;if(j.type==="ArrayPattern"){let W=j.elements?.[0];return W?.type==="Identifier"?W.name:void 0}if(j.type==="ObjectPattern"){let W=(j.properties??[]).map((V)=>V.type==="ObjectProperty"?V.key?.name:void 0).filter((V)=>typeof V==="string");return W.length>0?`{ ${W.join(", ")} }`:void 0}return}var Mq=new Set(["use","useState","useReducer","useRef","useMemo","useCallback","useEffect","useLayoutEffect","useInsertionEffect","useImperativeHandle","useContext","useId","useTransition","useDeferredValue","useSyncExternalStore","useDebugValue","useOptimistic","useActionState","useFormState","useFormStatus","useEffectEvent"]);function vq(z){let q=[];return z.traverse({Function($){$.skip()},CallExpression:{exit($){let K=Jq($.node);if(!K)return;let j={hook:K.hook},W=xq($);if(W!==void 0)j.name=W;if(!Mq.has(K.hook))j.ref=K.expr;q.push(j)}}}),q}function Gq(z,q){let $=q.map((K)=>{let j=[`hook: ${JSON.stringify(K.hook)}`];if(K.name!==void 0)j.push(`name: ${JSON.stringify(K.name)}`);if(K.ref!==void 0)j.push(`ref: function () { return ${K.ref}; }`);return`{ ${j.join(", ")} }`});return`${z}.__squiggleHooks = [${$.join(", ")}];`}function Hq(z){let q=z.parentPath?.node.type;return q==="Program"||q==="ExportNamedDeclaration"||q==="ExportDefaultDeclaration"}function f(z,q={}){let $=z.types,K=q.callSites??Wq(z),j=[];if(q.instrumentZustand!==!1)j.push(qq);if(q.instrumentMmkv!==!1)j.push(zq);if(q.instrumentAsyncStorage!==!1)j.push($q);if(q.instrumentSqlite!==!1)j.push(Bq,Xq);if(q.instrumentLegendState!==!1)j.push(Yq,Zq);let W=q.helperModule??q.zustandHelperModule??t,V=q.rootDir??process.cwd(),M=q.stripInProduction===!0&&!0;function u(B){let X=w.isAbsolute(B)?w.relative(V,B).split("\\").join("/"):B;return e(X)}function I(B,X){let Y=X.squiggleFileLocal;if(!Y){Y=B.scope.generateUidIdentifier("sqFile").name,X.squiggleFileLocal=Y;let Z=u(X.filename??"<unknown>");B.scope.getProgramParent().path.unshiftContainer("body",$.variableDeclaration("const",[$.variableDeclarator($.identifier(Y),$.stringLiteral(Z))]))}return Y}function d(B,X,Y){let Z=B.node;if(Z.type!=="ImportDeclaration")return;if(!Y.modules.has(Z.source.value))return;let Q=[];for(let J of Z.specifiers){if(J.type==="ImportDefaultSpecifier"){if(!Y.defaultExport)continue}else if(J.type==="ImportSpecifier"){let P=J.imported,b=P?.type==="Identifier"?P.name:void 0;if(!b||!Y.names.has(b))continue}else continue;let x=J.local.name,G=B.scope.generateUidIdentifier(x).name;J.local=$.identifier(G),Q.push({localName:x,uid:G})}if(Q.length===0)return;let F=X.squiggleHelperLocals??={},U=F[Y.helper];if(!U){U=B.scope.generateUidIdentifier("squiggleInstrument").name,F[Y.helper]=U;let J=$.importDeclaration([$.importSpecifier($.identifier(U),$.identifier(Y.helper))],$.stringLiteral(W));B.scope.getProgramParent().path.unshiftContainer("body",J)}let v=Q.map(({localName:J,uid:x})=>$.variableDeclarator($.identifier(J),$.callExpression($.identifier(U),[$.identifier(x)])));B.insertAfter($.variableDeclaration("const",v))}function A(B,X){return X.reduce((Y,Z)=>$.memberExpression(Y,$.identifier(Z)),$.identifier(B))}function O(B,X,Y,Z,Q=[]){return $.expressionStatement($.assignmentExpression("=",$.memberExpression(A(B,Q),$.identifier("__squiggleSrc")),$.objectExpression([$.objectProperty($.identifier("file"),$.identifier(X)),$.objectProperty($.identifier("line"),$.numericLiteral(Y)),$.objectProperty($.identifier("col"),$.numericLiteral(Z))])))}function k(B){let X=B.node.loc?.start;return{line:X?.line??0,col:X?.column??0}}let L=new WeakSet;function h(B,X){let Y=B.node;if(L.has(Y))return;if(!Vq(Y.openingElement?.name))return;let Z=Y.loc?.start;if(!Z||typeof Z.line!=="number")return;let Q=B.scope.getProgramParent(),F=X.squiggleSites??=[],U=X.squiggleTagLocal??=Q.generateUidIdentifier("sqTag").name;X.squiggleSitesLocal??=Q.generateUidIdentifier("sqSites").name,X.squiggleSitesInit??=Q.generateUidIdentifier("sqSitesInit").name;let v=F.length;F.push({line:Z.line,col:Z.column??0}),L.add(Y);let J=$.callExpression($.identifier(U),[Y,$.numericLiteral(v)]),x=B.parentPath?.node.type,G=x==="JSXElement"||x==="JSXFragment"||x==="JSXAttribute";B.replaceWith(G?$.jsxExpressionContainer(J):J)}function m(B,X){let Y=X.squiggleSites;if(!Y||Y.length===0)return;if(!z.template)return;B.scope.getProgramParent().path.unshiftContainer("body",z.template.statements.ast(Fq({tag:X.squiggleTagLocal,sites:X.squiggleSitesLocal,init:X.squiggleSitesInit},u(X.filename??"<unknown>"),Y,V)))}function y(B){return K&&!(B.filename??"").includes("/node_modules/")}function D(B,X,Y,Z,Q=X){if(!y(Z)||!z.template)return;if(!H(X)&&!S(X))return;if(!Hq(Y))return;let F=vq(B);if(F.length===0)return;Y.insertAfter(z.template.statements.ast(Gq(Q,F)))}function r(B,X,Y){let Z=Qq(B.get("init"));if(Z===void 0||!B.parentPath)return;let{fnPath:Q,fields:F}=Z,U=B.parentPath;try{D(Q,X,U,Y,[X,...F].join("."))}catch{}let{line:v,col:J}=k(B);if(U.insertAfter(O(X,I(B,Y),v,J,F)),Q.node.id?.name===void 0)U.insertAfter($.expressionStatement($.assignmentExpression("=",$.memberExpression(A(X,F),$.identifier("displayName")),$.stringLiteral(X))))}return{name:"squiggle",visitor:{Program:{exit(B,X){if(!y(X))return;try{m(B,X)}catch{}}},JSXElement:{exit(B,X){if(!y(X))return;try{h(B,X)}catch{}}},ImportDeclaration(B,X){for(let Y of j)try{d(B,X,Y)}catch{}},FunctionDeclaration(B,X){try{let Y=B.node.id?.name;if(Y)D(B,Y,B,X)}catch{}if(M)return;try{let Y=B.node.id?.name;if(!Y||!H(Y))return;if(!R(B.node))return;let{line:Z,col:Q}=k(B);B.insertAfter(O(Y,I(B,X),Z,Q))}catch{}},VariableDeclarator(B,X){try{let Y=B.node.id,Z=B.node.init;if(Y?.type==="Identifier"&&Y.name&&B.parentPath&&(Z?.type==="ArrowFunctionExpression"||Z?.type==="FunctionExpression"))D(B.get("init"),Y.name,B.parentPath,X)}catch{}if(M)return;try{let Y=B.node.id;if(!Y||Y.type!=="Identifier")return;let Z=Y.name;if(!Z||!H(Z))return;let Q=B.node.init;if(!Q)return;if(Q.type==="CallExpression"){r(B,Z,X);return}if(!R(Q))return;let{line:F,col:U}=k(B);B.parentPath?.insertAfter(O(Z,I(B,X),F,U))}catch{}}}}}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squiggle.sh/babel-plugin",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"description": "Squiggle Babel plugin: injects stable component source
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Squiggle Babel plugin: injects stable component source locations (definition and, in dev, each element's call site) into React components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"babel-plugin",
|
|
7
7
|
"devtools",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"sideEffects": true,
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@babel/core": ">=7",
|
|
39
|
-
"@squiggle.sh/react-native": "0.1
|
|
39
|
+
"@squiggle.sh/react-native": "0.2.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependenciesMeta": {
|
|
42
42
|
"@squiggle.sh/react-native": {
|